matplotlibcolorspoint

Matplotlib change color of a specific point


I can't change the color of the single that is clicked. The idea is to change the color of a point in red after a click on, and turn back the other in blue if he was selected before and in red, to keep only a point "active", so in red. But what happens now in the program is that only when I click on the 9th point placed (at the top right), all points change their color to become red. And when I click on the others, nothing happend

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

fig, ax = plt.subplots()

liste_points = [(1, 1, "a"), (2, 1, "b"), (3, 1, "c"), (1, 2, "d"), (2, 2, "e"), (3, 2, "f"), (1, 3, "g"), (2, 3, "h"), (3, 3, "i")]
x, y, labels = zip(*liste_points)
sc = ax.scatter(x, y, s=10, c="blue", picker=5)

def onpick(event):
    point_choisi = event.artist
    index = event.ind[0]
    for i, point in enumerate(sc.get_offsets()):
        if i == index:
            point_choisi.set_color('red')
        else:
            point_choisi.set_color('blue')
    fig.canvas.draw_idle()

fig.canvas.mpl_connect('pick_event', onpick)

plt.show()

The other idea would be to print the tag associated to the point clicked, which turns in red (so the letter)


Solution

  • One simple option is to make an array of the scatter's color (c can be array-like), then set_facecolor of the clicked point to red (based on the PickEvent.ind) right after you reset all the colors to blue (if any red) :

    on, off = "r", "b"
    
    fig, ax = plt.subplots()
    
    sc = ax.scatter(x, y, s=50, c=off, picker=5)
    
    def on_pick(event):
        _new_colors = np.full(len(liste_points), off) # make sure all blue
        _new_colors[event.ind] = on                   # then set a red one
        sc.set_facecolor(_new_colors)
        fig.canvas.draw()
    
    fig.canvas.mpl_connect("pick_event", on_pick)
    
    plt.show()
    

    enter image description here