我是matplotlib,python和编程的新手。我一直在寻找这个问题的答案已有一段时间了,但一无所获。也许我不是在问合理的问题。
我有不同类型的绘图(绘图,散点图,plot_date,条形图等),每个轴有多个绘图,我在鼠标悬停时进行交互式注释。到目前为止,我一直在注释单个点(或条)。这就是代码的样子(在this answer上找到注释部分并对其进行了修改):
tabs = [{'SOUTH CAROLINA': 1662, 'IDAHO': 10343, 'VIRGINIA': 9689, 'KANSAS': 3634, 'NEBRASKA': 5024, 'TEXAS': 5134},
{'SOUTH CAROLINA': 8015, 'IDAHO': 57541, 'VIRGINIA': 54272, 'KANSAS': 20370, 'NEBRASKA': 29011, 'TEXAS': 29910},
{'SOUTH CAROLINA': 15000, 'IDAHO': 40000, 'VIRGINIA': 40000, 'KANSAS': 25000, 'NEBRASKA': 20000, 'TEXAS': 25000}]
vals = len(tabs)
xticks = np.arange(len(tabs[0]))
xlabels = list(tabs[0].keys())
fig, ax = plt.subplots(figsize=(8, 5))
plots = []
for i in range(len(tabs)):
plots.append(
ax.bar(
xticks - 0.7 / 2. + i / float(vals) * 0.7,
list(tabs[i].values()),
width=0.7/float(vals),
align='edge',
label=i
)
)
# annotation template
annot = ax.annotate(
"",
xy = (0,0),
xytext = (10, 20),
textcoords = "offset points",
arrowprops = dict(arrowstyle = 'wedge', fc = 'black')
)
annot.set_visible(False)
# update annotation with bar data
def update_annot(i, bar):
x = bar.get_x() + bar.get_width() / 2.
y = bar.get_y() + bar.get_height()
annot.xy = (x, y)
text = f'{list(tabs[0].keys())[i]}: {y}'
annot.set_text(text)
annot.set_bbox(
dict(
boxstyle='round',
lw=0,
alpha=0.8
)
)
# activate annotation on hover
def hover(event):
vis = annot.get_visible()
if event.inaxes:
for i, plot in enumerate(plots):
for bar in plot:
cont, _ = bar.contains(event)
if cont:
update_annot(i, bar)
annot.set_visible(True)
fig.canvas.draw_idle()
return
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
ax.set(title='title', xlabel='xlabel', ylabel='ylabel')
ax.set_xticks(xticks)
ax.set_xticklabels(xlabels, rotation=45)
ax.legend()
ax.grid(axis='y')
fig.tight_layout()
fig.canvas.mpl_connect("motion_notify_event", hover)
plt.show()
This is what I get when I run this script.
当我将鼠标悬停在其中一个栏上时,会看到一个带有x和y值的文本框。
但是现在我想用相同的x值注释所有点,这样,如果将鼠标悬停在其中的一个上,其余所有注释都将被注释。也就是说,在示例图像中,当我将鼠标悬停在代表任意状态的所有3列中时,都希望对其进行注释。
我尝试通过使用绘图对象列表上的zip()对每列进行分组,但是随后我无法一次显示多个注释。将列分组到列表中是不好的,因为它们不是matplotlib对象,并且不能在事件上被选择,并且遍历它们显然会一次选择一个。
任何帮助都感激不尽!