Skip to content
Advertisement

How do I change color of the selected points in matplotlib?

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()
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement