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

Skip to content

Commit 930bd2f

Browse files
committed
Fix colorbar dividers with explicit limits
In this case, place dividers at the same place internally, but then always place a divider at the Axes limits (when there's an extend triangle there).
1 parent 8fa6bd5 commit 930bd2f

3 files changed

Lines changed: 71 additions & 28 deletions

File tree

lib/matplotlib/colorbar.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -651,12 +651,31 @@ def _add_solids(self, X, Y, C):
651651
if not self.drawedges:
652652
if len(self._y) >= self.n_rasterize:
653653
self.solids.set_rasterized(True)
654-
if self.drawedges:
655-
start_idx = 0 if self._extend_lower() else 1
656-
end_idx = len(X) if self._extend_upper() else -1
657-
self.dividers.set_segments(np.dstack([X, Y])[start_idx:end_idx])
658-
else:
654+
self._update_dividers()
655+
656+
def _update_dividers(self):
657+
if not self.drawedges:
659658
self.dividers.set_segments([])
659+
return
660+
# Place all *internal* dividers.
661+
if self.orientation == 'vertical':
662+
lims = self.ax.get_ylim()
663+
bounds = (lims[0] < self._y) & (self._y < lims[1])
664+
else:
665+
lims = self.ax.get_xlim()
666+
bounds = (lims[0] < self._y) & (self._y < lims[1])
667+
y = self._y[bounds]
668+
# And then add outer dividers if extensions are on.
669+
if self._extend_lower():
670+
y = np.insert(y, 0, lims[0])
671+
if self._extend_upper():
672+
y = np.append(y, lims[1])
673+
X, Y = np.meshgrid([0, 1], y)
674+
if self.orientation == 'vertical':
675+
segments = np.dstack([X, Y])
676+
else:
677+
segments = np.dstack([Y, X])
678+
self.dividers.set_segments(segments)
660679

661680
def _add_solids_patches(self, X, Y, C, mappable):
662681
hatches = mappable.hatches * len(C) # Have enough hatches.
@@ -761,7 +780,8 @@ def _do_extends(self, ax=None):
761780
zorder=np.nextafter(self.ax.patch.zorder, -np.inf))
762781
self.ax.add_patch(patch)
763782
self._extend_patches.append(patch)
764-
return
783+
784+
self._update_dividers()
765785

766786
def add_lines(self, *args, **kwargs):
767787
"""
16.4 KB
Loading

lib/matplotlib/tests/test_colorbar.py

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

933933

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

957980

958981
def test_negative_boundarynorm():

0 commit comments

Comments
 (0)