将鼠标悬停在多轴上的一个点上时如何使标签出现? [英] How to make labels appear when hovering over a point in multiple axis?

查看:37
本文介绍了将鼠标悬停在多轴上的一个点上时如何使标签出现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在具有多轴的matplotlib上显示悬停标签.

I'm trying to show hover label on matplotlib with multiple axis.

我将python 3.6.8与matplotlib 3.0.3结合使用

I'm using python 3.6.8 with matplotlib 3.0.3

我的情节有多个轴,我看了这篇文章中的例子:

My plot have multiple axis, and I looked on the example from this post:

可以显示标签将鼠标悬停在matplotlib中的某个点上时?

但是什么也没发生(不能看到标签).

But nothing happen (cant see the labels).

这是我的代码:

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))
y2 = np.sort(np.random.rand(15))

fig = plt.figure()
ax1 = plt.subplot(2, 2, 1)
line, = plt.plot(x,y)
ax1.grid(True)

ax2 = ax1.twinx()
ax2.plot(x, y2, color='green')
ax2.tick_params(axis='y', labelcolor='green')

annot = ax1.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 = "x = {}\ny= {}".format(x[ind["ind"][0]], y[ind["ind"][0]])
    annot.set_text(text)
    annot.get_bbox_patch().set_alpha(0.4)


def hover(event):
    vis = annot.get_visible()
    if event.inaxes == ax1:
        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()

当我禁用(评论)第二个轴(ax2)时,我可以看到标签.

when I disable (comments) the second axis (ax2) I can see the labels.

如何在使用多轴时显示悬停标签?

How can I display the hover labels when using multiple axis ?

推荐答案

问题确实是只为双轴之一触发事件.因此,如果要标记两个轴的内容,则需要多路复用标记,即创建两个注释,每个轴一个,并调整代码以使两个注释都可能可见.

The problem is indeed that events are triggered only for one of the twin axes. So if you want to label content of both axes, your need to multiplex the labeling, i.e. create two annotations, one for each axes, and adjust the code such that both annotations are potentially visible.

如下所示:

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))
y2 = np.sort(np.random.rand(15))

fig = plt.figure()
ax1 = plt.subplot(2, 2, 1)
line1, = plt.plot(x,y)
ax1.grid(True)

ax2 = ax1.twinx()
line2, = ax2.plot(x, y2, color='green')
ax2.tick_params(axis='y', labelcolor='green')

annots = []
for ax in [ax1, ax2]:
    annot = ax1.annotate("", xy=(0,0), xytext=(-20,20),textcoords="offset points",
                        bbox=dict(boxstyle="round", fc="w", alpha=0.4),
                        arrowprops=dict(arrowstyle="->"))
    annot.set_visible(False)
    annots.append(annot)

annot_dic = dict(zip([ax1, ax2], annots))
line_dic = dict(zip([ax1, ax2], [line1, line2]))

def update_annot(line, annot, ind):
    x,y = line.get_data()
    annot.xy = (x[ind["ind"][0]], y[ind["ind"][0]])
    text = "x = {}\ny= {}".format(x[ind["ind"][0]], y[ind["ind"][0]])
    annot.set_text(text)

def hover(event):

    if event.inaxes in [ax1, ax2]:
        for ax in [ax1, ax2]:
            cont, ind = line_dic[ax].contains(event)
            annot = annot_dic[ax]
            if cont:
                update_annot(line_dic[ax], annot, ind)
                annot.set_visible(True)
                fig.canvas.draw_idle()
            else:
                if annot.get_visible():
                    annot.set_visible(False)
                    fig.canvas.draw_idle()

fig.canvas.mpl_connect("motion_notify_event", hover)

plt.show()

这篇关于将鼠标悬停在多轴上的一个点上时如何使标签出现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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