发生鼠标悬停事件时如何更改饼图的颜色
Posted
技术标签:
【中文标题】发生鼠标悬停事件时如何更改饼图的颜色【英文标题】:How to change color of pie slice when mouse hover event take place 【发布时间】:2017-09-01 12:47:46 【问题描述】:我在matplotlib
中创建了一个饼图。我想在 python 中实现this 结果,即每当鼠标悬停在任何切片上时,它的颜色都会改变。我进行了很多搜索并想出了使用bind
方法,但这虽然无效,因此无法提出积极的意见结果。如果这可以通过任何其他库完成,我将没有问题(比如tkinter
、plotly
等,但我需要用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()
【讨论】:
非常感谢先生!!!但是我想出了这个解决方案。我希望当鼠标悬停发生时,更改不会发生在点击事件上!!!但是再次感谢您提供宝贵的时间以上是关于发生鼠标悬停事件时如何更改饼图的颜色的主要内容,如果未能解决你的问题,请参考以下文章