Home > Software design >  Picker Event to display legend labels in matplotlib
Picker Event to display legend labels in matplotlib

Time:08-13

I'm still very new to this so please bare with me if I'm not making myself clear enough:

I want the picker event to simply display the legend label when I click on any of the points on my scatter plot. This is what I have and looks like:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# x y data and legend labels
x = np.random.uniform(0, 100, 50)
y = np.random.uniform(0, 100, 50)
ID = np.random.randint(0,25,50)

# define the event
def onpick(event):
    ind = event.ind
    print('x:', x[ind], 'y:', y[ind])

# create the plot
fig, ax = plt.subplots()
scatter = ax.scatter(x, y, c = ID, picker=True)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend(*scatter.legend_elements(num=list(np.unique(ID))),
          loc="center left", 
          title='ID', 
          bbox_to_anchor=(1, 0.5),
          ncol=2
         )    
ax.ticklabel_format(useOffset=False)
ax.tick_params(axis = 'x',labelrotation = 45)
plt.tight_layout()


# call the event
fig.canvas.mpl_connect('pick_event', onpick)

The scatter plot: The current output when click on a point:

I want it to print something like:

x: [76.25650514] y: [59.85198124] ID: 11 (the corresponding legend label)

I have been searching through the web and couldn't find much I can duplicate from. Any input is appreciated!

CodePudding user response:

Generally, the way you would get the label of the point you clicked on would be print(event.artist.get_label()) but with your custom legends labels, the only thing that prints is _child0. However, due to your custom labels, you can use your variable ID just like how you are using your x and y variables e.g. print('id:', ID[ind]).

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# x y data and legend labels
x = np.random.uniform(0, 100, 50)
y = np.random.uniform(0, 100, 50)
ID = np.random.randint(0,25,50)

# define the event
def onpick(event):
    ind = event.ind
    print(event.artist.get_label()) # How you normally get the legend label
    print('id:', ID[ind])           # How you can get your custom legend label
    print('x:', x[ind], 'y:', y[ind])

# create the plot
fig, ax = plt.subplots()
scatter = ax.scatter(x, y, c = ID, picker=True)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend(*scatter.legend_elements(num=list(np.unique(ID))),
          loc="center left", 
          title='ID', 
          bbox_to_anchor=(1, 0.5),
          ncol=2
         )    
ax.ticklabel_format(useOffset=False)
ax.tick_params(axis = 'x',labelrotation = 45)
plt.tight_layout()


# call the event
fig.canvas.mpl_connect('pick_event', onpick)
plt.show()

Clicking on the yellow most point gives:

_child0
id: [24]
x: [84.73899472] y: [3.07532246]

Clicking on a very purple point gives:

_child0
id: [2]
x: [99.88397652] y: [98.89144833]
  • Related