Maison >développement back-end >Tutoriel Python >Comment puis-je ajouter des annotations de survol aux nuages ​​de points et aux courbes Matplotlib pour afficher les noms d'objets au survol de la souris ?

Comment puis-je ajouter des annotations de survol aux nuages ​​de points et aux courbes Matplotlib pour afficher les noms d'objets au survol de la souris ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-09 11:26:11245parcourir

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

Ajout d'annotations de survol aux nuages ​​de points

Lorsque vous utilisez matplotlib pour créer des nuages ​​de points où chaque point représente un objet spécifique, il peut être utile de afficher le nom de l'objet lorsque le curseur passe sur le point correspondant. Cela permet aux utilisateurs d'identifier rapidement les valeurs aberrantes ou d'autres informations pertinentes sans encombrer le tracé avec des étiquettes permanentes.

Une solution consiste à utiliser la fonction d'annotation pour créer une étiquette qui devient visible lorsque le curseur passe sur un point spécifique. Voici un exemple d'extrait de code :

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()

Ce code définit un nuage de points avec 15 points aléatoires. Chaque point est associé à un nom du tableau des noms. La fonction annoter crée une étiquette qui reste initialement invisible.

La fonction de survol est définie pour gérer les événements de mouvement de la souris. Lorsque le curseur survole un point, il vérifie si le point est contenu dans le nuage de points. Si tel est le cas, il met à jour l'annotation avec le nom et la position de l'objet, la rend visible et redessine la figure. Lorsque le curseur quitte le point, l'annotation est masquée.

Pour les tracés linéaires au lieu des nuages ​​de points, la même solution peut être adaptée comme suit :

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()

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn