Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1df0529

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

File tree

Expand file treeCollapse file tree

4 files changed

+23
-10
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+23
-10
lines changed

‎lib/matplotlib/colors.py

Copy file name to clipboardExpand all lines: lib/matplotlib/colors.py
+5-3Lines 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

Loading

‎lib/matplotlib/tests/test_colorbar.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_colorbar.py
+3-2Lines 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

Copy file name to clipboardExpand all lines: tutorials/colors/colormapnorms.py
+15-5Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.