8000 Merge pull request #23591 from meeseeksmachine/auto-backport-of-pr-23… · matplotlib/matplotlib@0428306 · GitHub
[go: up one dir, main page]

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
"""
Loading

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)
0