鼠标悬停时使用matplotlib注释绘图线[重复]

Posted

技术标签:

【中文标题】鼠标悬停时使用matplotlib注释绘图线[重复]【英文标题】:Annotate lines of a plot with matplotlib when hover with mouse [duplicate] 【发布时间】:2020-01-23 03:27:18 【问题描述】:

我想在鼠标悬停时在绘图上注释不同的线,这里用点Possible to make labels appear when hovering over a point in matplotlib?做同样的方法

我尝试将此代码修改为以下内容:

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
y = np.random.rand(4,15)
x = [np.arange(15) for i in range(len(y))]
names = np.array(list("ABCD"))
fig, ax = plt.subplots()
lines = []
for i in range(len(names)):
    lines.append(ax.plot(x[i],y[i]))

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 = line.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:
        for line in lines:
            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()

问题是当我将鼠标悬停在绘图上时出现以下错误:

AttributeError: 'list' object has no attribute 'contains'

我该如何解决这个问题?

【问题讨论】:

我标记为重复,因为该问题包含两种不同的方式为线条产生悬停。 【参考方案1】:

你不能盲目复制scatter()使用的代码并使用它用于plot(),因为返回的艺术家完全不同。

此外,您看到的错误的根本原因是plot() 返回了艺术家列表(即使在绘制单行时也是如此)。我已经修改了你的代码,以提供应该接近你想要的东西:

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(1)
y = np.random.rand(4, 15)
x = [np.arange(15) for i in range(len(y))]
names = np.array(list("ABCD"))
fig, ax = plt.subplots()
lines = []
for i in range(len(names)):
    l, = ax.plot(x[i], y[i], label=names[i])
    lines.append(l)

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(line, idx):
    posx, posy = [line.get_xdata()[idx], line.get_ydata()[idx]]
    annot.xy = (posx, posy)
    text = f'line.get_label(): posx:.2f-posy:.2f'
    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:
        for line in lines:
            cont, ind = line.contains(event)
            if cont:
                update_annot(line, ind['ind'][0])
                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注释绘图线[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在鼠标悬停时显示绘图值。 - 检测散点

在 pyqt5 中包含带有悬停标签的 matplotlib

Matplotlib 绘图细节设置

如何在Kivy的matplotlib图表上实现鼠标悬停数据标签弹出窗口

pyqt 中的多个嵌入式 matplotlib 画布在鼠标悬停时改变大小

Python+matplotlib数据可视化鼠标悬停自动标注功能实现