0
votes

I receive the error No handles with labels found to put in legend. when running the code below. How can I add a legend to this scatter plot that shows the color definitions (a red dot for A, blue dot for B, green dot for C)?

### Dummy Dataset
x = [0,1,-1,4,0,2,2,4,2]
y = [1,5,9,2,4,2,5,6,1]
cat = ['A','B','B','B','A','C','A','B','B']
df = pd.DataFrame(list(zip(x,y,cat)), columns =['x', 'y', 'cat'])

### Build color definitions
df.loc[:, 'color'] = df.cat
df.color.replace(['A', 'B', 'C'], ['red', 'blue', 'green'], inplace=True)
display(df)

### Plotting
fig = plt.figure(figsize=(5,5), constrained_layout=True)
gs = fig.add_gridspec(2, 1)
ax1 = fig.add_subplot(gs[0, 0])
ax1.scatter(df.x, df.y, edgecolors = 'none', c = df.color)
ax1.legend(loc='upper left', facecolor='white', frameon=1, 
           framealpha=1, labelspacing=0.2, borderpad=0.25)

enter image description here

1
you did specify the labels for the scatter plot, as the warning says - Paul H
@PaulH yes the question is how to do that? - a11
simplest version is add the label kwarg to your call to scatter. If not all, nearly all matplotlib plotting functions take label as a parameter according to their docstrings, which you can see in jupyter by executing e.g., ax1.scatter?. For more advanced legends, the second scatter example in the matplotlib documentation is pretty exhaustive matplotlib.org/gallery/lines_bars_and_markers/… - Paul H
Should have said this in the OP, but I also tried myplot = ax1.scatter(df... and ax1.legend(*myplot.legend_elements(), loc='upper...), which returned the error UserWarning: Collection without array used. Make sure to specify the values to be colormapped via the c` argument.` - a11

1 Answers

0
votes

It seems like there might not be a way to do this without a simple loop. Based on the procedure here, the following code works.

x = [0,1,-1,4,0,2,2,4,2]
y = [1,5,9,2,4,2,5,6,1]
cat = ['A','B','B','B','A','C','A','B','B']
df = pd.DataFrame(list(zip(x,y,cat)), columns =['x', 'y', 'cat'])

mycolorsdict = {'A':'red', 'B':'blue', 'C':'green'}

fig = plt.figure(figsize=(5,5), constrained_layout=True)
gs = fig.add_gridspec(2, 1)
ax1 = fig.add_subplot(gs[0, 0])
grouped = df.groupby('cat')
for key, group in grouped:
    group.plot(ax=ax1, kind='scatter', 
               x='x', y='y', 
               label=key, color=mycolorsdict[key])
ax1.legend(loc='upper left', facecolor='white', frameon=1, 
           framealpha=1, labelspacing=0.2, borderpad=0.25)

enter image description here