【问题标题】:How to display an annotation and exploding a wedge when hovering over pie chart?悬停在饼图上时如何显示注释并爆炸楔形?
【发布时间】:2020-10-08 15:18:45
【问题描述】:

我想在饼图中添加一个事件,当悬停时,会显示一个带有值和标签的楔形的注释。经过一段时间的尝试,我得到了一个折线图的工作示例,但是对于饼图,我无法理解如何获取每个楔形的数据。到目前为止我的代码:

from matplotlib.figure import Figure

figure = Figure()
drawFigure = figure.subplots()
annotate = drawFigure.annotate("", xy=(0,0),xytext=(-20, 20), textcoords="offset points",
                                         bbox=dict(boxstyle="round", fc="black", ec="b", lw=2),
                                         arrowprops=dict(arrowstyle="->"))
annotate.set_visible(False)
days, amounts = zip(*my_dict.items())
wedges, _ = drawFigure.pie(amounts, labels=None)
drawFigure.axis('equal')
figure.canvas.mpl_connect("motion_notify_event", Hover)

def UpdateAnnotation(ind):
    data = ind.get_patch_transform() # I'm not sure this does anything useful
    # what now? can't seem to get anything working

def Hover(event):
    vis = annotate.get_visible()
    if event.inaxes == drawFigure:
        for i, w in enumerate(wedges):
            if w.contains_point([event.x, event.y]):
                print("hovering")
        figure.canvas.draw_idle()

理想情况下,我希望当我将鼠标悬停在楔形上时,会弹出一个注释,其中包含与该楔形相对应的 key : value 对。另外,把那个楔子炸开也不错。

【问题讨论】:

  • @JohanC 如果我要使用该方法,则意味着显示标签。我想要一个没有可见标签的饼图,但是当我将鼠标悬停在楔形上时,标签和值应该会出现。我可以在不使用 labels=None 的情况下以某种方式隐藏标签吗?

标签: python matplotlib


【解决方案1】:

您可以为每个楔形分配一个标签,该标签可以通过.get_label() 检索。可以使用textprops={'visible': False} 将标签文本设置为不可见。

要“爆炸”一个楔子,您可以移动它的中心,使用方向的平均角度。

为了使注释文本在黑色背景上可区分,可以选择浅色文本。

import numpy as np
import matplotlib.pyplot as plt

def hover_func(event):
    global selected_wedge
    if selected_wedge is not None:
        selected_wedge.set_center((0, 0))
        selected_wedge = None
    if event.inaxes == ax:
        for w in wedges:
            if w.contains_point([event.x, event.y]):
                annotation.set_text(f'{w.get_label()}: {months[w.get_label()]}')
                annotation.xy = (event.xdata, event.ydata)
                annotation.set_visible(True)
                theta = np.radians((w.theta1 + w.theta2) / 2)
                w.set_center((.2 * np.cos(theta), .2 * np.sin(theta)))
                selected_wedge = w
                fig.canvas.draw_idle()
    if selected_wedge is None and annotation.get_visible():
        annotation.set_visible(False)
        fig.canvas.draw_idle()

selected_wedge = None
fig, ax = plt.subplots()
annotation = ax.annotate("", xy=(0, 0), xytext=(-20, 20), textcoords="offset points",
                         color='yellow',
                         bbox=dict(boxstyle="round", fc="black", ec="b", lw=2),
                         arrowprops=dict(arrowstyle="->"))
annotation.set_visible(False)
months = {'January': 31, 'February': 29, 'March': 31, 'April': 30, 'May': 31, 'June': 30,
          'July': 31, 'August': 31, 'September': 30, 'October': 31, 'November': 30, 'December': 31}
wedges, _ = ax.pie(months.values(), labels=months.keys(), textprops={'visible': False},
                   colors=plt.get_cmap('plasma', len(months)).colors)
fig.canvas.mpl_connect("motion_notify_event", hover_func)

plt.show()

【讨论】:

  • 非常感谢!奇怪的是,即使我设置了elif vis: 部分,最后一个悬停的楔形始终保持爆炸状态,并且注释仍然可见。我尝试在其中添加打印,无论我做什么,我都没有得到打印声明。什么时候触发?
  • 以前的版本只在你在'ax'对象之外但在图形内部时才删除注释。更新后的版本现在还可以在您处于楔形之外时隐藏注释。
猜你喜欢
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 2022-09-29
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多