I am trying to create a legend in a python figure where the artist is a string (a single letter) which is then labelled. For example I would like a legend for the following figure:
import numpy as np
import matplotlib.pyplot as plt
import string
N = 7
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2
plt.scatter(x, y, s=area, c=colors, alpha=0.5)
for i,j in enumerate(zip(x,y)):
plt.annotate(list(string.ascii_uppercase)[i],xy=j)
plt.show()
Where the legend is something like:
A - Model Name A
B - Model Name B
C - Model Name C
D - Model Name D
etc.etc.
What I can't work out how to do is place 'A', 'B', .... as the artist for the legend text. I can see how you would use a line or Patch, or something similar. But in general is there a way to use a string as the artist instead of, say, a line?
I don't think there's a legend handler for text (see the list of available ones here). But you can implement your own custom legend handler. Here I'll just modify the example at the above link:
The solution will depend on whether you already have texts in the axes that should appear in the legend as well, or whether those are independent on anything you have in the axes.
A. Existing texts or annotation
If you already have texts or annotations in the axes, you can provide them as handles to the legend. A new
TextHandlerA
that is registered to theLegend
class takes thoseText
s as input. The respective label is taken from the artist as usual, via thelabel
argument.B. Legend from list of strings.
If you want legend entries that are not themselves texts in the axes, you can create them from a list of strings. In this case the
TextHandlerB
takes the string as input. In that case the legend needs to be called with two lists of strings, one for the handles, and one for the labels.In both cases the output is