You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
clearing axes with shared axis with non-linear scales should not warn #9970
Throws a warning:
UserWarning: Attempted to set non-positive xlimits for log-scale axis; invalid limits will be ignored.
'Attempted to set non-positive xlimits for log-scale axis;
ax1.cla() also throws a warning.
Matplotlib version
2.1.0,
python 3.6.3
ipython 6.1.0
fig.clf() will do a ax1.cla(). So the real culpit is ax1.cla().
Because ax1 does not have a master/parent axes share it will default to 'linear' scale. And then set the data limit to [0,1]. But since ax1 share axes with ax2 which has log scale it will throw the warning.
So there are 2 problems here. 1) Why should fig.clf() clear axes as well. It should just clear the axes from the figure and not clear the axes itself.
2) when a master axes clear should it revert all the other shared axes to linear scale as well.
Actually the warning shows up even if the figure is shown (e.g. if you type @timhoffm's lines one after the other at an IPython prompt). AFAICT the root cause is that cla()'ing ax1 resets it to linear, but doesn't reset the scale on ax2, so we end up with ax1 using log and ax2 using linear scale, which seems contrary to the semantics of shared axes.
Also there's some funky asymmetry which makes ax2.cla() not do the same (it doesn't even revert the scale to linear), likely because the implementation in cla is
so things behave differently between the master axes (which has self._sharex=None) and the follower axes (which as self._sharex = master); at least that seems like something to be fixed...
importwarningswarnings.filterwarnings("ignore", message="Attempted to set non-positive left xlim on a log-scaled axis.\nInvalid limit will be ignored.")
Hi, found this page by googling with the error message.
Something like this creates a buggy gui as well.
The axes-functions expects standard linear/log10 scales and cannot deal with customization.
(Is this because some functions are not implemented in the plot the gui needs? If so, what should be provided?)
Select region 60-160 with pan/zoom tool (to create a state to go back/forward to).
Change x-axis scale with L,
go back....
you get the error
UserWarning: Attempted to set non-positive left xlim on a log-scaled axis.
Invalid limit will be ignored.
plt.show()
go forward,
press L again
x-axis is restored
go back...
no error
A similar error message pops up in my case with an interactive drawing where scale settings for the y-axis can get changed between linear and log2 (from within the drawing, by clicking the y-axis).
The changed scaling is not passed on when going back a snapshot. Instead unwanted axes with standard scales are presented, which is off-putting although restorable via the built-in interactivity.
Scale-change is not seen as a state-change or new snapshot, which is possibly the source of the unexpected behavior from this user's point of view. In a similar vein:
When pressing l (y-axis change) the mercatorprojection is lost and cannot be restored (say, by pressing 'home').
Using the gui's edit-axes dialog one gets:
index 'mercator' is invalid (label: Scale, value: ['linear', 'log', 'symlog', 'logit']);
How can a plot tell the gui what to set as an alternative scale??
The axis functions of the gui are also crashing the drawing when values to be changed are not positive:
2b. Select a region between -150 to -50 with pan/zoom tool
3b. Change x-axis scale with L,
You see a long error-stack, which is not really user-friendly;
Maybe scale change by means of the gui should by default be ignored when this cannot be completed (with the error stack overruled by a warning; "scale change impossible"):
Traceback (most recent call last):
File "/usr/lib64/python3.9/site-packages/matplotlib/backends/backend_qt.py", line 477, in _draw_idle
self.draw()
File "/usr/lib64/python3.9/site-packages/matplotlib/backends/backend_agg.py", line 436, in draw
self.figure.draw(self.renderer)
File "/usr/lib64/python3.9/site-packages/matplotlib/artist.py", line 73, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
File "/usr/lib64/python3.9/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
return draw(artist, renderer)
File "/usr/lib64/python3.9/site-packages/matplotlib/figure.py", line 2837, in draw
mimage._draw_list_compositing_images(
File "/usr/lib64/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/lib64/python3.9/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
return draw(artist, renderer)
File "/usr/lib64/python3.9/site-packages/matplotlib/axes/_base.py", line 3091, in draw
mimage._draw_list_compositing_images(
File "/usr/lib64/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/lib64/python3.9/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
return draw(artist, renderer)
File "/usr/lib64/python3.9/site-packages/matplotlib/axis.py", line 1158, in draw
ticks_to_draw = self._update_ticks()
File "/usr/lib64/python3.9/site-packages/matplotlib/axis.py", line 1045, in _update_ticks
major_locs = self.get_majorticklocs()
File "/usr/lib64/python3.9/site-packages/matplotlib/axis.py", line 1277, in get_majorticklocs
return self.major.locator()
File "/usr/lib64/python3.9/site-packages/matplotlib/ticker.py", line 2293, in call
return self.tick_values(vmin, vmax)
File "/usr/lib64/python3.9/site-packages/matplotlib/ticker.py", line 2326, in tick_values
log_vmin = math.log(vmin) / math.log(b)
ValueError: math domain error
/usr/lib64/python3.9/site-packages/matplotlib/transforms.py:2662: RuntimeWarning: divide by zero encountered in double_scalars
x_scale = 1.0 / inw
/usr/lib64/python3.9/site-packages/matplotlib/ticker.py:1012: UserWarning: Warning: converting a masked element to nan.
return '%-12g' % value
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
I can confirm that this is still a bug and I think that the analysis above that the scale state is not correctly reset on all of the shared axis is the correct.
I'm going to label this as a good first issues (and change the title), but medium difficulty.
It is a good first issue because there is minimal API design here (the code above should not warn!), but medium difficulty because there are a number of moving parts in the shared axis code and fixing this will likely require chasing though a bunch of OO layers.
The one choice I think we have here is what to do to prevent this warning:
keep the scale of the axis cla is called on (this is bad because if the scale is changed or not depends on if there is a shared axis on not!
change the scale on the shared axis (good in that the object we touched did indeed change, but bad in that we now have some (spooky) action at a distance)
un-share the axis before resetting (this is the best in my view as "clearing" should take that axes back to its "just created" state which does not involve a shared axis.
Skipping ax.cla() in fig.clf() seems dicey as we do want to do some clean up proactively rather than relying on reference cycles to save us (but not help too much).
So exact steps:
sort out how to unshare all the axis of an axes (probably) first thing is Axes.cla()
importwarningswarnings.filterwarnings("ignore", message="Attempted to set non-positive left xlim on a log-scaled axis.\nInvalid limit will be ignored.")
Ignore the warning as above.
I just added
plt.xcale('linear')
right before the cla() call, to ensure the x-axis is linear. Fewer characters. :)
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
#30843 may have a partial fix (re-ordering the way state is set) but has some other changes that are not correct.
Shared axis can not logically have different scales (otherwise they are not the same!) so I suspect the complete fix is in making sure cla correctly resets the linked axis as well.
Activity
lkjell commentedon Dec 11, 2017
fig.clf() will do a ax1.cla(). So the real culpit is ax1.cla().
Because ax1 does not have a master/parent axes share it will default to 'linear' scale. And then set the data limit to [0,1]. But since ax1 share axes with ax2 which has log scale it will throw the warning.
So there are 2 problems here. 1) Why should fig.clf() clear axes as well. It should just clear the axes from the figure and not clear the axes itself.
2) when a master axes clear should it revert all the other shared axes to linear scale as well.
divenex commentedon Apr 17, 2018
This bug is still present in Matplotlib 2.2
divenex commentedon Jul 1, 2021
This bug still persists in Matplotlib 3.3
jklymak commentedon Jul 1, 2021
You are trying to plot 0 on a loglog plot so you get a warning. I am not sure what the bug is.
timhoffm commentedon Jul 1, 2021
Yes, but probably other than you think 😄. This is the minimal example I cam up with (no 0 data involved):
Ingedients you need:
I suspect this has to do something with
show()) so that we still have a 0 limit.Given that this only happens when you clear a non-shown figure (that also needs certain further properties), I'd be fine with closing as "won't fix".
anntzer commentedon Jul 2, 2021
Actually the warning shows up even if the figure is shown (e.g. if you type @timhoffm's lines one after the other at an IPython prompt). AFAICT the root cause is that
cla()'ing ax1 resets it to linear, but doesn't reset the scale on ax2, so we end up with ax1 using log and ax2 using linear scale, which seems contrary to the semantics of shared axes.Also there's some funky asymmetry which makes
ax2.cla()not do the same (it doesn't even revert the scale to linear), likely because the implementation inclaisso things behave differently between the master axes (which has
self._sharex=None) and the follower axes (which asself._sharex = master); at least that seems like something to be fixed...linusjf commentedon Aug 30, 2021
Ignore the warning as above.
billtubbs commentedon Jan 1, 2022
It would be great to have this fixed! It's raising warnings in our test script which is like this:
brobr commentedon May 11, 2022
Hi, found this page by googling with the error message.
Something like this creates a buggy gui as well.
The axes-functions expects standard linear/log10 scales and cannot deal with customization.
(Is this because some functions are not implemented in the plot the gui needs? If so, what should be provided?)
For example
you get the error
x-axis is restored
no error
A similar error message pops up in my case with an interactive drawing where scale settings for the y-axis can get changed between linear and log2 (from within the drawing, by clicking the y-axis).
The changed scaling is not passed on when going back a snapshot. Instead unwanted axes with standard scales are presented, which is off-putting although restorable via the built-in interactivity.
Scale-change is not seen as a state-change or new snapshot, which is possibly the source of the unexpected behavior from this user's point of view. In a similar vein:
How can a plot tell the gui what to set as an alternative scale??
The axis functions of the gui are also crashing the drawing when values to be changed are not positive:
2b. Select a region between -150 to -50 with pan/zoom tool
3b. Change x-axis scale with L,
You see a long error-stack, which is not really user-friendly;
Maybe scale change by means of the gui should by default be ignored when this cannot be completed (with the error stack overruled by a warning; "scale change impossible"):
Tests: work around matplotlib 3.6.0 warning
github-actions commentedon May 12, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
tacaswell commentedon Jun 12, 2023
I can confirm that this is still a bug and I think that the analysis above that the scale state is not correctly reset on all of the shared axis is the correct.
I'm going to label this as a good first issues (and change the title), but medium difficulty.
It is a good first issue because there is minimal API design here (the code above should not warn!), but medium difficulty because there are a number of moving parts in the shared axis code and fixing this will likely require chasing though a bunch of OO layers.
The one choice I think we have here is what to do to prevent this warning:
clais called on (this is bad because if the scale is changed or not depends on if there is a shared axis on not!Skipping
ax.cla()infig.clf()seems dicey as we do want to do some clean up proactively rather than relying on reference cycles to save us (but not help too much).So exact steps:
Axes.cla()8 remaining items
gjcoram commentedon Dec 29, 2023
I just added
plt.xcale('linear')
right before the cla() call, to ensure the x-axis is linear. Fewer characters. :)
pinradaThan commentedon Apr 2, 2024
Hello! Seems like this issue has not been fixed yet. My friend and I are first-time contributors and would like to take a jab at this.
github-actions commentedon Apr 2, 2025
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
saumyacoder1709 commentedon Dec 8, 2025
I would like to work on this issue.
FIX: Prevent warning when clearing axes with shared non-linear scale
FIX: Prevent warning when clearing axes with shared non-linear scale
FIX: Prevent warning when clearing axes with shared non-linear scale
Add test for clearing shared non-linear axes without warning
Fix matplotlib#9970: Set scale before xlim/ylim in sharex/sharey to a…
Fix matplotlib#9970: suppress spurious warning when clearing axes wit…
tacaswell commentedon Jul 18, 2026
#30843 may have a partial fix (re-ordering the way state is set) but has some other changes that are not correct.
Shared axis can not logically have different scales (otherwise they are not the same!) so I suspect the complete fix is in making sure
clacorrectly resets the linked axis as well.