I have written this code which allows the user to select 4 points on the graph and as the 4 points are selected, two lines are drawn. But I want the user to be able to see which points she has selected by changing the color of the point or drawing a small circle around it. I tried reading the matplotlib documentation but couldn’t understand what to add/change in my code.
I just want to change the color of the selected points or draw a small circle around the selected points. How do I do that?
#ONCLICK Event which lets user select 4 points on the graph and stores the coordinates of the points in coords coords=[] def onclick(self,event): global ix, iy, fig ix, iy = event.xdata, event.ydata print ('x = %d, y = %d'%(ix, it)) #I am not able to plot this circle #plt.Circle((ix,iy), radius=0.07, color='g') event.canvas.draw() self.coords.append(ix) self.coords.append(iy) print(len(self.coords)) if len(self.coords) == 8: fig.canvas.mpl_disconnect(cid) plt.close(1) s=self.coords[0] t=self.coords[1] u=self.coords[2] v=self.coords[3] w=self.coords[4] x=self.coords[5] y=self.coords[6] z=self.coords[7] line1= '(' + str("{:.2f}".format(s))+',' + str("{:.2f}".format(t)) + ')' + ',' + '(' +str("{:.2f}".format(u)) +',' + str("{:.2f}".format(v)) + ')' line2= '(' + str("{:.2f}".format(w))+',' + str("{:.2f}".format(x)) + ')' + ',' + '(' +str("{:.2f}".format(y)) +',' + str("{:.2f}".format(z)) + ')' df['Parameter']=df['Parameter'].astype('float') df['Step']=df['Step'].astype('float') a = df['Step'] b = df['Parameter'] #LINE EQUATION m1=(v-t)/(u-s) c1=t-m1*s x1=np.linspace(df.iloc[0]["Step"],df.iloc[samples-1]["Step"],100) y1=m1*x1+c1 m2=(z-x)/(y-w) c2=x-m2*w x2=np.linspace(df.iloc[1]["Step"],df.iloc[samples-1]["Step"],100) y2=m2*x2 +c2 #INTERSECTION det=m2-m1 if det==0: print("Lines are paralleln") else: pointx=(c1-c2)/det pointy=((c1*m2)-(m1*c2))/det #PLOTTING fig = plt.figure() ax = plt.axes() plt.plot(a, b, '.',color='yellow') plt.plot(x1,y1,color='red',label=line1) plt.plot(x2,y2,color='black',label=line2) plt.xlabel('Volume') plt.ylabel('Conductivity') ax.set_ylim(bottom=0) ax.set_xlim(left=0.) idx = np.argwhere(np.diff(np.sign(y2 - y1))).flatten() plt.title("END POINT") plt.plot(x2[idx], y2[idx], 'ro',color='Purple') plt.annotate("Intersecting Point", (pointx,pointy),color='Blue') plt.plot((pointx,pointx),(pointy,0),'--',color='purple') plt.annotate("(%s,0) Volume" %pointx, (pointx,0),color='Blue') mplcursors.cursor(hover=True) plt.legend() plt.show() return #Main graph which appears when a button in the interface is clicked. def manual(self): df['Parameter']=df['Parameter'].astype('float') df['Step']=df['Step'].astype('float') a = df['Step'] b = df['Parameter'] df['Parameter']=df['Parameter'].astype('float') df['Step']=df['Step'].astype('float') a=df['Step'] b=df['Parameter'] global fig fig=plt.figure() plt.xlabel('Volume') plt.ylabel('Conductivity') plt.title('SCATTER PLOT') plt.scatter(a, b,color='r', label=self.Name) mplcursors.cursor(hover=True) global cid cid = fig.canvas.mpl_connect('button_press_event', self.onclick) plt.legend() plt.show()
Advertisement
Answer
The answer to your question is illustrated in your example itself. All you have to do is to grab the axes currently in context and plot your point emitted from the event on it. Here is a simple example that is not very dissimilar from your own.
from matplotlib import pyplot as plt i = 0 def onclick(event): global i ix, iy = event.xdata, event.ydata ax = plt.gca() ax.plot(ix, iy, 'b*') ax.annotate(f"Clicked Point {i}", (ix,iy),color='Black') i += 1 print(f'x = {ix}, y = {iy}') event.canvas.draw() fig, ax = plt.subplots() ax.set_xlim([0,10]) ax.set_ylim([0,10]) fig.canvas.callbacks.connect('button_press_event', onclick) plt.show()