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

Skip to content

Implement get_cursor_data for QuadMesh. #19908

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
merged 1 commit into from
May 27, 2021
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
30 changes: 22 additions & 8 deletions lib/matplotlib/artist.py
Original file line number Diff line number Diff line change
Expand Up @@ -1251,19 +1251,33 @@ def format_cursor_data(self, data):
method yourself.

The default implementation converts ints and floats and arrays of ints
and floats into a comma-separated string enclosed in square brackets.
and floats into a comma-separated string enclosed in square brackets,
unless the artist has an associated colorbar, in which case scalar
values are formatted using the colorbar's formatter.

See Also
--------
get_cursor_data
"""
try:
data[0]
except (TypeError, IndexError):
data = [data]
data_str = ', '.join('{:0.3g}'.format(item) for item in data
if isinstance(item, Number))
return "[" + data_str + "]"
if np.ndim(data) == 0 and getattr(self, "colorbar", None):
Copy link
Member

@timhoffm timhoffm Apr 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there better criterion than having a colorbar?

You still have a value (~color) in the mesh even if that's not explained via a colorbar. It would be nice if this works for a simple plt.pcolormesh() call. Also if you plot on multiple Axes with "shared" colors and use only one colorbar as description, AFAIK only one of the Mappables will be associated with the colorbar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "colorbar-for-value-formatting" discussion is at #12473 (I personally just patch matplotlib locally with that PR...). I think it's orthogonal to the feature here?

# This block logically belongs to ScalarMappable, but can't be
# implemented in it because most ScalarMappable subclasses inherit
# from Artist first and from ScalarMappable second, so
# Artist.format_cursor_data would always have precedence over
# ScalarMappable.format_cursor_data.
return (
"["
+ cbook.strip_math(
self.colorbar.formatter.format_data_short(data)).strip()
+ "]")
else:
try:
data[0]
except (TypeError, IndexError):
data = [data]
data_str = ', '.join('{:0.3g}'.format(item) for item in data
if isinstance(item, Number))
return "[" + data_str + "]"

@property
def mouseover(self):
Expand Down
19 changes: 16 additions & 3 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,7 @@ def draw(self, renderer):


class QuadMesh(Collection):
"""
r"""
Class for the efficient drawing of a quadrilateral mesh.

A quadrilateral mesh is a grid of M by N adjacent qudrilaterals that are
Expand All @@ -1957,6 +1957,10 @@ class QuadMesh(Collection):

Notes
-----
Unlike other `.Collection`\s, the default *pickradius* of `.QuadMesh` is 0,
i.e. `~.Artist.contains` checks whether the test point is within any of the
mesh quadrilaterals.

There exists a deprecated API version ``QuadMesh(M, N, coords)``, where
the dimensions are given explicitly and ``coords`` is a (M*N, 2)
array-like. This has been deprecated in Matplotlib 3.5. The following
Expand Down Expand Up @@ -1984,8 +1988,8 @@ class QuadMesh(Collection):
For example, the first entry in *coordinates* is the coordinates of the
vertex at mesh coordinates (0, 0), then the one at (0, 1), then at (0, 2)
.. (0, meshWidth), (1, 0), (1, 1), and so on.

"""

def __init__(self, *args, **kwargs):
# signature deprecation since="3.5": Change to new signature after the
# deprecation has expired. Also remove setting __init__.__signature__,
Expand Down Expand Up @@ -2017,6 +2021,7 @@ def __init__(self, *args, **kwargs):
"coordinates must be 2D; all parameters except "
"coordinates will be keyword-only.")
coords = np.asarray(coords, np.float64).reshape((h + 1, w + 1, 2))
kwargs.setdefault("pickradius", 0)
# end of signature deprecation code

super().__init__(**kwargs)
Expand All @@ -2031,7 +2036,7 @@ def __init__(self, *args, **kwargs):
# Only needed during signature deprecation
__init__.__signature__ = inspect.signature(
lambda self, coordinates, *,
antialiased=True, shading='flat', **kwargs: None)
antialiased=True, shading='flat', pickradius=0, **kwargs: None)

def get_paths(self):
if self._paths is None:
Expand Down Expand Up @@ -2162,3 +2167,11 @@ def draw(self, renderer):
gc.restore()
renderer.close_group(self.__class__.__name__)
self.stale = False

def get_cursor_data(self, event):
contained, info = self.contains(event)
if len(info["ind"]) == 1:
ind, = info["ind"]
return self.get_array()[ind]
else:
return None
10 changes: 0 additions & 10 deletions lib/matplotlib/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -995,16 +995,6 @@ def get_cursor_data(self, event):
else:
return arr[i, j]

def format_cursor_data(self, data):
if np.ndim(data) == 0 and self.colorbar:
return (
"["
+ cbook.strip_math(
self.colorbar.formatter.format_data_short(data)).strip()
+ "]")
else:
return super().format_cursor_data(data)


class NonUniformImage(AxesImage):
mouseover = False # This class still needs its own get_cursor_data impl.
Expand Down
14 changes: 14 additions & 0 deletions lib/matplotlib/tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.backend_bases import MouseEvent
import matplotlib.collections as mcollections
import matplotlib.colors as mcolors
import matplotlib.transforms as mtransforms
Expand Down Expand Up @@ -972,3 +973,16 @@ def test_array_wrong_dimensions():
pc = plt.pcolormesh(z)
pc.set_array(z) # 2D is OK for Quadmesh
pc.update_scalarmappable()


def test_quadmesh_cursor_data():
fig, ax = plt.subplots()
*_, qm = ax.hist2d(
np.arange(11)**2, 100 + np.arange(11)**2) # width-10 bins
x, y = ax.transData.transform([1, 101])
event = MouseEvent('motion_notify_event', fig.canvas, x, y)
assert qm.get_cursor_data(event) == 4 # (0**2, 1**2, 2**2, 3**2)
for out_xydata in []:
x, y = ax.transData.transform([-1, 101])
event = MouseEvent('motion_notify_event', fig.canvas, x, y)
assert qm.get_cursor_data(event) is None