Hi everyone !
This is my first object-oriented project, thus some parts could be wrote in a better way (advices would be appreciate..
)
I manage do build a code that allows points to be drag verticaly with mouse event.
https://ibb.co/CVvH0ww
https://ibb.co/P1MCJCp
I am able to retrieve the new coordinates, but only within the DraggablePoint Class.
Now I want the new coordinates from the drag point to be update in a list, in real time.
I mean, whenever the plot change with a mouse event, the list value should be update.
The main issue is that I don't know how to access and retrieve coordinates values outside of the event class
I tried to store the new coordinates in an attributes of the instance DraggablePoint, but didn't manage to get what I want..
Once again, I am quite new in this object-oriented world
Could someone give me advices ?
Thanks a lot !
The DraggablePoint class is the Following :
This is my first object-oriented project, thus some parts could be wrote in a better way (advices would be appreciate..

I manage do build a code that allows points to be drag verticaly with mouse event.
https://ibb.co/CVvH0ww
https://ibb.co/P1MCJCp
I am able to retrieve the new coordinates, but only within the DraggablePoint Class.
Now I want the new coordinates from the drag point to be update in a list, in real time.
I mean, whenever the plot change with a mouse event, the list value should be update.
The main issue is that I don't know how to access and retrieve coordinates values outside of the event class
I tried to store the new coordinates in an attributes of the instance DraggablePoint, but didn't manage to get what I want..
Once again, I am quite new in this object-oriented world
Could someone give me advices ?
Thanks a lot !
The DraggablePoint class is the Following :
# drag.py import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib.lines import Line2D import PySide2.QtCore as QtCore class DraggablePoint: lock = None # only one can be animated at a time def __init__(self, parent, x=0.1, y=0.1, size=0.1): global dragx, dragy self.parent = parent self.point = patches.Ellipse((x, y), size, size , fc='r', alpha=0.5, edgecolor='r') self.x = x self.y = y parent.fig.axes[0].add_patch(self.point) self.press = None self.background = None self.connect() # if another point already exist we draw a line if self.parent.list_points: line_x = [self.parent.list_points[-1].x, self.x] line_y = [self.parent.list_points[-1].y, self.y] self.line = Line2D(line_x, line_y, color='r', alpha=0.5) parent.fig.axes[0].add_line(self.line) self.coordinates = [] def connect(self): 'connect to all the events we need' self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.on_press) self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event', self.on_release) self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.on_motion) def on_press(self, event): if event.inaxes != self.point.axes: return if DraggablePoint.lock is not None: return contains, attrd = self.point.contains(event) if not contains: return self.press = (self.point.center), event.xdata, event.ydata DraggablePoint.lock = self # draw everything but the selected rectangle and store the pixel buffer canvas = self.point.figure.canvas axes = self.point.axes self.point.set_animated(True) # TODO also the line of some other points needs to be released point_number = self.parent.list_points.index(self) if self == self.parent.list_points[0]: self.parent.list_points[1].line.set_animated(True) elif self == self.parent.list_points[-1]: self.line.set_animated(True) else: self.line.set_animated(True) self.parent.list_points[point_number+1].line.set_animated(True) canvas.draw() self.background = canvas.copy_from_bbox(self.point.axes.bbox) # now redraw just the rectangle axes.draw_artist(self.point) # and blit just the redrawn area canvas.blit(axes.bbox) def on_motion(self, event): if DraggablePoint.lock is not self: return if event.inaxes != self.point.axes: return self.point.center, xpress, ypress = self.press dy = event.ydata - ypress self.point.center = (self.point.center[0], self.point.center[1]+dy) canvas = self.point.figure.canvas axes = self.point.axes # restore the background region canvas.restore_region(self.background) # redraw just the current rectangle axes.draw_artist(self.point) point_number = self.parent.list_points.index(self) self.x = self.point.center[0] self.y = self.point.center[1] # We check if the point is A or B if self == self.parent.list_points[0]: # or we draw the other line of the point self.parent.list_points[1].line.set_animated(True) axes.draw_artist(self.parent.list_points[1].line) elif self == self.parent.list_points[-1]: # we draw the line of the point axes.draw_artist(self.line) else: # we draw the line of the point axes.draw_artist(self.line) #self.parent.list_points[point_number+1].line.set_animated(True) axes.draw_artist(self.parent.list_points[point_number+1].line) if self == self.parent.list_points[0]: # The first point is especial because it has no line line_x = [self.x, self.parent.list_points[1].x] line_y = [self.y, self.parent.list_points[1].y] # this is were the line is updated self.parent.list_points[1].line.set_data(line_x, line_y) elif self == self.parent.list_points[-1]: line_x = [self.parent.list_points[-2].x, self.x] line_y = [self.parent.list_points[-2].y, self.y] self.line.set_data(line_x, line_y) else: # The first point is especial because it has no line line_x = [self.x, self.parent.list_points[point_number+1].x] line_y = [self.y, self.parent.list_points[point_number+1].y] # this is were the line is updated self.parent.list_points[point_number+1].line.set_data(line_x, line_y) line_x = [self.parent.list_points[point_number-1].x, self.x] line_y = [self.parent.list_points[point_number-1].y, self.y] self.line.set_data(line_x, line_y) # blit just the redrawn area canvas.blit(axes.bbox) def on_release(self, event): 'on release we reset the press data' if DraggablePoint.lock is not self: return self.press = None DraggablePoint.lock = None # turn off the rect animation property and reset the background self.point.set_animated(False) point_number = self.parent.list_points.index(self) if self == self.parent.list_points[0]: self.parent.list_points[1].line.set_animated(False) elif self == self.parent.list_points[-1]: self.line.set_animated(False) else: self.line.set_animated(False) self.parent.list_points[point_number+1].line.set_animated(False) self.background = None # redraw the full figure self.point.figure.canvas.draw() self.x = self.point.center[0] self.y = self.point.center[1] self.coordinates.append([self.x, self.y]) #print("Access from Class", self.x) #print("Access from Class", self.y) print("Access from Class", self.coordinates) def disconnect(self): 'disconnect all the stored connection ids' self.point.figure.canvas.mpl_disconnect(self.cidpress) self.point.figure.canvas.mpl_disconnect(self.cidrelease) self.point.figure.canvas.mpl_disconnect(self.cidmotion)The main piece of code :
#------------------------------------------------------------------------------- # Name: module5 # Purpose: # # Author: jguillerm # # Created: 05/01/2023 # Copyright: (c) jguillerm 2023 # Licence: <your licence> #------------------------------------------------------------------------------- import sys import matplotlib matplotlib.use("Qt5Agg") from PyQt5 import QtWidgets, QtGui from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure import PySide2.QtCore as QtCore # Personnal modules from drag import DraggablePoint class MyGraph(FigureCanvas): """A canvas that updates itself every second with a new plot.""" def __init__(self, parent=None, width=5, height=4, dpi=100): PK = [0, 10, 20, 30, 40, 50] FE = [251, 252, 248, 250, 251, 253] self.fig = Figure(figsize=(width, height), dpi=dpi) self.axes = self.fig.add_subplot() self.axes.grid(True) self.axes.set_xlim([0,50]) self.axes.set_ylim([240,260]) FigureCanvas.__init__(self, self.fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) # To store the 2 draggable points self.list_points = [] self.show() self.plotDraggablePoints(PK, FE) def plotDraggablePoints(self, listX, listY, size=1): """Plot and define the 2 draggable points of the baseline""" n = len(listX) for i in range(0,n): DragPoint = DraggablePoint(self, listX[i], listY[i], size) self.list_points.append(DragPoint) #print(" Access from script ", DragPoint.x) #print(" Access from script ", DragPoint.y) self.updateFigure() print(listY) def clearFigure(self): """Clear the graph""" self.axes.clear() self.axes.grid(True) del(self.list_points[:]) self.updateFigure() def updateFigure(self): """Update the graph. Necessary, to call after each plot""" self.draw() if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) ex = MyGraph() sys.exit(app.exec_()) print(PK)