2017-03-28 2 views
3

그림에 여러 개의 데이터 계열이 흩어져있어 주석을 토글 할 수 있기를 원합니다. 문제는 때로는 두 개의 선택 이벤트가 발생한다는 것입니다 (사용자가 주석과 점 안에있는 지점을 클릭 할 때). "annotation"pick 이벤트는 주석을 지우지 만, "dot"pick 이벤트는 바로 뒤를 놓습니다. 따라서 토글이 작동하지 않습니다.여러 픽업 이벤트가 간섭을 받음

df = pd.DataFrame({'a': np.random.rand(25)*1000, 
        'b': np.random.rand(25)*1000, 
        'c': np.random.rand(25)}) 

def handlepick(event): 
    artist = event.artist 
    if isinstance(artist, matplotlib.text.Annotation): 
     artist.set_visible(not artist.get_visible()) 
    else: 
     x = event.mouseevent.xdata 
     y = event.mouseevent.ydata 
     if artist.get_label() == 'a': 
      ann = matplotlib.text.Annotation('blue', xy=(x,y), picker=5) 
     else: # label == 'b' 
      ann = matplotlib.text.Annotation('red', xy=(x,y), picker=5) 
     plt.gca().add_artist(ann) 

plt.figure() 
plt.scatter(data=df, x='a', y='c', c='blue', s='a', alpha=0.5, picker=5, label='a') 
plt.scatter(data=df, x='b', y='c', c='red', s='b', alpha=0.5, picker=5, label='b') 
plt.gcf().canvas.mpl_connect('pick_event', handlepick) 
plt.show() 

어떻게이 주석 도트 픽업 이벤트를 분리 점은 이미 주석이있는 경우 주석을하지 말 것을 알 수 있습니까? 나는 이미 흩 뿌려진 시리즈를 선택하기 위해 라벨을 사용하고 있습니다.

대단히 감사합니다.

+0

질문과 관련이 없지만 if-else 조건의 테스트가'artist.get_label() == 'a''이 아니어야합니까? – TuanDT

+0

예, 지금 수정되었습니다. 감사. – datacathy

답변

2

이전의 모든 분산 점에 대해 특수 효과를 만들고 그 중 일부를 숨김으로 설정할 수 있습니다. scatterpoint를 클릭하면 해당 주석의 가시성이 토글됩니다. 주석을 클릭하면 아무 것도하지 않습니다.

import matplotlib.pyplot as plt 
import numpy as np 
import pandas as pd 

df = pd.DataFrame({'a': np.random.rand(25)*1000, 
        'b': np.random.rand(25)*1000, 
        'c': np.random.rand(25)}) 

def handlepick(event): 
    artist = event.artist 
    lab = artist.get_label() 
    if lab in d: 
     for ind in event.ind: 
      ann = d[lab][ind] 
      ann.set_visible(not ann.get_visible()) 
    plt.gcf().canvas.draw() 


plt.figure() 
plt.scatter(data=df, x='a', y='c', c='blue', s='a', alpha=0.5, picker=5, label='a') 
plt.scatter(data=df, x='b', y='c', c='red', s='b', alpha=0.5, picker=5, label='b') 

d = {"a" : [], "b": []} 
for i in range(len(df)): 
    ann = plt.annotate("blue", xy=(df["a"].iloc[i], df["c"].iloc[i]), visible=False) 
    d["a"].append(ann) 
    ann = plt.annotate("red", xy=(df["b"].iloc[i], df["c"].iloc[i]), visible=False) 
    d["b"].append(ann) 
plt.gcf().canvas.mpl_connect('pick_event', handlepick) 
plt.show()