Home > Backend Development > Python Tutorial > How can I add hovering annotations to Matplotlib scatter and line plots to display object names on mouseover?

How can I add hovering annotations to Matplotlib scatter and line plots to display object names on mouseover?

Susan Sarandon
Release: 2024-12-09 11:26:11
Original
248 people have browsed it

How can I add hovering annotations to Matplotlib scatter and line plots to display object names on mouseover?

Adding Hovering Annotations to Scatter Plots

When using matplotlib to create scatter plots where each point represents a specific object, it can be helpful to display the object's name when the cursor hovers over the corresponding point. This allows users to quickly identify outliers or other relevant information without cluttering the plot with permanent labels.

One solution involves using the annotate function to create a label that becomes visible when the cursor hovers over a specific point. Here is an example code snippet:

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.random.rand(15)
y = np.random.rand(15)
names = np.array(list("ABCDEFGHIJKLMNO"))
c = np.random.randint(1, 5, size=15)

norm = plt.Normalize(1, 4)
cmap = plt.cm.RdYlGn

fig, ax = plt.subplots()
sc = plt.scatter(x, y, c=c, s=100, cmap=cmap, norm=norm)

annot = ax.annotate("", xy=(0, 0), xytext=(20, 20), textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)


def update_annot(ind):
    pos = sc.get_offsets()[ind["ind"][0]]
    annot.xy = pos
    text = "{}, {}".format(" ".join(list(map(str, ind["ind"]))),
                           " ".join([names[n] for n in ind["ind"]]))
    annot.set_text(text)
    annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]])))
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = sc.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()
Copy after login

This code defines a scatter plot with 15 random points. Each point is associated with a name from the names array. The annotate function creates a label that initially remains invisible.

The hover function is defined to handle mouse movement events. When the cursor hovers over a point, it checks if the point is contained within the scatter plot. If so, it updates the annotation with the object's name and position, makes it visible, and redraws the figure. When the cursor leaves the point, the annotation is hidden.

For line plots instead of scatter plots, the same solution can be adapted as follows:

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

x = np.sort(np.random.rand(15))
y = np.sort(np.random.rand(15))
names = np.array(list("ABCDEFGHIJKLMNO"))

norm = plt.Normalize(1, 4)
cmap = plt.cm.RdYlGn

fig, ax = plt.subplots()
line, = plt.plot(x, y, marker="o")

annot = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"),
                    arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)


def update_annot(ind):
    x, y = line.get_data()
    annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
    text = "{}, {}".format(" ".join(list(map(str, ind["ind"]))),
                           " ".join([names[n] for n in ind["ind"]]))
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax:
        cont, ind = line.contains(event)
        if cont:
            update_annot(ind)
            annot.set_visible(True)
            fig.canvas.draw_idle()
        else:
            if vis:
                annot.set_visible(False)
                fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()
Copy after login

The above is the detailed content of How can I add hovering annotations to Matplotlib scatter and line plots to display object names on mouseover?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template