Skip to content

old colorbar removed but still occupies space #15986

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

Closed
shuheng-liu opened this issue Dec 20, 2019 · 5 comments · Fixed by #12443
Closed

old colorbar removed but still occupies space #15986

shuheng-liu opened this issue Dec 20, 2019 · 5 comments · Fixed by #12443

Comments

@shuheng-liu
Copy link

Bug report

Bug summary

When there are multiple subplots, the colorbar takes space even after successfully removed. New colorbar will have to be positioned to the left of old ones.

It can be seen in the following example that the contour plot is being shrinked in width because space is being occupied by colorbar.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0., 5., 1.)
y = np.arange(0., 10., 1.)
z = np.tensordot(y, x, axes=0)

fig = plt.figure()
fig.add_subplot(1, 3, 1)
fig.add_subplot(1, 3, 2)
ax = fig.add_subplot(1, 3, 2)

ax.clear()
contour = ax.contourf(x, y, z)

cb = fig.colorbar(contour)
# The following should not have no effect on the final outcome if uncommented
# ax.clear()
# cb.remove()
# contour = ax.contourf(x, y, z)
# cb_new = fig.colorbar(contour)

Actual outcome
This is the result I get if the last 4 lines are NOT commented; i.e. colorbar cb is removed and a new, identical one is added.

Screen Shot 2019-12-20 at 17 35 08

If I do this process (remove -> readd) again, things get even worse,
Screen Shot 2019-12-20 at 17 23 27

Expected outcome
This is the result I get if the last 4 lines ARE commented; i.e., only 1 colorbar is ever created
Screen Shot 2019-12-20 at 17 23 58

Matplotlib version

  • Operating system: Darwin MacBook-Pro-15.local 19.2.0 Darwin Kernel Version 19.2.0: Sat Nov 9 03:47:04 PST 2019; root:xnu-6153.61.1~20/RELEASE_X86_64 x86_64
  • Matplotlib version: 3.1.1
  • Matplotlib backend: nbAgg
  • Python version: 3.7.3
  • jupyter core : 4.6.0
  • jupyter-notebook : 6.0.1
  • conda: 4.7.12
@jklymak
Copy link
Member

jklymak commented Dec 20, 2019

Pleas try with constrianed_layout.

@dstansby
Copy link
Member

Pleas try with constrianed_layout.

Regardless of using constrained_layout or not, I think it's still reasonable to expect a removed colourbar to not affect subsequent colourbar additions.

@jklymak
Copy link
Member

jklymak commented Dec 26, 2019

Adding a colorbar steals space from the parent. That space remains stolen if you delete the colorbar. If you re add a colorbar the space is stolen a second time.

I suppose someone could go through the bother of tracking us a colorbar has already been removed and just put the new colorbar where the old one was. But the use case for needing to do this is not particularly compelling.

@timhoffm
Copy link
Member

Regardless of using constrained_layout or not, I think it's still reasonable to expect a removed colourbar to not affect subsequent colourbar additions.

I do not think so. The default layout is static, which is just not suited for the requested behavior. Axes span a certian space of the figure. To prevent overlap, a colorbar steals some space. But that information is lost immediately. The Axes just has a new size. No way of knowing if it was resized by a colorbar or if somebody wanted larger margins. Thus, we cannot undo sizing on colorbar removal or not resize the Axes on a second colorbar addition. Any attempt to do so (e.g. tracking resizing due to colorbars or checking if there is enough space to add colorbar without Axes resizing) would create more trouble than it solves.

The requested behavior can only be fulfilled by a real layout manager such as constrained_layout.

@timhoffm timhoffm added Community support Users in need of help. topic: geometry manager LayoutEngine, Constrained layout, Tight layout labels Dec 28, 2019
@anntzer anntzer added has PR and removed Community support Users in need of help. topic: geometry manager LayoutEngine, Constrained layout, Tight layout labels Dec 29, 2019
@anntzer
Copy link
Contributor

anntzer commented Dec 29, 2019

Actually #12443 already (indirectly) fixes this: colorbar.remove already tries to restore the parent's axes (

try:
ax = self.mappable.axes
except AttributeError:
return
), but for contour plots the attribute is .ax, not .axes. (Indeed, replacing contour plots in the OP's example by imshows doesn't repro the issue, because AxesImage has a .axes attribute.) So https://github.com/matplotlib/matplotlib/pull/12443/files#diff-2e46ac77d349b367229eda1b93d92fc3R941 is the specific fix for the issue.

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

Successfully merging a pull request may close this issue.

5 participants