2017-09-01 61 views
1

我在matplotlib中創建了一個餅圖。我想實現this結果python 即每當鼠標懸停在任何切片的顏色發生變化。我搜索了很多,想出了使用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() 

問候......

+0

怎麼樣'figure_enter_event'? – SwiftsNamesake

+0

您能提供一些樣品嗎? – Mandy8055

+1

該文檔有一些例子:https://matplotlib.org/users/event_handling.html#mouse-enter-and-leave – SwiftsNamesake

回答

3

你會需要一個motion_notify_event一個matplotlib event handler。 這可以連接到一個函數,該函數檢查鼠標是否在餅圖的楔形內。這通過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() 
+0

像往常一樣,你的答案是非常翔實的。我正在尋找一種方法來識別鼠標所在的楔子。我不知道'contains_point()',很高興學到了新的東西。 –

+0

@DizietAsahi我恰好碰巧有一天在回答[有關'contains_point']的問題](https://stackoverflow.com/a/45986805/4124317),所以我在腦海裏想到了它。 ;-)但是,理想情況下,我希望使用['contains(event)'](https://matplotlib.org/devdocs/api/_as_gen/matplotlib.patches.Patch.html#matplotlib.patches.Patch.contains ),由於某種原因,不能按預期工作(如果鼠標位於座標軸內,則不會返回True,不僅僅是所討論的楔形)。 – ImportanceOfBeingErnest

+0

你是一位奇蹟工作者爵士!!!非常感謝。我被困在這裏超過21小時......主席先生,我只想知道一件事(儘管非常愚蠢併爲此道歉)如果我們想要在鼠標懸停時顯示不同切片的顏色,我們需要創建多個事件還是可以有一些有效的選擇呢? – Mandy8055

0

首先,你要找的是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() 
+0

非常感謝您爵士!!!但我想出了這個解決方案。我希望當鼠標懸停發生時,變化不會發生在點擊事件!!!!但是再次感謝您給寶貴的時間 – Mandy8055

相關問題