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

Skip to content

Commit 5211ed8

Browse files
authored
Merge pull request #11584 from pharshalp/fix-colorbar-minor-ticks
ENH: fix colorbar bad minor ticks
2 parents 21b102e + ae6eaf0 commit 5211ed8

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Add ``minorticks_on()/off()`` methods for colorbar
2+
--------------------------------------------------
3+
4+
A new method :meth:`.Colobar.minorticks_on` is
5+
introduced to correctly display minor ticks on the colorbar. This method
6+
doesn't allow the minor ticks to extend into the regions beyond vmin and vmax
7+
when the extend `kwarg` (used while creating the colorbar) is set to 'both',
8+
'max' or 'min'.
9+
A complementary method :meth:`.Colobar.minorticks_off`
10+
is introduced to remove the minor ticks on the colorbar.

examples/color/colorbar_basics.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
Zpos = np.ma.masked_less(Z, 0)
2121
Zneg = np.ma.masked_greater(Z, 0)
2222

23-
fig, (ax1, ax2) = plt.subplots(figsize=(8, 3), ncols=2)
23+
fig, (ax1, ax2, ax3) = plt.subplots(figsize=(13, 3), ncols=3)
2424

2525
# plot just the positive data and save the
2626
# color "mappable" object returned by ax1.imshow
@@ -35,6 +35,13 @@
3535
neg = ax2.imshow(Zneg, cmap='Reds_r', interpolation='none')
3636
fig.colorbar(neg, ax=ax2)
3737

38+
# Plot both positive and negative values betwen +/- 1.2
39+
pos_neg_clipped = ax3.imshow(Z, cmap='RdBu', vmin=-1.2, vmax=1.2,
40+
interpolation='none')
41+
# Add minorticks on the colorbar to make it easy to read the
42+
# values off the colorbar.
43+
cbar = fig.colorbar(pos_neg_clipped, ax=ax3, extend='both')
44+
cbar.minorticks_on()
3845
plt.show()
3946

4047
#############################################################################

lib/matplotlib/colorbar.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,32 @@ def tick_values(self, vmin, vmax):
244244
return ticks[(ticks >= vmin) & (ticks <= vmax)]
245245

246246

247+
class _ColorbarAutoMinorLocator(ticker.AutoMinorLocator):
248+
"""
249+
AutoMinorLocator for Colorbar
250+
251+
This locator is just a `.AutoMinorLocator` except the min and max are
252+
clipped by the norm's min and max (i.e. vmin/vmax from the
253+
image/pcolor/contour object). This is necessary so that the minorticks
254+
don't extrude into the "extend regions".
255+
"""
256+
257+
def __init__(self, colorbar, n=None):
258+
"""
259+
This ticker needs to know the *colorbar* so that it can access
260+
its *vmin* and *vmax*.
261+
"""
262+
self._colorbar = colorbar
263+
self.ndivs = n
264+
ticker.AutoMinorLocator.__init__(self, n=None)
265+
266+
def __call__(self):
267+
vmin = self._colorbar.norm.vmin
268+
vmax = self._colorbar.norm.vmax
269+
ticks = ticker.AutoMinorLocator.__call__(self)
270+
return ticks[(ticks >= vmin) & (ticks <= vmax)]
271+
272+
247273
class _ColorbarLogLocator(ticker.LogLocator):
248274
"""
249275
LogLocator for Colorbarbar
@@ -1164,6 +1190,33 @@ def remove(self):
11641190
# use_gridspec was True
11651191
ax.set_subplotspec(subplotspec)
11661192

1193+
def minorticks_on(self):
1194+
"""
1195+
Turns on the minor ticks on the colorbar without extruding
1196+
into the "extend regions".
1197+
"""
1198+
ax = self.ax
1199+
long_axis = ax.yaxis if self.orientation == 'vertical' else ax.xaxis
1200+
1201+
if long_axis.get_scale() == 'log':
1202+
warnings.warn('minorticks_on() has no effect on a '
1203+
'logarithmic colorbar axis')
1204+
else:
1205+
long_axis.set_minor_locator(_ColorbarAutoMinorLocator(self))
1206+
1207+
def minorticks_off(self):
1208+
"""
1209+
Turns off the minor ticks on the colorbar.
1210+
"""
1211+
ax = self.ax
1212+
long_axis = ax.yaxis if self.orientation == 'vertical' else ax.xaxis
1213+
1214+
if long_axis.get_scale() == 'log':
1215+
warnings.warn('minorticks_off() has no effect on a '
1216+
'logarithmic colorbar axis')
1217+
else:
1218+
long_axis.set_minor_locator(ticker.NullLocator())
1219+
11671220

11681221
@docstring.Substitution(make_axes_kw_doc)
11691222
def make_axes(parents, location=None, orientation=None, fraction=0.15,

lib/matplotlib/tests/test_colorbar.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,31 @@ def test_colorbar_ticks():
270270
assert len(cbar.ax.xaxis.get_ticklocs()) == len(clevs)
271271

272272

273+
def test_colorbar_minorticks_on_off():
274+
# test for github issue #11510 and PR #11584
275+
np.random.seed(seed=12345)
276+
data = np.random.randn(20, 20)
277+
with rc_context({'_internal.classic_mode': False}):
278+
fig, ax = plt.subplots()
279+
# purposefully setting vmin and vmax to odd fractions
280+
# so as to check for the correct locations of the minor ticks
281+
im = ax.pcolormesh(data, vmin=-2.3, vmax=3.3)
282+
283+
cbar = fig.colorbar(im, extend='both')
284+
cbar.minorticks_on()
285+
correct_minorticklocs = np.array([-2.2, -1.8, -1.6, -1.4, -1.2, -0.8,
286+
-0.6, -0.4, -0.2, 0.2, 0.4, 0.6,
287+
0.8, 1.2, 1.4, 1.6, 1.8, 2.2, 2.4,
288+
2.6, 2.8, 3.2])
289+
# testing after minorticks_on()
290+
np.testing.assert_almost_equal(cbar.ax.yaxis.get_minorticklocs(),
291+
correct_minorticklocs)
292+
cbar.minorticks_off()
293+
# testing after minorticks_off()
294+
np.testing.assert_almost_equal(cbar.ax.yaxis.get_minorticklocs(),
295+
np.array([]))
296+
297+
273298
def test_colorbar_autoticks():
274299
# Test new autotick modes. Needs to be classic because
275300
# non-classic doesn't go this route.

0 commit comments

Comments
 (0)