2013-05-13 41 views
10

this example的啓發我試圖編寫一個小matplotlib程序,允許用戶動態地在散點圖中拖放數據點。與使用條形圖(因此允許拖動矩形)的示例相反,我的目標是實現與其他修補程序相同的修改,例如圓形(與矩形相比散點圖更兼容的任何修補程序都會執行)。不過,我堅持要更新我的補丁的位置。雖然Rectangle提供了一個功能set_xy我找不到CirlceEllipse直接模擬。獲取圓的位置對於矩形也不那麼簡單,但可以通過獲取邊界框來獲得。現在缺失的部分是找到一種方法來更新我的補丁的位置。任何有關如何實現這一點的提示都會很棒!目前最小的工作示例是這樣的:matplotlib:更新修補程序的位置(或:set_xy for circles)

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.patches as patches 

class DraggablePatch: 

    def __init__(self, patch): 
    self.patch = patch 
    self.storedPosition = None 
    self.connect() 

    def getPosOfPatch(self, marker): 
    ext = marker.get_extents().get_points() 
    x0 = ext[0,0] 
    y0 = ext[0,1] 
    x1 = ext[1,0] 
    y1 = ext[1,1] 
    return 0.5*(x0+x1), 0.5*(y0+y1) 

    def connect(self): 
    'connect to all the events we need' 
    self.cidpress = self.patch.figure.canvas.mpl_connect('button_press_event', self.onPress) 
    self.cidmotion = self.patch.figure.canvas.mpl_connect('motion_notify_event', self.onMove) 

    def onPress(self, event): 
    'on button press we will see if the mouse is over us and store some data' 
    contains, attrd = self.patch.contains(event) 
    if contains: 
     self.storedPosition = self.getPosOfPatch(self.patch), event.xdata, event.ydata 

    def onMove(self, event): 
    'how to update an circle?!' 
    contains, attrd = self.patch.contains(event) 
    if contains and self.storedPosition is not None: 
     oldPos, oldEventXData, oldEventYData = self.storedPosition 
     dx = event.xdata - oldEventXData 
     dy = event.ydata - oldEventYData 
     newX = oldPos[0] + dx 
     newY = oldPos[1] + dy 
     print "now I would like to move my patch to", newX, newY 


def myPatch(x,y): 
    return patches.Circle((x,y), radius=.05, alpha=0.5) 

N = 10 
x = np.random.random(N) 
y = np.random.random(N) 
patches = [myPatch(x[i], y[i]) for i in range(N)] 

fig = plt.figure() 
ax = fig.add_subplot(111) 
drs = [] 
for patch in patches: 
    ax.add_patch(patch) 
    dr = DraggablePatch(patch) 
    drs.append(dr) 

plt.show() 

回答

11

這是一個有點討厭它的不一致,但更新圓的位置,設置circ.center = new_x, new_y

舉一個簡單的(非拖動)例:

import matplotlib.pyplot as plt 
from matplotlib.patches import Circle 

class InteractiveCircle(object): 
    def __init__(self): 
     self.fig, self.ax = plt.subplots() 
     self.ax.axis('equal') 

     self.circ = Circle((0.5, 0.5), 0.1) 
     self.ax.add_artist(self.circ) 
     self.ax.set_title('Click to move the circle') 

     self.fig.canvas.mpl_connect('button_press_event', self.on_click) 

    def on_click(self, event): 
     if event.inaxes is None: 
      return 
     self.circ.center = event.xdata, event.ydata 
     self.fig.canvas.draw() 

    def show(self): 
     plt.show() 


InteractiveCircle().show() 
+0

非常感謝你,是沒有的伎倆!由於我總是主張RTFM概念,我想知道我在哪裏可以找到這些信息?我無法在[patches.Circle]中看到它(http://matplotlib.org/api/artist_api.html?highlight=patches.circle#matplotlib.patches.Circle),[patches.Ellipse](http:// matplotlib.org/api/artist_api.html?highlight=patches.circle#matplotlib.patches.Ellipse),[patches.Patch](http://matplotlib.org/api/artist_api.html?highlight=patches.circle#matplotlib .patches.Patch)或[artist.Artist](http://matplotlib.org/api/artist_api.html?highlight=patches.circle#matplotlib.artist.Artist)。 – bluenote10 2013-05-14 07:21:22

+2

不幸的是,它沒有證件。我不得不通過代碼來找到它('ipython'也是一個很大的幫助)。 matplotlib的這些「角落」肯定需要更好的文檔... – 2013-05-14 12:09:38

+0

@JoeKington那麼我該如何做弧?我不想移動它的中心,而是想改變它的起點和終點,即弧的擴展。 – 2014-04-03 12:36:05

相關問題