Skip to content

Commit 66ade4e

Browse files
authored
Merge pull request #7 from eslothower/task3
modified hover functions stub files & fixed style
2 parents 5c5e5cc + 736d53e commit 66ade4e

File tree

4 files changed

+58
-51
lines changed

4 files changed

+58
-51
lines changed

lib/matplotlib/artist.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,14 +640,23 @@ def set_hover(self, hover):
640640
641641
Parameters
642642
----------
643-
hover : None or bool
643+
hover : None or bool or callable or list
644644
This can be one of the following:
645645
646646
- *None*: Hover is disabled for this artist (default).
647647
648648
- A boolean: If *True* then hover will be enabled and the
649649
artist will fire a hover event if the mouse event is hovering over
650650
the artist.
651+
652+
- A function: If hover is callable, it is a user supplied
653+
function which sets the hover message to be displayed.
654+
655+
- A list: If hover is a list of string literals, each string represents
656+
an additional information assigned to each data point. These arbitrary
657+
data labels will appear as a tooltip in the bottom right hand corner
658+
of the screen when the cursor is detected to be hovering over a data
659+
point that corresponds with one of the data labels.
651660
"""
652661
self._hover = hover
653662

lib/matplotlib/artist.pyi

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,18 @@ class Artist:
7878
]: ...
7979
def hoverable(self) -> bool: ...
8080
def hover(self, mouseevent: MouseEvent) -> None: ...
81-
def set_hover(self, hover: None | bool) -> None: ...
82-
def get_hover(self) -> None | bool: ...
81+
def set_hover(
82+
self,
83+
hover: None
84+
| bool
85+
| list[str]
86+
| Callable[[Artist, MouseEvent], tuple[bool, dict[Any, Any]]],
87+
) -> None: ...
88+
def get_hover(
89+
self,
90+
) -> None | bool | list[str] | Callable[
91+
[Artist, MouseEvent], tuple[bool, dict[Any, Any]]
92+
]: ...
8393
def get_url(self) -> str | None: ...
8494
def set_url(self, url: str | None) -> None: ...
8595
def get_gid(self) -> str | None: ...

lib/matplotlib/backend_bases.py

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3010,49 +3010,46 @@ def _mouse_event_to_message(event):
30103010
return s
30113011
return ""
30123012

3013-
def mouse_move(self, event):
3013+
def _nonrect(self, x):
30143014
from .patches import Rectangle
3015+
return not isinstance(x, Rectangle)
3016+
3017+
def _tooltip_list(self, event, hover):
3018+
import matplotlib.pyplot as plt
3019+
lines = plt.gca().get_lines()
3020+
num_of_points = 0
3021+
for line in lines:
3022+
num_of_points += 1
3023+
if num_of_points >= len(hover):
3024+
raise ValueError("""Number of data points
3025+
does not match up with number of labels""")
3026+
else:
3027+
mouse_x = event.xdata
3028+
mouse_y = event.ydata
3029+
for line in lines:
3030+
x_data = line.get_xdata()
3031+
y_data = line.get_ydata()
3032+
for i in range(len(x_data)):
3033+
distance = ((event.xdata - x_data[i])**2
3034+
+ (event.ydata - y_data[i])**2)**0.5
3035+
if distance < 0.05:
3036+
return "Data Label: " + hover[i]
3037+
3038+
def mouse_move(self, event):
30153039
self._update_cursor(event)
30163040
self.set_message(self._mouse_event_to_message(event))
30173041

30183042
if callable(getattr(self, 'set_hover_message', None)):
3019-
for a in self.canvas.figure.findobj(match=lambda x: not isinstance(x,
3020-
Rectangle), include_self=False):
3021-
inside = a.contains(event)
3043+
for a in self.canvas.figure.findobj(match=self._nonrect,
3044+
include_self=False):
3045+
inside, prop = a.contains(event)
30223046
if inside:
30233047
if a.hoverable():
30243048
hover = a.get_hover()
30253049
if callable(hover):
3026-
newX, newY = hover(event)
3027-
(self.set_hover_message("modified x = " + str(newX)
3028-
+ " modified y = " +
3029-
str(newY) +
3030-
" Original coords: "
3031-
))
3050+
self.set_hover_message(hover(event))
30323051
elif type(hover) == list:
3033-
import matplotlib.pyplot as plt
3034-
lines = plt.gca().get_lines()
3035-
num_of_points = 0
3036-
for line in lines:
3037-
num_of_points += 1
3038-
if num_of_points >= len(hover):
3039-
raise ValueError("""Number of data points
3040-
does not match up woth number of labels""")
3041-
else:
3042-
mouse_x = event.xdata
3043-
mouse_y = event.ydata
3044-
for line in lines:
3045-
x_data = line.get_xdata()
3046-
y_data = line.get_ydata()
3047-
for i in range(len(x_data)):
3048-
distance = ((event.xdata - x_data[i])**2
3049-
+ (event.ydata - y_data[i])**2)**0.5
3050-
if distance < 0.05:
3051-
(self.set_hover_message("Data Label: "
3052-
+ hover[i] +
3053-
" " +
3054-
"Original coords: "
3055-
))
3052+
self.set_hover_message(self._tooltip_list(event, hover))
30563053
else:
30573054
self.set_hover_message(self._mouse_event_to_message(event))
30583055
else:

lib/matplotlib/tests/test_toolkit.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,21 @@
33
from numpy.random import rand
44
matplotlib.use('tkagg')
55

6+
fig, ax = plt.subplots()
67

7-
# Run this if it seems like your chanegs aren't being applied. If this does not
8-
# print something along the lines of:
9-
# 3.8.0.dev898+g0a062ed8bf.d20230506 /Users/eslothower/Desktop/matplotlib/lib/
10-
# matplotlib/__init__.py
11-
# then this means you did not set up matplotlib for development:
12-
# https://matplotlib.org/stable/devel/development_setup.html
13-
14-
# print(matplotlib.__version__, matplotlib.__file__)
158

16-
# fig, ax = plt.subplots()
17-
# plt.ylabel('some numbers')
9+
def user_defined_function(event):
10+
x, y = round(event.xdata * 10, 1), round(event.ydata + 3, 3)
11+
return f'({x}, {y})'
1812

1913

20-
# def user_defined_function(event):
21-
# return round(event.xdata * 10, 1), round(event.ydata + 3, 3)
14+
ax.plot(rand(100), 'o', hover=user_defined_function)
15+
plt.show()
2216

23-
# ax.plot(rand(100), 'o', hover=user_defined_function)
24-
# plt.show()
2517

2618
# Alternative test for testing out string literals as tooltips:
2719

2820
fig, ax = plt.subplots()
29-
plt.ylabel('some numbers')
3021

3122
ax.plot(rand(3), 'o', hover=['London', 'Paris', 'Barcelona'])
3223
plt.show()

0 commit comments

Comments
 (0)