Skip to content

Commit 1b6bc17

Browse files
authored
Merge pull request matplotlib#28727 from timhoffm/format-cursor-data
MNT: Better workaround for format_cursor_data on ScalarMappables
2 parents 7a2ea1c + d4f0ebb commit 1b6bc17

File tree

2 files changed

+37
-33
lines changed

2 files changed

+37
-33
lines changed

lib/matplotlib/artist.py

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
import matplotlib as mpl
1515
from . import _api, cbook
16-
from .colors import BoundaryNorm
17-
from .cm import ScalarMappable
1816
from .path import Path
1917
from .transforms import (BboxBase, Bbox, IdentityTransform, Transform, TransformedBbox,
2018
TransformedPatchPath, TransformedPath)
@@ -1346,37 +1344,11 @@ def format_cursor_data(self, data):
13461344
--------
13471345
get_cursor_data
13481346
"""
1349-
if np.ndim(data) == 0 and isinstance(self, ScalarMappable):
1350-
# This block logically belongs to ScalarMappable, but can't be
1351-
# implemented in it because most ScalarMappable subclasses inherit
1352-
# from Artist first and from ScalarMappable second, so
1353-
# Artist.format_cursor_data would always have precedence over
1354-
# ScalarMappable.format_cursor_data.
1355-
n = self.cmap.N
1356-
if np.ma.getmask(data):
1357-
return "[]"
1358-
normed = self.norm(data)
1359-
if np.isfinite(normed):
1360-
if isinstance(self.norm, BoundaryNorm):
1361-
# not an invertible normalization mapping
1362-
cur_idx = np.argmin(np.abs(self.norm.boundaries - data))
1363-
neigh_idx = max(0, cur_idx - 1)
1364-
# use max diff to prevent delta == 0
1365-
delta = np.diff(
1366-
self.norm.boundaries[neigh_idx:cur_idx + 2]
1367-
).max()
1368-
elif self.norm.vmin == self.norm.vmax:
1369-
# singular norms, use delta of 10% of only value
1370-
delta = np.abs(self.norm.vmin * .1)
1371-
else:
1372-
# Midpoints of neighboring color intervals.
1373-
neighbors = self.norm.inverse(
1374-
(int(normed * n) + np.array([0, 1])) / n)
1375-
delta = abs(neighbors - data).max()
1376-
g_sig_digits = cbook._g_sig_digits(data, delta)
1377-
else:
1378-
g_sig_digits = 3 # Consistent with default below.
1379-
return f"[{data:-#.{g_sig_digits}g}]"
1347+
if np.ndim(data) == 0 and hasattr(self, "_format_cursor_data_override"):
1348+
# workaround for ScalarMappable to be able to define its own
1349+
# format_cursor_data(). See ScalarMappable._format_cursor_data_override
1350+
# for details.
1351+
return self._format_cursor_data_override(data)
13801352
else:
13811353
try:
13821354
data[0]

lib/matplotlib/cm.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,38 @@ def changed(self):
611611
self.callbacks.process('changed', self)
612612
self.stale = True
613613

614+
def _format_cursor_data_override(self, data):
615+
# This function overwrites Artist.format_cursor_data(). We cannot
616+
# implement ScalarMappable.format_cursor_data() directly, because
617+
# most ScalarMappable subclasses inherit from Artist first and from
618+
# ScalarMappable second, so Artist.format_cursor_data would always
619+
# have precedence over ScalarMappable.format_cursor_data.
620+
n = self.cmap.N
621+
if np.ma.getmask(data):
622+
return "[]"
623+
normed = self.norm(data)
624+
if np.isfinite(normed):
625+
if isinstance(self.norm, colors.BoundaryNorm):
626+
# not an invertible normalization mapping
627+
cur_idx = np.argmin(np.abs(self.norm.boundaries - data))
628+
neigh_idx = max(0, cur_idx - 1)
629+
# use max diff to prevent delta == 0
630+
delta = np.diff(
631+
self.norm.boundaries[neigh_idx:cur_idx + 2]
632+
).max()
633+
elif self.norm.vmin == self.norm.vmax:
634+
# singular norms, use delta of 10% of only value
635+
delta = np.abs(self.norm.vmin * .1)
636+
else:
637+
# Midpoints of neighboring color intervals.
638+
neighbors = self.norm.inverse(
639+
(int(normed * n) + np.array([0, 1])) / n)
640+
delta = abs(neighbors - data).max()
641+
g_sig_digits = cbook._g_sig_digits(data, delta)
642+
else:
643+
g_sig_digits = 3 # Consistent with default below.
644+
return f"[{data:-#.{g_sig_digits}g}]"
645+
614646

615647
# The docstrings here must be generic enough to apply to all relevant methods.
616648
mpl._docstring.interpd.update(

0 commit comments

Comments
 (0)