python - 如何在绘图中添加悬停注释

标签 python pandas matplotlib seaborn mplcursors

我正在使用 matplotlib 制作散点图。散点图上的每个点都与一个命名对象相关联。当我将光标悬停在与该对象关联的散点图上的点上时,我希望能够看到该对象的名称。特别是,如果能够快速查看异常点的名称,那就太好了。我在这里搜索时能找到的最接近的东西是注释命令,但这似乎会在图上创建一个固定标签。不幸的是,由于我拥有的点数,如果我标记每个点,散点图将无法阅读。有谁知道创建仅在光标悬停在该点附近时出现的标签的方法?

最佳答案

这里的其他答案似乎都没有真正回答这个问题。因此,这是一个使用 scatter 并在 悬停 散点上显示 注释 的代码。

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

enter image description here

因为人们也想将此解决方案用于 plot 行而不是散点图,所以以下将是 plot 的相同解决方案(工作方式略有不同)。

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

如果有人正在寻找双轴线的解决方案,请参阅 How to make labels appear when hovering over a point in multiple axis?

如果有人正在寻找条形图的解决方案,请引用例如this answer .

关于python - 如何在绘图中添加悬停注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7908636/

相关文章:

python - 在 Python 中对无限循环使用无限递归是一种罪过吗?

python - 删除 Pandas DataFrame.to_string 插入的列之间的自动两个空格

python - `pd.concat` 与 `join==' 内部 '` 不会产生 Pandas 数据帧的交集

python - 将 Pandas 更新为 postgres

python - 如何从 basemap 中删除美国大陆以外(墨西哥和加拿大境内)的轮廓颜色?

python - 如何在 pyplot 中仅使用对数 xscale 绘制累积直方图

python/matplotlib 在 savefig() 上随机挂起

python - 从 S3 Bucket 编辑 base.css 文件

Python Pandas Groupby isin

python - 如何在 Anaconda Python(Windows 平台)中安装 xgboost?