FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Removing axes created by twiny() leads to an error · Issue #18925 · matplotlib/matplotlib · GitHub

Repository navigation

Removing axes created by twiny() leads to an error #18925

Closed

Description

Bug report

Bug summary

Removing axes created with twiny() leads to an error. I have found a very similar bug to my issue here: #14911. Interestingly enough this works with twinx(). The code in the original bug report also works in my installation.

Code for reproduction

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax_twin = ax.twiny()
ax_twin.remove()
plt.show()

Actual outcome

Exception in Tkinter callback
Traceback (most recent call last):
  File "c:\programdata\miniconda3\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "c:\programdata\miniconda3\lib\tkinter\__init__.py", line 804, in callit
    func(*args)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\backends\_backend_tk.py", line 253, in idle_draw
    self.draw()
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 9, in draw
    super(FigureCanvasTkAgg, self).draw()
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\backends\backend_agg.py", line 407, in draw
    self.figure.draw(self.renderer)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\artist.py", line 41, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\figure.py", line 1863, in draw
    mimage._draw_list_compositing_images(
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\image.py", line 131, in _draw_list_compositing_images
    a.draw(renderer)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\artist.py", line 41, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\cbook\deprecation.py", line 411, in wrapper
    return func(*inner_args, **inner_kwargs)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\axes\_base.py", line 2707, in draw
    self._update_title_position(renderer)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\axes\_base.py", line 2638, in _update_title_position
    bb = ax.xaxis.get_tightbbox(renderer)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\axis.py", line 1109, in get_tightbbox
    ticks_to_draw = self._update_ticks()
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\axis.py", line 1021, in _update_ticks
    major_locs = self.get_majorticklocs()
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\axis.py", line 1283, in get_majorticklocs
    return self.major.locator()
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\ticker.py", line 2276, in __call__
    return self.tick_values(vmin, vmax)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\ticker.py", line 2284, in tick_values
    locs = self._raw_ticks(vmin, vmax)
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\ticker.py", line 2223, in _raw_ticks
    nbins = np.clip(self.axis.get_tick_space(),
  File "c:\programdata\miniconda3\lib\site-packages\matplotlib\axis.py", line 2243, in get_tick_space
    length = ((ends[1][0] - ends[0][0]) / self.axes.figure.dpi) * 72
AttributeError: 'NoneType' object has no attribute 'dpi'

Expected outcome

A plot with the twiny axes removed

Matplotlib version

  • Operating system: Windows 10
  • Matplotlib version: 3.3.2
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.8.3

Python is from miniconda, all packages installed via pip.

Activity

  1. added this to the v3.4.0 milestone on Nov 10, 2020
  2. tacaswell commented on Nov 10, 2020

    Member

    The fix here is to sort out why #14997 only worked on the x-axis and not the y-axis...

  3. anntzer commented on Nov 10, 2020

    Contributor

    From a quick look, I think that's unrelated to #14997 and actually due to the fact that the _shared_x_axes/_shared_y_axes/_twinned_axes groupers don't get updated when an axes is removed, and then the removed axes show up when _update_title_position calls _twinned_axes.get_siblings. (And the this only affects twiny because of implementation details of XAxis.get_tick_space.)

    Likely Figure.delaxes also needs to update the groupers, but note that on top of that add_axes (which explicitly can re-add a previously removed axes) should also update the groupers back if such an axes is readded.

  4. anntzer commented on Nov 11, 2020

    Contributor

    A related problem I noticed independently: setting a tick locator on a removed shared axes will affect the unremoved axes in a somewhat weird way. A realistic example is the following

    from pylab import *
    from matplotlib.ticker import MultipleLocator
    
    datasets = [  # Made up, imagine you have many.
        [1, 2, 3, 4],
        [1, 2, 4, 8],
        [1, 3, 5, 7],
    ]
    
    # I want to plot one dataset per subplot, and arrange axes in a square-ish way.
    axs = figure(constrained_layout=True).subplots(2, 2, sharex=True, sharey=True).ravel()
    # Remove axes that won't be used
    for ax in axs[len(datasets):]:
        ax.remove()
    # Do some common setup for axes.
    for ax in axs:
        ax.xaxis.set(major_locator=MultipleLocator(1))
        ax.yaxis.set(major_locator=MultipleLocator(1))
    # Plot the data.
    for ax, dataset in zip(axs, datasets):
        ax.plot(dataset)
    show()

    which yields
    (note the missing ticks).
    I believe what basically happens is that the MultipleLocator set on the last (now removed) axes wins and is used for everyone, but the axes limits of that axes are no longer updated and so the MultipleLocator thinks it is being used with axes limits of (0, 1) (the default axes limits) and decides to yield ticks at [-1, 0, 1, 2] (with the usual "1-over" excess tick). Again, removing the removed axes from _shared_x_axes would prevent its locator from "winning".

    (I have similar patterns quite often, but usually remove the datasets last (which avoids the problem as axes removal knows tickers need to be readjusted) or remember that I only need to set the locators once.)

  5. modified the milestones: v3.4.0, v3.5.0 on Jan 27, 2021
  6. thriveth commented on Aug 17, 2021

    I still have this problem, if there is not a fix, is there possibly a known work-around?

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL