Skip to content

Commit 0428306

Browse files
authored
Merge pull request #23591 from meeseeksmachine/auto-backport-of-pr-23549-on-v3.5.x
Backport PR #23549 on branch v3.5.x (Don't clip colorbar dividers)
2 parents 2f3abfb + ab78318 commit 0428306

File tree

3 files changed

+73
-29
lines changed

3 files changed

+73
-29
lines changed

lib/matplotlib/colorbar.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,8 @@ def __init__(self, ax, mappable=None, *, cmap=None,
467467
self.dividers = collections.LineCollection(
468468
[],
469469
colors=[mpl.rcParams['axes.edgecolor']],
470-
linewidths=[0.5 * mpl.rcParams['axes.linewidth']])
470+
linewidths=[0.5 * mpl.rcParams['axes.linewidth']],
471+
clip_on=False)
471472
self.ax.add_collection(self.dividers)
472473

473474
self.locator = None
@@ -627,12 +628,31 @@ def _add_solids(self, X, Y, C):
627628
if not self.drawedges:
628629
if len(self._y) >= self.n_rasterize:
629630
self.solids.set_rasterized(True)
630-
if self.drawedges:
631-
start_idx = 0 if self._extend_lower() else 1
632-
end_idx = len(X) if self._extend_upper() else -1
633-
self.dividers.set_segments(np.dstack([X, Y])[start_idx:end_idx])
634-
else:
631+
self._update_dividers()
632+
633+
def _update_dividers(self):
634+
if not self.drawedges:
635635
self.dividers.set_segments([])
636+
return
637+
# Place all *internal* dividers.
638+
if self.orientation == 'vertical':
639+
lims = self.ax.get_ylim()
640+
bounds = (lims[0] < self._y) & (self._y < lims[1])
641+
else:
642+
lims = self.ax.get_xlim()
643+
bounds = (lims[0] < self._y) & (self._y < lims[1])
644+
y = self._y[bounds]
645+
# And then add outer dividers if extensions are on.
646+
if self._extend_lower():
647+
y = np.insert(y, 0, lims[0])
648+
if self._extend_upper():
649+
y = np.append(y, lims[1])
650+
X, Y = np.meshgrid([0, 1], y)
651+
if self.orientation == 'vertical':
652+
segments = np.dstack([X, Y])
653+
else:
654+
segments = np.dstack([Y, X])
655+
self.dividers.set_segments(segments)
636656

637657
def _add_solids_patches(self, X, Y, C, mappable):
638658
hatches = mappable.hatches * len(C) # Have enough hatches.
@@ -737,7 +757,8 @@ def _do_extends(self, ax=None):
737757
zorder=np.nextafter(self.ax.patch.zorder, -np.inf))
738758
self.ax.add_patch(patch)
739759
self._extend_patches.append(patch)
740-
return
760+
761+
self._update_dividers()
741762

742763
def add_lines(self, *args, **kwargs):
743764
"""

lib/matplotlib/tests/test_colorbar.py

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -929,28 +929,51 @@ def test_proportional_colorbars():
929929
fig.colorbar(CS3, spacing=spacings[j], ax=axs[i, j])
930930

931931

932-
@pytest.mark.parametrize("extend, coloroffset, res", [
933-
('both', 1, [np.array([[0., 0.], [0., 1.]]),
934-
np.array([[1., 0.], [1., 1.]]),
935-
np.array([[2., 0.], [2., 1.]])]),
936-
('min', 0, [np.array([[0., 0.], [0., 1.]]),
937-
np.array([[1., 0.], [1., 1.]])]),
938-
('max', 0, [np.array([[1., 0.], [1., 1.]]),
939-
np.array([[2., 0.], [2., 1.]])]),
940-
('neither', -1, [np.array([[1., 0.], [1., 1.]])])
941-
])
942-
def test_colorbar_extend_drawedges(extend, coloroffset, res):
943-
cmap = plt.get_cmap("viridis")
944-
bounds = np.arange(3)
945-
nb_colors = len(bounds) + coloroffset
946-
colors = cmap(np.linspace(100, 255, nb_colors).astype(int))
947-
cmap, norm = mcolors.from_levels_and_colors(bounds, colors, extend=extend)
948-
949-
plt.figure(figsize=(5, 1))
950-
ax = plt.subplot(111)
951-
cbar = Colorbar(ax, cmap=cmap, norm=norm, orientation='horizontal',
952-
drawedges=True)
953-
assert np.all(np.equal(cbar.dividers.get_segments(), res))
932+
@image_comparison(['extend_drawedges.png'], remove_text=True, style='mpl20')
933+
def test_colorbar_extend_drawedges():
934+
params = [
935+
('both', 1, [[[1.1, 0], [1.1, 1]],
936+
[[2, 0], [2, 1]],
937+
[[2.9, 0], [2.9, 1]]]),
938+
('min', 0, [[[1.1, 0], [1.1, 1]],
939+
[[2, 0], [2, 1]]]),
940+
('max', 0, [[[2, 0], [2, 1]],
941+
[[2.9, 0], [2.9, 1]]]),
942+
('neither', -1, [[[2, 0], [2, 1]]]),
943+
]
944+
945+
plt.rcParams['axes.linewidth'] = 2
946+
947+
fig = plt.figure(figsize=(10, 4))
948+
subfigs = fig.subfigures(1, 2)
949+
950+
for orientation, subfig in zip(['horizontal', 'vertical'], subfigs):
951+
if orientation == 'horizontal':
952+
axs = subfig.subplots(4, 1)
953+
else:
954+
axs = subfig.subplots(1, 4)
955+
fig.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95)
956+
957+
for ax, (extend, coloroffset, res) in zip(axs, params):
958+
cmap = plt.get_cmap("viridis")
959+
bounds = np.arange(5)
960+
nb_colors = len(bounds) + coloroffset
961+
colors = cmap(np.linspace(100, 255, nb_colors).astype(int))
962+
cmap, norm = mcolors.from_levels_and_colors(bounds, colors,
963+
extend=extend)
964+
965+
cbar = Colorbar(ax, cmap=cmap, norm=norm, orientation=orientation,
966+
drawedges=True)
967+
# Set limits such that only two colours are visible, and the
968+
# dividers would be outside the Axes, to ensure that a) they are
969+
# not drawn outside, and b) a divider still appears between the
970+
# main colour and the extension.
971+
if orientation == 'horizontal':
972+
ax.set_xlim(1.1, 2.9)
973+
else:
974+
ax.set_ylim(1.1, 2.9)
975+
res = np.array(res)[:, :, [1, 0]]
976+
np.testing.assert_array_equal(cbar.dividers.get_segments(), res)
954977

955978

956979
def test_negative_boundarynorm():

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy