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
importnumpyasnpimportmatplotlib.pyplotaspltx=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.
If I do this process (remove -> readd) again, things get even worse,
Expected outcome
This is the result I get if the last 4 lines ARE commented; i.e., only 1 colorbar is ever created
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
Regardless of using constrained_layout or not, I think it's still reasonable to expect a removed colourbar to not affect subsequent colourbar additions.
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.
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.
Activity
jklymak commented on Dec 20, 2019
Pleas try with constrianed_layout.
dstansby commented on Dec 26, 2019
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 commented on 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 commented on Dec 28, 2019
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.
anntzer commented on Dec 29, 2019
Actually #12443 already (indirectly) fixes this: colorbar.remove already tries to restore the parent's axes (
matplotlib/lib/matplotlib/colorbar.py
Lines 1310 to 1313 in b91b001