发生鼠标悬停事件时如何更改饼图的颜色

Posted

技术标签:

【中文标题】发生鼠标悬停事件时如何更改饼图的颜色【英文标题】:How to change color of pie slice when mouse hover event take place 【发布时间】:2017-09-01 12:47:46 【问题描述】:

我在matplotlib 中创建了一个饼图。我想在 python 中实现this 结果,即每当鼠标悬停在任何切片上时,它的颜色都会改变。我进行了很多搜索并想出了使用bind 方法,但这虽然无效,因此无法提出积极的意见结果。如果这可以通过任何其他库完成,我将没有问题(比如tkinterplotly 等,但我需要用matplotlib 提出解决方案,所以我会很感激)。请看看通过我的问题,任何建议都受到热烈欢迎...... 这是我的代码:

import matplotlib.pyplot as plt

labels = 'A', 'B', 'C', 'D'
sizes = [10, 35, 50, 5]
explode = (0, 0, 0.1, 0)  # only "explode" the 3rd slice (i.e. 'C')

fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
    shadow=True, startangle=90)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.show()

问候...

【问题讨论】:

figure_enter_event 呢? 您能提供一些样品吗? 文档中有一些例子:matplotlib.org/users/event_handling.html#mouse-enter-and-leave 我一定会看看的,先生!!!谢谢 【参考方案1】:

matplotlib event handler 需要 motion_notify_event。 这可以连接到一个函数,该函数检查鼠标是否在饼图的楔形之一内。这是通过contains_point 完成的。在这种情况下,对楔形进行不同的着色,否则将其颜色设置为其原始颜色。

import matplotlib.pyplot as plt

labels = 'A', 'B', 'C', 'D'
sizes = [10, 35, 50, 5]
explode = (0, 0, 0.1, 0)  # only "explode" the 3rd slice (i.e. 'C')

fig1, ax1 = plt.subplots()
wedges, _, __ = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
    shadow=True, startangle=90)
ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

ocols= [w.get_facecolor() for w in wedges]
ncols= ["gold", "indigo", "purple", "salmon"]

def update(event):
    if event.inaxes == ax1:
        for i, w in enumerate(wedges):
            if w.contains_point([event.x, event.y]):
                w.set_facecolor(ncols[i])
            else:
                w.set_facecolor(ocols[i])
        fig1.canvas.draw_idle()


fig1.canvas.mpl_connect("motion_notify_event", update)

plt.show()

【讨论】:

像往常一样,您的回答非常有用。我正在寻找一种方法来识别鼠标所在的楔子。我不知道contains_point(),很高兴学到了新东西。 @DizietAsahi 我恰好在前几天回复了a question about contains_point,所以我对此记忆犹新。 ;-) 但是,理想情况下,我希望使用contains(event),由于某种原因,它没有按预期工作(如果鼠标在轴内,它总是返回 True,而不仅仅是有问题的楔形)。 您是一位创造奇迹的先生!!!非常感谢您。我被困在里面超过 21 小时......先生,我只想知道一件事(虽然很愚蠢并为此道歉)先生,如果我们想在鼠标悬停时为不同的切片显示不同的颜色,我们需要创建多个事件还是可以有一些有效的选择? 我更新了答案,使每个楔形都有不同的“悬停颜色”。您只需要拥有与楔形一样多的颜色列表。【参考方案2】:

首先,您要查找的是the documentation on Event handling in matplotlib。特别是,每次鼠标移动时都会触发motion_notify_event。但是,我想不出一个简单的方法来识别鼠标现在在哪个楔子上。

如果点击是可以接受的,那么问题就简单多了:

labels = 'A', 'B', 'C', 'D'
sizes = [10, 35, 50, 5]
explode = (0, 0, 0.1, 0)  # only "explode" the 3rd slice (i.e. 'C')
click_color = [0.2, 0.2, 0.2]

fig1, ax1 = plt.subplots()
patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
    shadow=True, startangle=90)

# store original color inside patch object
# THIS IS VERY HACKY.
# We use the Artist's 'gid' which seems to be unused as far as I can tell
# to be able to recall the original color
for p in patches:
    p.set_gid(p.get_facecolor())
    # enable picking
    p.set_picker(True)

ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.


def on_pick(event):
    #restore all facescolor to erase previous changes
    for p in patches:
        p.set_facecolor(p.get_gid())
    a = event.artist
    # print('on pick:', a, a.get_gid())
    a.set_facecolor(click_color)
    plt.draw()

fig1.canvas.mpl_connect('pick_event', on_pick)
plt.show()

【讨论】:

非常感谢先生!!!但是我想出了这个解决方案。我希望当鼠标悬停发生时,更改不会发生在点击事件上!!!但是再次感谢您提供宝贵的时间

以上是关于发生鼠标悬停事件时如何更改饼图的颜色的主要内容,如果未能解决你的问题,请参考以下文章

Java Swing:在鼠标悬停时更改背景颜色

Java Swing:在鼠标悬停时更改背景颜色

如何在 Material ui 数据表中悬停或鼠标悬停时更改表格行背景颜色

悬停时如何更改导航栏链接上的文本颜色(和背景)? [复制]

将鼠标悬停在图像上时如何更改 SVG 的颜色?

使用对象时如何在鼠标悬停时更改 SVG 笔触颜色