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

Skip to content

Commit 1df0529

Browse files
authored
Merge pull request #20582 from jklymak/fix-twoslopenorm-colorbar
Fix twoslopenorm colorbar
2 parents 14b34fd + 38ad08e commit 1df0529

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

lib/matplotlib/colors.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,9 +1300,11 @@ def __call__(self, value, clip=None):
13001300

13011301
if not self.vmin <= self.vcenter <= self.vmax:
13021302
raise ValueError("vmin, vcenter, vmax must increase monotonically")
1303+
# note that we must extrapolate for tick locators:
13031304
result = np.ma.masked_array(
13041305
np.interp(result, [self.vmin, self.vcenter, self.vmax],
1305-
[0, 0.5, 1.]), mask=np.ma.getmask(result))
1306+
[0, 0.5, 1], left=-np.inf, right=np.inf),
1307+
mask=np.ma.getmask(result))
13061308
if is_scalar:
13071309
result = np.atleast_1d(result)[0]
13081310
return result
@@ -1313,8 +1315,8 @@ def inverse(self, value):
13131315
(vmin,), _ = self.process_value(self.vmin)
13141316
(vmax,), _ = self.process_value(self.vmax)
13151317
(vcenter,), _ = self.process_value(self.vcenter)
1316-
1317-
result = np.interp(value, [0, 0.5, 1.], [vmin, vcenter, vmax])
1318+
result = np.interp(value, [0, 0.5, 1], [vmin, vcenter, vmax],
1319+
left=-np.inf, right=np.inf)
13181320
return result
13191321

13201322

lib/matplotlib/tests/test_colorbar.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,11 +765,12 @@ def test_inset_colorbar_layout():
765765
@image_comparison(['colorbar_twoslope.png'], remove_text=True,
766766
style='mpl20')
767767
def test_twoslope_colorbar():
768-
# Note that the first tick = 20, and should be in the middle
768+
# Note that the second tick = 20, and should be in the middle
769769
# of the colorbar (white)
770+
# There should be no tick right at the bottom, nor at the top.
770771
fig, ax = plt.subplots()
771772

772-
norm = mcolors.TwoSlopeNorm(20, 0, 100)
773+
norm = mcolors.TwoSlopeNorm(20, 5, 95)
773774
pc = ax.pcolormesh(np.arange(1, 11), np.arange(1, 11),
774775
np.arange(100).reshape(10, 10),
775776
norm=norm, cmap='RdBu_r')

tutorials/colors/colormapnorms.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@
277277
# longitude depends on latitude.
278278
ax.set_aspect(1 / np.cos(np.deg2rad(49)))
279279
ax.set_title('TwoSlopeNorm(x)')
280-
fig.colorbar(pcm, shrink=0.6)
280+
cb = fig.colorbar(pcm, shrink=0.6)
281+
cb.set_ticks([-500, 0, 1000, 2000, 3000, 4000])
281282
plt.show()
282283

283284

@@ -312,7 +313,8 @@ def _inverse(x):
312313
# ----------------------------------------------------------
313314
#
314315
# The `.TwoSlopeNorm` described above makes a useful example for
315-
# defining your own norm.
316+
# defining your own norm. Note for the colorbar to work, you must
317+
# define an inverse for your norm:
316318

317319

318320
class MidpointNormalize(colors.Normalize):
@@ -323,8 +325,14 @@ def __init__(self, vmin=None, vmax=None, vcenter=None, clip=False):
323325
def __call__(self, value, clip=None):
324326
# I'm ignoring masked values and all kinds of edge cases to make a
325327
# simple example...
326-
x, y = [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1]
327-
return np.ma.masked_array(np.interp(value, x, y))
328+
# Note also that we must extrapolate beyond vmin/vmax
329+
x, y = [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1.]
330+
return np.ma.masked_array(np.interp(value, x, y,
331+
left=-np.inf, right=np.inf))
332+
333+
def inverse(self, value):
334+
y, x = [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1]
335+
return np.interp(value, x, y, left=-np.inf, right=np.inf)
328336

329337

330338
fig, ax = plt.subplots()
@@ -334,5 +342,7 @@ def __call__(self, value, clip=None):
334342
cmap=terrain_map, shading='auto')
335343
ax.set_aspect(1 / np.cos(np.deg2rad(49)))
336344
ax.set_title('Custom norm')
337-
fig.colorbar(pcm, shrink=0.6, extend='both')
345+
cb = fig.colorbar(pcm, shrink=0.6, extend='both')
346+
cb.set_ticks([-500, 0, 1000, 2000, 3000, 4000])
347+
338348
plt.show()

0 commit comments

Comments
 (0)