簡體   English   中英

如何為 BrokenBarHCollection 對象使用 matplotlib 在子圖上創建 hover 注釋?

[英]How to create hover annotations on a subplot using matplotlib for BrokenBarHCollection objects?

我目前有一個包含三個子圖的圖形,它們都共享 y 軸但不共享 x 軸。 對於每個子圖,我使用創建 BrokenBarHCollection 的 for 循環生成數據點。 我使用的 for 循環如下(function "f" 只是為每個子圖創建 xranges 和 yrange):

for c in f(t):
    axis[1].add_collection(c)

現在,我希望用戶能夠在該子圖中的某些點上進行 hover 並顯示關於他們懸停的內容的注釋。 但是,我需要展示的 label 最初並未用於創建子圖,因此我創建了一個列表,其中包含我需要的所有標簽和另一個列表,其中包含我想要指定的 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 事件 function 但我不確定如何使用 BrokenBarHCollection object 來做到這一點。 有人有什么想法嗎?

子圖當前的樣子:

在此處輸入圖像描述

有點不清楚您如何創建 plot 以及它的外觀。 下面的方法為每個小條分配一個 label。 一個broken_barh只能有一個 label 用於整個集合,因此不是繪制ax.broken_barh() ,而是創建單獨的矩形,每個矩形都有自己的 label。 另一種可能性是也將單獨的 colors 分配給每個矩形(下面的示例假設最多 20 種顏色)。

在這種情況下, mplcursors默認生成帶有 cursor 的 label、x 和 y position 的注釋。 您可以更改默認注釋,例如僅使用 label。

請注意, mplcursors.cursor(..., hover=True)在懸停時顯示注釋。 默認只在點擊時顯示注解。

import matplotlib.pyplot as plt
import mplcursors
import numpy as np

gene_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, 'AUA1': 114958.0, 'WWM1': 115252.0, 'YPI1': 152424.0, 'MIC19': 166370.5, 'YFR012': 168579.0, 'RPL29': 222135.5, 'CDC26': 225896.0, 'YMR31': 247177.5}
color_dict = { key:color for key, color in zip(gene_dict.keys(), plt.cm.tab20.colors )}

fig, ax = plt.subplots()

for y in range(10, 51, 10):
    keys = np.random.choice(list(gene_dict.keys()), 5, replace=False)
    width = 3000
    for key in keys:
        ax.add_patch(plt.Rectangle((gene_dict[key] - width / 2, y), width, 9,
                                   color=color_dict[key], label=key))
ax.relim() # needed to update the xlim and ylim when using add_patch
ax.autoscale()

mplcursors.cursor(hover=True).connect("add", lambda sel: sel.annotation.set_text(sel.artist.get_label()))
plt.show()

broken_barh 的懸停注釋

關於mplcursors.cursor(...).connect("add", lambda sel: ...)的一些解釋。 lambda是一種快速編寫短 function(無名稱)的方法,因此它可以用作另一個 function 的參數。 代碼等價於:

def update_annotation(sel):
    """ update the annotation belonging to the current selected item (sel) """
    # get the label of the graphical element that is selected
    label = sel.artist.get_label()
    # change the text of the annotation
    sel.annotation.set_text(label)

# create an mplcursor object that shows an annotation while hovering
cursor = mplcursors.cursor(hover=True)
# call the function "update_annotation" each time a new element gets hovered over
cursor.connect("add", update_annotation)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM