Repository navigation
Fix cla colorbar #20330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix cla colorbar #20330
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
co-author: Greg Lucas <greg.m.lucas@gmail.com>
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -260,7 +260,6 @@ def __init__(self, parent, userax=True): | |||||||
| parent.remove() | ||||||||
| else: | ||||||||
| outer_ax = parent | ||||||||
|
|
||||||||
| inner_ax = outer_ax.inset_axes([0, 0, 1, 1]) | ||||||||
| self.__dict__.update(inner_ax.__dict__) | ||||||||
|
|
||||||||
|
|
@@ -285,6 +284,32 @@ def _set_inner_bounds(self, bounds): | |||||||
| self.inner_ax._axes_locator = _TransformedBoundsLocator( | ||||||||
| bounds, self.outer_ax.transAxes) | ||||||||
|
|
||||||||
| def cla(self): | ||||||||
| """ | ||||||||
| Reset the colorbar axes to be empty. | ||||||||
| """ | ||||||||
| # need to low-level manipulate the stacks because we | ||||||||
| # are just swapping places here. We don't need to | ||||||||
| # set transforms etc... | ||||||||
| self.inner_ax.cla() | ||||||||
| self.outer_ax.cla() | ||||||||
| self.figure._axstack.add(self) | ||||||||
| self.figure._axstack.remove(self.outer_ax) | ||||||||
| self.figure._localaxes.add(self) | ||||||||
| self.figure._localaxes.remove(self.outer_ax) | ||||||||
|
|
||||||||
| self.__dict__.update(self.outer_ax.__dict__) | ||||||||
| self.inner_ax.remove() | ||||||||
| del self.inner_ax | ||||||||
| del self.outer_ax | ||||||||
|
|
||||||||
| self.xaxis.set_visible(True) | ||||||||
| self.yaxis.set_visible(True) | ||||||||
| for spine in self.spines.values(): | ||||||||
| spine.set_visible(True) | ||||||||
|
|
||||||||
| self.set_facecolor(mpl.rcParams['axes.facecolor']) | ||||||||
|
|
||||||||
|
|
||||||||
| class _ColorbarSpine(mspines.Spine): | ||||||||
| def __init__(self, axes): | ||||||||
|
|
@@ -1250,7 +1275,12 @@ def update_normal(self, mappable): | |||||||
| self.norm = mappable.norm | ||||||||
| self._reset_locator_formatter_scale() | ||||||||
|
|
||||||||
| self.draw_all() | ||||||||
| try: | ||||||||
| self.draw_all() | ||||||||
| except AttributeError: | ||||||||
| # update_normal sometimes is called when it shouldn't be.. | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh more lovely callbacks ;-)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fundamental problem is that the colorbar axes is
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is that for the callbacks, each mappable only maps to one colorbar, but in the following the mappable is used for two colorbars: import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
pc = ax.imshow(np.arange(100).reshape(10, 10))
cb = fig.colorbar(pc, extend='both')
cb2 = fig.colorbar(pc)
# Clear and re-use the same colorbar axes
print('HERE1:', pc, pc.callbacksSM.callbacks)
cb.ax.cla()
print('HERE2:', pc, pc.callbacksSM.callbacks)
cb2.ax.cla()
print('HERE3:', pc, pc.callbacksSM.callbacks)
cb = fig.colorbar(pc, cax=cb.ax)
cb2 = fig.colorbar(pc, cax=cb2.ax)which results in: For The culprit is here: matplotlib/lib/matplotlib/colorbar.py Lines 1181 to 1183 in d0137e9
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course this doesn't work at all on master? So maybe this test is just too stringent.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is an idea that would help this situation (and the pan/zoom on colorbars too which would help me). What about making the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if that helps in particular. The issue here is that the scalar mappable is only storing a reference to a single colorbar, whereas it stores two callbacks. So the line The newest commit promotes
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oof, this opened a can of worms ;) I don't think changing For this specific use-case, the reason you're getting multiple callbacks is because when you call
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not at all fundamentally against that, but it seems a pretty hefty change. I think what you would do is lock out cb.ax and then just reproduce all the axes methods (which has been done already, but only partially). But it'd take some work to do it and not have a bunch of breaking API.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surprisingly, it doesn't seem that bad... See this commit: |
||||||||
| pass | ||||||||
|
|
||||||||
| if isinstance(self.mappable, contour.ContourSet): | ||||||||
| CS = self.mappable | ||||||||
| if not CS.filled: | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here self is back to an Axes now, so can you call
super().cla()to get the defaults for you?