1"""
2====================
3Trifinder Event Demo
4====================
5
6Example showing the use of a TriFinder object.  As the mouse is moved over the
7triangulation, the triangle under the cursor is highlighted and the index of
8the triangle is displayed in the plot title.
9"""
10import matplotlib.pyplot as plt
11from matplotlib.tri import Triangulation
12from matplotlib.patches import Polygon
13import numpy as np
14
15
16def update_polygon(tri):
17    if tri == -1:
18        points = [0, 0, 0]
19    else:
20        points = triang.triangles[tri]
21    xs = triang.x[points]
22    ys = triang.y[points]
23    polygon.set_xy(np.column_stack([xs, ys]))
24
25
26def on_mouse_move(event):
27    if event.inaxes is None:
28        tri = -1
29    else:
30        tri = trifinder(event.xdata, event.ydata)
31    update_polygon(tri)
32    ax.set_title(f'In triangle {tri}')
33    event.canvas.draw()
34
35
36# Create a Triangulation.
37n_angles = 16
38n_radii = 5
39min_radius = 0.25
40radii = np.linspace(min_radius, 0.95, n_radii)
41angles = np.linspace(0, 2 * np.pi, n_angles, endpoint=False)
42angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
43angles[:, 1::2] += np.pi / n_angles
44x = (radii*np.cos(angles)).flatten()
45y = (radii*np.sin(angles)).flatten()
46triang = Triangulation(x, y)
47triang.set_mask(np.hypot(x[triang.triangles].mean(axis=1),
48                         y[triang.triangles].mean(axis=1))
49                < min_radius)
50
51# Use the triangulation's default TriFinder object.
52trifinder = triang.get_trifinder()
53
54# Setup plot and callbacks.
55fig, ax = plt.subplots(subplot_kw={'aspect': 'equal'})
56ax.triplot(triang, 'bo-')
57polygon = Polygon([[0, 0], [0, 0]], facecolor='y')  # dummy data for (xs, ys)
58update_polygon(-1)
59ax.add_patch(polygon)
60fig.canvas.mpl_connect('motion_notify_event', on_mouse_move)
61plt.show()
62