I am using Matplotlib to basically draw a \'picture\', not for plotting data.
In the \'picture\' I use plt.annotate
to label certain parts of the pictur
In most cases you probably also want to illustrate elements on the graphic with color in your custom legend. In this case I would simply use matplotlib's own functions, than you also do not need to write your own complex function.
import matplotlib
red_line = matplotlib.lines.Line2D([], [], color='red',markersize=100, label='Blue line')
blue_line = matplotlib.lines.Line2D([], [], color='blue', markersize=100, label='Green line')
purple_line = matplotlib.lines.Line2D([], [], color='purple', markersize=100, label='Green line')
handles = [blue_line,red_line, purple_line]
labels = [h.get_label() for h in handles]
ax.legend(handles=handles, labels=labels)
plt.show()
There are a lot of ways to do it, but it's probably easiest to use a proxy artist in this case. You can use arbitrary text as a marker, so it's fairly easy to have fake Line2D
's show labels instead of lines.
As an example (the bulk of this is the relatively "fancy" call to annotate
):
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def main():
labels = ['A', 'B', 'C']
positions = [(2, 5), (1, 1), (4, 8)]
descriptions = ['Happy Cow', 'Sad Horse', 'Drooling Dog']
# Plot the data, similar to what you described...
fig, ax = plt.subplots()
ax.imshow(np.random.random((10, 10)), interpolation='none')
for label, xy in zip(labels, positions):
ax.annotate(label, xy, xytext=(20, 20), size=15,
textcoords='offset points',
bbox={'facecolor':'white'},
arrowprops={'arrowstyle':'->'})
# Create a legend with only labels
proxies = [create_proxy(item) for item in labels]
ax.legend(proxies, descriptions, numpoints=1, markerscale=2)
plt.show()
def create_proxy(label):
line = matplotlib.lines.Line2D([0], [0], linestyle='none', mfc='black',
mec='none', marker=r'$\mathregular{{{}}}$'.format(label))
return line
main()