Python 如何使用matplotlib为BrokenBarHCollection对象在子地块上创建悬停批注?

Python 如何使用matplotlib为BrokenBarHCollection对象在子地块上创建悬停批注?,python,matplotlib,annotations,hover,Python,Matplotlib,Annotations,Hover,我现在有一个图形,有三个子图,它们都共享y轴,但不共享x轴。对于每个子批次,我使用创建BrokenBarHCollection的For循环生成数据点。我使用的for循环如下(函数“f”只为每个子批次创建xranges和yrange): 现在,我希望用户能够将鼠标悬停在子图中的某些点上,并显示一个关于鼠标悬停的内容的注释。但是,我需要显示的标签最初不是用于创建子地块的,因此我创建了一个包含我需要的所有标签的列表,以及另一个包含我要指定的x轴上的所有点的列表。因为它们是矩形(使用BrokenBarH

我现在有一个图形,有三个子图,它们都共享y轴,但不共享x轴。对于每个子批次,我使用创建BrokenBarHCollection的For循环生成数据点。我使用的for循环如下(函数“f”只为每个子批次创建xranges和yrange):

现在,我希望用户能够将鼠标悬停在子图中的某些点上,并显示一个关于鼠标悬停的内容的注释。但是,我需要显示的标签最初不是用于创建子地块的,因此我创建了一个包含我需要的所有标签的列表,以及另一个包含我要指定的x轴上的所有点的列表。因为它们是矩形(使用BrokenBarHCollection),所以第二个列表中的点位于矩形的中间)。y范围仅为0。我后来创建了一个字典,标签是键,点是值,并使用以下代码了解了如何在子图中生成注释:

for keys, values in gene_dict.items():
    y = 0
    annot = axs[1].annotate(keys, xy = (values, y), fontsize = 4) 
以下是生成的词典:

{'YFL067': 2074.5, 'YFL041': 49352.5, 'YPT1': 56193.5, 'PAU5': 99435.0, 'YFL019': 100497.0, 'SMX2': 103801.5, 'YFL015': 106649.5, 'HSP12': 107304.5, 'YFL012': 110789.5, 'AUA1': 114958.0, 'WWM1': 115252.0, 'YPI1': 152424.0, 'MIC19': 166370.5, 'YFR012': 168579.0, 'RPL29': 222135.5, 'CDC26': 225896.0, 'YMR31': 247177.5}
所以,我的问题是如何使用我生成的标签和沿x轴的点来创建悬停注释?我在这里看到过使用mplcursors的帖子,但当我这样做时,什么也没有发生:

mplcursors.cursor(axs[1]).connect("add", lambda sel: sel.annot.set_text(keys[sel.target.index]))
我想我必须创建一个onHover事件函数,但我不知道如何使用BrokenBarHCollection对象来创建它。有人有什么想法吗

子地块当前的外观:


现在还不清楚你是如何创建你的绘图的,以及它是什么样子的。下面的方法为每个小条指定一个标签。一个
breaked\u barh
在整个集合中只能有一个标签,因此不绘制
ax.breaked\u barh()
,而是创建单独的矩形,每个矩形都有自己的标签。另外一种可能性是为每个矩形指定单独的颜色(下面的示例假设最多20种颜色)

在这种情况下,
mplcursors
default会生成一个带有标签、光标x和y位置的注释。可以更改默认注释,例如仅使用标签

请注意,
mplcursors.cursor(…,hover=True)
在悬停时显示注释。默认设置仅在单击时显示注释

导入matplotlib.pyplot作为plt
导入MPLS游标
将numpy作为np导入
基因dict={'YFL067':2074.5,'YFL041':49352.5,'YPT1':56193.5,'PAU5':99435.0,'YFL019':100497.0,'SMX2':103801.5,'YFL015':106649.5,'HSP12':107304.5,'YFL012':110789.5,'CDCAUA1':114958.0,'WWM1':115252.0,'YP1':152424.0,'MIC19':166370.5,'YFR012':1078579.0,'RP1629,'2135.2475,'YMR359.5''
color_dict={key:color for key,color in zip(gene_dict.keys(),plt.cm.tab20.colors)}
图,ax=plt.子批次()
对于范围(10,51,10)内的y:
keys=np.random.choice(list(gene_dict.keys()),5,replace=False)
宽度=3000
对于键入键:
ax.添加补片(plt.长方形((基因dict[key]-宽度/2,y)),宽度9,
颜色=颜色(数字[键],标签=键)
ax.relim()#在使用add_修补程序时需要更新xlim和ylim
ax.自动缩放()
mplcursors.cursor(hover=True).connect(“添加”,lambda sel:sel.annotation.set_text(sel.artist.get_label()))
plt.show()

关于
mplcursors.cursor(…).connect(“添加”,lambda sel:…)
的一些解释。是一种快速编写短函数(无名称)的方法,因此可以将其用作另一个函数的参数。 该代码相当于:

def更新注释(sel):
“”“更新属于当前选定项(sel)的批注”
#获取所选图形元素的标签
label=sel.artist.get_label()
#更改注释的文本
选择注释设置文本(标签)
#创建一个鼠标悬停时显示注释的mplcursor对象
cursor=mplcursors.cursor(hover=True)
#每次悬停新元素时调用函数“update_annotation”
cursor.connect(“添加”,更新注释)

@JohanC哇这已经帮了大忙了,谢谢。您知道如何自定义悬停时显示的工具提示吗?例如,当鼠标悬停时,它显示x和y坐标,但当鼠标悬停在x轴上的某个点上时,我希望它显示一个字符串(我在标签列表中有这个字符串)。虽然这并不完全是我想要做的,但它非常有帮助。我在我的问题中添加了一个图像,其中有三个子图(axs[0]是灰色条,axs[1]是红色和蓝色条,axs[2]是黑色条)。我希望用户能够将鼠标悬停在axs[2]中的黑条上,并在字典中显示标签。我还将标签存储在BrokenBarHCollection对象中,因此我不确定这是否会使它更易于使用。请您再解释一下这一行好吗?我经常看到它,并认为它是解决这个问题的关键``mplcursors.cursor(hover=True).connect(“添加”,lambda sel:sel.annotation.set_text(sel.artist.get_label())```你能编辑你的帖子并添加一个更完整的例子说明你在做什么吗?没有它,猜测是很难的,尤其是当我的第一个猜测似乎是错误的。想一想创建一个。实际上,我最终得到了它,因为你是如何解释断条的,或者创建矩形补丁的。我现在面临的唯一问题是,每个基因的标签有时会被其他轴阻挡(取决于你点击的位置)。您熟悉自定义注释框吗?您想更改什么?每个子批次是否有一个光标?如果只有一个光标,您可能可以更改相应的
ax
axs[…]的顺序。设置顺序(10)
mplcursors.cursor(axs[1]).connect("add", lambda sel: sel.annot.set_text(keys[sel.target.index]))