Ispirato da this example Sto provando a scrivere un piccolo programma matplotlib che consente all'utente di trascinare e rilasciare i punti dati in un diagramma a dispersione in modo dinamico. In contrasto con l'esempio che utilizza un grafico a barre (e quindi consente il trascinamento di rettangoli) il mio obiettivo era quello di ottenere lo stesso risultato con altre patch, come ad esempio un cerchio (qualsiasi patch più compatibile con lo scatter-plot di un rettangolo). Tuttavia sono bloccato al punto di aggiornare la posizione della mia patch. Mentre un Rectangle
fornisce una funzione set_xy
Non riesco a trovare un analogico diretto per Cirlce
o Ellipse
. Ottenere la posizione di un cerchio è anche meno diretto che per un rettangolo, ma è possibile ottenendo il rettangolo di selezione. Il pezzo mancante ora è trovare un modo per aggiornare la posizione della mia patch. Qualsiasi suggerimento su come ottenere questo sarebbe fantastico! L'attuale esempio di lavoro minima sarebbe simile a questa:matplotlib: aggiornamento posizione delle patch (o: set_xy per cerchi)
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()
La ringrazio molto, che ha fatto il trucco! Poiché sostengo sempre il concetto RTFM, mi chiedo dove posso trovare queste informazioni? Non riesco a vederlo in [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) o [artist.Artist] (http://matplotlib.org/api/artist_api.html?highlight=patches.circle#matplotlib.artist.Artist). – bluenote10
Sfortunatamente, non è documentato. Ho dovuto scavare attraverso il codice per trovarlo ('ipython' è anche un grande aiuto). Questi tipi di "angoli" di matplotlib necessitano sicuramente di una documentazione migliore ... –
@JoeKington Quindi, come faccio a fare questo per un arco? Non voglio spostare il suo centro piuttosto voglio cambiare il suo inizio e fine theta cioè la diffusione dell'arco. –