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

Skip to content

Backport PR #22835 on branch v3.5.x (Fix BoundaryNorm cursor data output) #23331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions lib/matplotlib/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import matplotlib as mpl
from . import _api, cbook
from .colors import BoundaryNorm
from .cm import ScalarMappable
from .path import Path
from .transforms import (Bbox, IdentityTransform, Transform, TransformedBbox,
Expand Down Expand Up @@ -1280,10 +1281,20 @@ def format_cursor_data(self, data):
return "[]"
normed = self.norm(data)
if np.isfinite(normed):
# Midpoints of neighboring color intervals.
neighbors = self.norm.inverse(
(int(self.norm(data) * n) + np.array([0, 1])) / n)
delta = abs(neighbors - data).max()
if isinstance(self.norm, BoundaryNorm):
# not an invertible normalization mapping
cur_idx = np.argmin(np.abs(self.norm.boundaries - data))
neigh_idx = max(0, cur_idx - 1)
# use max diff to prevent delta == 0
delta = np.diff(
self.norm.boundaries[neigh_idx:cur_idx + 2]
).max()

else:
# Midpoints of neighboring color intervals.
neighbors = self.norm.inverse(
(int(normed * n) + np.array([0, 1])) / n)
delta = abs(neighbors - data).max()
g_sig_digits = cbook._g_sig_digits(data, delta)
else:
g_sig_digits = 3 # Consistent with default below.
Expand Down
163 changes: 163 additions & 0 deletions lib/matplotlib/tests/test_artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import pytest

from matplotlib import cm
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
Expand Down Expand Up @@ -374,3 +376,164 @@ class MyArtist4(MyArtist3):
pass

assert MyArtist4.set is MyArtist3.set


def test_format_cursor_data_BoundaryNorm():
"""Test if cursor data is correct when using BoundaryNorm."""
X = np.empty((3, 3))
X[0, 0] = 0.9
X[0, 1] = 0.99
X[0, 2] = 0.999
X[1, 0] = -1
X[1, 1] = 0
X[1, 2] = 1
X[2, 0] = 0.09
X[2, 1] = 0.009
X[2, 2] = 0.0009

# map range -1..1 to 0..256 in 0.1 steps
fig, ax = plt.subplots()
fig.suptitle("-1..1 to 0..256 in 0.1")
norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 20), 256)
img = ax.imshow(X, cmap='RdBu_r', norm=norm)

labels_list = [
"[0.9]",
"[1.]",
"[1.]",
"[-1.0]",
"[0.0]",
"[1.0]",
"[0.09]",
"[0.009]",
"[0.0009]",
]
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.1))
assert img.format_cursor_data(v) == label

plt.close()

# map range -1..1 to 0..256 in 0.01 steps
fig, ax = plt.subplots()
fig.suptitle("-1..1 to 0..256 in 0.01")
cmap = cm.get_cmap('RdBu_r', 200)
norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 200), 200)
img = ax.imshow(X, cmap=cmap, norm=norm)

labels_list = [
"[0.90]",
"[0.99]",
"[1.0]",
"[-1.00]",
"[0.00]",
"[1.00]",
"[0.09]",
"[0.009]",
"[0.0009]",
]
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.01))
assert img.format_cursor_data(v) == label

plt.close()

# map range -1..1 to 0..256 in 0.01 steps
fig, ax = plt.subplots()
fig.suptitle("-1..1 to 0..256 in 0.001")
cmap = cm.get_cmap('RdBu_r', 2000)
norm = mcolors.BoundaryNorm(np.linspace(-1, 1, 2000), 2000)
img = ax.imshow(X, cmap=cmap, norm=norm)

labels_list = [
"[0.900]",
"[0.990]",
"[0.999]",
"[-1.000]",
"[0.000]",
"[1.000]",
"[0.090]",
"[0.009]",
"[0.0009]",
]
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.001))
assert img.format_cursor_data(v) == label

plt.close()

# different testing data set with
# out of bounds values for 0..1 range
X = np.empty((7, 1))
X[0] = -1.0
X[1] = 0.0
X[2] = 0.1
X[3] = 0.5
X[4] = 0.9
X[5] = 1.0
X[6] = 2.0

labels_list = [
"[-1.0]",
"[0.0]",
"[0.1]",
"[0.5]",
"[0.9]",
"[1.0]",
"[2.0]",
]

fig, ax = plt.subplots()
fig.suptitle("noclip, neither")
norm = mcolors.BoundaryNorm(
np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='neither')
img = ax.imshow(X, cmap='RdBu_r', norm=norm)
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33))
assert img.format_cursor_data(v) == label

plt.close()

fig, ax = plt.subplots()
fig.suptitle("noclip, min")
norm = mcolors.BoundaryNorm(
np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='min')
img = ax.imshow(X, cmap='RdBu_r', norm=norm)
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33))
assert img.format_cursor_data(v) == label

plt.close()

fig, ax = plt.subplots()
fig.suptitle("noclip, max")
norm = mcolors.BoundaryNorm(
np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='max')
img = ax.imshow(X, cmap='RdBu_r', norm=norm)
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33))
assert img.format_cursor_data(v) == label

plt.close()

fig, ax = plt.subplots()
fig.suptitle("noclip, both")
norm = mcolors.BoundaryNorm(
np.linspace(0, 1, 4, endpoint=True), 256, clip=False, extend='both')
img = ax.imshow(X, cmap='RdBu_r', norm=norm)
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33))
assert img.format_cursor_data(v) == label

plt.close()

fig, ax = plt.subplots()
fig.suptitle("clip, neither")
norm = mcolors.BoundaryNorm(
np.linspace(0, 1, 4, endpoint=True), 256, clip=True, extend='neither')
img = ax.imshow(X, cmap='RdBu_r', norm=norm)
for v, label in zip(X.flat, labels_list):
# label = "[{:-#.{}g}]".format(v, cbook._g_sig_digits(v, 0.33))
assert img.format_cursor_data(v) == label

plt.close()