Skip to content

clearing axes with shared axis with non-linear scales should not warn #9970

Closed

Description

@fredrik-1
import matplotlib.pyplot as plt

fig=plt.figure(1)
ax1=fig.add_subplot(1,2,1)
ax1.loglog(range(10))
ax2=fig.add_subplot(1,2,2, sharex=ax1)
ax2.loglog(range(10))

fig.clf()

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

Activity

  1. lkjell commented on Dec 11, 2017

    @lkjell
    Contributor

    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.

  2. divenex commented on Apr 17, 2018

    @divenex

    This bug is still present in Matplotlib 2.2

  3. divenex commented on Jul 1, 2021

    @divenex

    This bug still persists in Matplotlib 3.3

  4. jklymak commented on Jul 1, 2021

    @jklymak
    Member

    You are trying to plot 0 on a loglog plot so you get a warning. I am not sure what the bug is.

  5. timhoffm commented on Jul 1, 2021

    @timhoffm
    Member

    You are trying to plot 0 on a loglog plot so you get a warning. I am not sure what the bug is.

    Yes, but probably other than you think 😄. This is the minimal example I cam up with (no 0 data involved):

    fig, (ax1, ax2) = plt.subplots(1, 2, sharex=True)
    x = range(1, 10)
    ax1.plot(x, x)
    ax2.semilogx(x, x)
    ax1.cla()
    

    Ingedients you need:

    • at least one log scale on a shared axis
    • clearing an Axes that axis-shares with the log Axes.

    I suspect this has to do something with

    1. an internal state not being updated (missing show()) so that we still have a 0 limit.
    2. The interaction between shared axes during cleanup.

    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".

  6. anntzer commented on Jul 2, 2021

    @anntzer
    Contributor

    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

            if self._sharex is not None:
                self.sharex(self._sharex)
            else:
                self.xaxis._set_scale('linear')
                try:
                    self.set_xlim(0, 1)
                except TypeError:
                    pass

    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...

  7. linusjf commented on Aug 30, 2021

    @linusjf
    import warnings
    warnings.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.

  8. billtubbs commented on Jan 1, 2022

    @billtubbs

    It would be great to have this fixed! It's raising warnings in our test script which is like this:

    fig, axes = plt.subplots(2, 1, sharex=True)
    axes[0].loglog([1e-1, 1e0, 1e1], [10, 100, 1000])
    axes[1].loglog([1e-1, 1e0, 1e1], [10, 100, 1000])
    # ... do some tests here ...
    fig.clear()
    
    UserWarning: Attempted to set non-positive left xlim on a log-scaled axis.
    Invalid limit will be ignored.
      fig.clear()
    
  9. brobr commented on May 11, 2022

    @brobr

    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

    1. Run the https://matplotlib.org/stable/gallery/scales/custom_scale.html demo (from a terminal or within a ide like geany).
    2. Select region 60-160 with pan/zoom tool (to create a state to go back/forward to).
    3. Change x-axis scale with L,
    4. 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()

    1. go forward,
    2. press L again
      x-axis is restored
    3. 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:

    1. When pressing l (y-axis change) the mercatorprojection is lost and cannot be restored (say, by pressing 'home').
    2. 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

  10. github-actions commented on May 12, 2023

    @github-actions

    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!

  11. added
    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.
    on Jun 12, 2023
  12. tacaswell commented on Jun 12, 2023

    @tacaswell
    Member

    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()
    • write test
    • write behavior change note
  13. 8 remaining items

  14. gjcoram commented on Dec 29, 2023

    @gjcoram
    import warnings
    warnings.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. :)

  15. pinradaThan commented on Apr 2, 2024

    @pinradaThan

    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.

  16. github-actions commented on Apr 2, 2025

    @github-actions

    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!

  17. added
    keepItems to be ignored by the “Stale” Github Action
    and removed
    status: inactiveMarked by the “Stale” Github Action
    on Apr 2, 2025
  18. saumyacoder1709 commented on Dec 8, 2025

    @saumyacoder1709
    Contributor

    I would like to work on this issue.

  19. added 3 commits that reference this issue on Dec 8, 2025
    2321eab
    b5abeb2
    2e53341
  20. added 2 commits that reference this issue on May 5, 2026
    f88a936
    63e1c4d
  21. tacaswell commented on Jul 18, 2026

    @tacaswell
    Member

    #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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Difficulty: Mediumhttps://matplotlib.org/devdocs/devel/contribute.html#good-first-issueskeepItems to be ignored by the “Stale” Github Action🌱 Good first issueOpen a pull request against these issues if there are no active ones!

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions