Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 714ea73

Browse files
committed
FIX: removing colorbar's axes also removes colorbar
1 parent 60383ac commit 714ea73

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

lib/matplotlib/colorbar.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
End-users most likely won't need to directly use this module's API.
1212
"""
1313

14+
import functools
1415
import logging
1516

1617
import numpy as np
@@ -194,6 +195,17 @@ def get_subplotspec(self):
194195
or getattr(self._orig_locator, "get_subplotspec", lambda: None)())
195196

196197

198+
def _remove_cbar_axes(ax, cbar):
199+
"""
200+
Replacement remove method for a colorbar's axes, so that the colorbar is
201+
properly removed.
202+
203+
Note we define this at the module level to preserve pickling. A lambda or
204+
local def within the Colorbar.__init__ method will not work.
205+
"""
206+
cbar.remove()
207+
208+
197209
@_docstring.interpd
198210
class Colorbar:
199211
r"""
@@ -427,6 +439,14 @@ def __init__(
427439
self._extend_cid2 = self.ax.callbacks.connect(
428440
"ylim_changed", self._do_extends)
429441

442+
# Ensure proper cleanup when `cbar.ax.remove()` is called. We ensure
443+
# this by overriding the Axes' remove method, so that `cbar.ax.remove()`
444+
# actually calls `cbar.remove()`. In turn, we store the original Axes'
445+
# remove method in `_ax_remove`, which `cbar.remove()` will eventually
446+
# call to clean up the Axes itself.
447+
self._ax_remove = self.ax._remove_method
448+
self.ax._remove_method = functools.partial(_remove_cbar_axes, cbar=self)
449+
430450
@property
431451
def long_axis(self):
432452
"""Axis that has decorations (ticks, etc) on it."""
@@ -1032,7 +1052,7 @@ def remove(self):
10321052
if self.ax in a._colorbars:
10331053
a._colorbars.remove(self.ax)
10341054

1035-
self.ax.remove()
1055+
self._ax_remove(self.ax)
10361056

10371057
self.mappable.callbacks.disconnect(self.mappable.colorbar_cid)
10381058
self.mappable.colorbar = None

lib/matplotlib/tests/test_colorbar.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import platform
2+
from unittest import mock
23

34
import numpy as np
45
import pytest
@@ -311,6 +312,18 @@ def test_remove_from_figure_cl():
311312
post_position.get_points())
312313

313314

315+
def test_axes_remove():
316+
"""Removing the colorbar's axes should also remove the colorbar"""
317+
fig, ax = plt.subplots()
318+
sc = ax.scatter([1, 2], [3, 4])
319+
cb = fig.colorbar(sc)
320+
321+
with mock.patch.object(cb, 'remove') as mock_cb_remove:
322+
cb.ax.remove()
323+
324+
mock_cb_remove.assert_called()
325+
326+
314327
def test_colorbarbase():
315328
# smoke test from #3805
316329
ax = plt.gca()

0 commit comments

Comments
 (0)