首页 >后端开发 >Python教程 >如何向 Matplotlib 散点图和线图添加悬停注释以在鼠标悬停时显示对象名称?

如何向 Matplotlib 散点图和线图添加悬停注释以在鼠标悬停时显示对象名称?

Susan Sarandon
Susan Sarandon原创
2024-12-09 11:26:11243浏览

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

向散点图添加悬停注释

使用 matplotlib 创建每个点代表一个特定对象的散点图时,它会很有帮助当光标悬停在相应点上时显示对象的名称。这允许用户快速识别异常值或其他相关信息,而不会用永久标签弄乱绘图。

一种解决方案涉及使用注释功能创建一个标签,当光标悬停在特定点上时该标签变得可见。以下是示例代码片段:

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

此代码定义了包含 15 个随机点的散点图。每个点都与名称数组中的一个名称相关联。 annotate 函数创建一个最初不可见的标签。

hover 函数被定义为处理鼠标移动事件。当光标悬停在某个点上时,它会检查该点是否包含在散点图中。如果是这样,它会使用对象的名称和位置更新注释,使其可见,并重新绘制图形。当光标离开该点时,注释被隐藏。

对于线图而不是散点图,可以采用相同的解决方案,如下所示:

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

以上是如何向 Matplotlib 散点图和线图添加悬停注释以在鼠标悬停时显示对象名称?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn