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

Skip to content

Commit 0cca1de

Browse files
committed
Implement get_cursor_data for QuadMesh.
The motivation is actually to provide get_cursor_data for hist2d, which uses a QuadMesh to draw itself (see the test). As it turns out, Collection.contains already contains the relevant code to find which path contains the mouse event, so just reuse that.
1 parent 07fd38f commit 0cca1de

File tree

4 files changed

+53
-22
lines changed

4 files changed

+53
-22
lines changed

lib/matplotlib/artist.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,19 +1262,33 @@ def format_cursor_data(self, data):
12621262
method yourself.
12631263
12641264
The default implementation converts ints and floats and arrays of ints
1265-
and floats into a comma-separated string enclosed in square brackets.
1265+
and floats into a comma-separated string enclosed in square brackets,
1266+
unless the artist has an associated colorbar, in which case scalar
1267+
values are formatted using the colorbar's formatter.
12661268
12671269
See Also
12681270
--------
12691271
get_cursor_data
12701272
"""
1271-
try:
1272-
data[0]
1273-
except (TypeError, IndexError):
1274-
data = [data]
1275-
data_str = ', '.join('{:0.3g}'.format(item) for item in data
1276-
if isinstance(item, Number))
1277-
return "[" + data_str + "]"
1273+
if np.ndim(data) == 0 and getattr(self, "colorbar", None):
1274+
# This block logically belongs to ScalarMappable, but can't be
1275+
# implemented in it because most ScalarMappable subclasses inherit
1276+
# from Artist first and from ScalarMappable second, so
1277+
# Artist.format_cursor_data would always have precedence over
1278+
# ScalarMappable.format_cursor_data.
1279+
return (
1280+
"["
1281+
+ cbook.strip_math(
1282+
self.colorbar.formatter.format_data_short(data)).strip()
1283+
+ "]")
1284+
else:
1285+
try:
1286+
data[0]
1287+
except (TypeError, IndexError):
1288+
data = [data]
1289+
data_str = ', '.join('{:0.3g}'.format(item) for item in data
1290+
if isinstance(item, Number))
1291+
return "[" + data_str + "]"
12781292

12791293
@property
12801294
def mouseover(self):

lib/matplotlib/collections.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,7 @@ def draw(self, renderer):
19611961

19621962

19631963
class QuadMesh(Collection):
1964-
"""
1964+
r"""
19651965
Class for the efficient drawing of a quadrilateral mesh.
19661966
19671967
A quadrilateral mesh consists of a grid of vertices.
@@ -1987,11 +1987,16 @@ class QuadMesh(Collection):
19871987
vertex at mesh coordinates (0, 0), then the one at (0, 1), then at (0, 2)
19881988
.. (0, meshWidth), (1, 0), (1, 1), and so on.
19891989
1990-
*shading* may be 'flat', or 'gouraud'
1990+
*shading* may be 'flat', or 'gouraud'.
1991+
1992+
Unlike other `.Collection`\s, the default *pickradius* of `.QuadMesh` is 0,
1993+
i.e. `~.Artist.contains` checks whether the test point is within any of the
1994+
mesh quadrilaterals.
19911995
"""
1996+
19921997
def __init__(self, meshWidth, meshHeight, coordinates,
1993-
antialiased=True, shading='flat', **kwargs):
1994-
super().__init__(**kwargs)
1998+
antialiased=True, shading='flat', *, pickradius=0, **kwargs):
1999+
super().__init__(pickradius=pickradius, **kwargs)
19952000
self._meshWidth = meshWidth
19962001
self._meshHeight = meshHeight
19972002
# By converting to floats now, we can avoid that on every draw.
@@ -2131,6 +2136,14 @@ def draw(self, renderer):
21312136
renderer.close_group(self.__class__.__name__)
21322137
self.stale = False
21332138

2139+
def get_cursor_data(self, event):
2140+
contained, info = self.contains(event)
2141+
if len(info["ind"]) == 1:
2142+
ind, = info["ind"]
2143+
return self.get_array()[ind]
2144+
else:
2145+
return None
2146+
21342147

21352148
_artist_kwdoc = artist.kwdoc(Collection)
21362149
for k in ('QuadMesh', 'TriMesh', 'PolyCollection', 'BrokenBarHCollection',

lib/matplotlib/image.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -997,16 +997,6 @@ def get_cursor_data(self, event):
997997
else:
998998
return arr[i, j]
999999

1000-
def format_cursor_data(self, data):
1001-
if np.ndim(data) == 0 and self.colorbar:
1002-
return (
1003-
"["
1004-
+ cbook.strip_math(
1005-
self.colorbar.formatter.format_data_short(data)).strip()
1006-
+ "]")
1007-
else:
1008-
return super().format_cursor_data(data)
1009-
10101000

10111001
class NonUniformImage(AxesImage):
10121002
mouseover = False # This class still needs its own get_cursor_data impl.

lib/matplotlib/tests/test_collections.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import matplotlib as mpl
99
import matplotlib.pyplot as plt
10+
from matplotlib.backend_bases import MouseEvent
1011
import matplotlib.collections as mcollections
1112
import matplotlib.colors as mcolors
1213
import matplotlib.transforms as mtransforms
@@ -884,3 +885,16 @@ def test_array_wrong_dimensions():
884885
pc = plt.pcolormesh(z)
885886
pc.set_array(z) # 2D is OK for Quadmesh
886887
pc.update_scalarmappable()
888+
889+
890+
def test_quadmesh_cursor_data():
891+
fig, ax = plt.subplots()
892+
*_, qm = ax.hist2d(
893+
np.arange(11)**2, 100 + np.arange(11)**2) # width-10 bins
894+
x, y = ax.transData.transform([1, 101])
895+
event = MouseEvent('motion_notify_event', fig.canvas, x, y)
896+
assert qm.get_cursor_data(event) == 4 # (0**2, 1**2, 2**2, 3**2)
897+
for out_xydata in []:
898+
x, y = ax.transData.transform([-1, 101])
899+
event = MouseEvent('motion_notify_event', fig.canvas, x, y)
900+
assert qm.get_cursor_data(event) is None

0 commit comments

Comments
 (0)