鼠标悬停时,使用matplotlib注释图的线条 [英] Annotate lines of a plot with matplotlib when hover with mouse

查看:74
本文介绍了鼠标悬停时,使用matplotlib注释图的线条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我用鼠标悬停时,我想在图上标注不同的线,这里用点

I want to annotate different lines on a plot when hovering with the mouse, the same way is done here with points Possible to make labels appear when hovering over a point in matplotlib?

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

I tried to adapt this code as the following :

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

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

The problem is when I hover the mouse on the plot I have the following error:

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

我该如何解决这个问题?

How can I solve this problem ?

推荐答案

您不能盲目地复制用于 scatter()的代码并将其用于 plot()返回的艺术家完全不同.

You cannot blindly copy the code used for scatter() and use it for plot()as the returned artists are completly different.

此外,您所看到的错误的根本原因是 plot()返回艺术家列表(即使绘制单行).我对您的代码进行了修改,使其所提供的内容应接近您想要的样子:

In addition, and the root cause for the error you are seeing is that plot() returns a list of artists (even when plotting a single line). I've modified you code to give something that should be close to what you wanted like so:

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注释图的线条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆