I was trying to create a figure of a legend (without a plot) and it took me way to long to figure it out. What I wanted was something like this:


I initially though this would be really easy using the approach in this stack overflow post

import matplotlib.pyplot as plt

labels = ['Label 1', 'Label 2', 'Label 3', 'Label 4']
colors = []

fig = plt.figure()
fig_legend = plt.figure(figsize=(2, 1.25))
ax = fig.add_subplot(111)
lines = ax.plot(range(2), range(2), range(2), range(2), range(2), range(2), range(2), range(2))
fig_legend.legend(lines, labels, loc='center', frameon=False)


This worked well enough for making lines, but what I really wanted were the boxes/patches, like you would get with a bar chart or histogram.  I tried switching to plotting bars:

fig = plt.figure()
fig_legend = plt.figure(figsize=(2, 1.25))
ax = fig.add_subplot(111)
bars =, range(4), color=colors, label=labels)
fig_legend.legend(bars.get_children(), labels, loc='center', frameon=False)

but this resulted in the following “RuntimeError: Can not put single artist in more than one figure“.

I tried as many different combinations of “ax.get_legend_handles_labels()”, “bars.get_children()”, plotting each bar separately, and plotting histograms, but kept getting the same error.

Finally, after far too long, I realized I didn’t need to play anything to get a patch object and could create them manually.  The following code was used to generate the figure at the top.

fig = plt.figure(figsize=(2, 1.25))
patches = [
    mpatches.Patch(color=color, label=label)
    for label, color in zip(labels, colors)]
fig.legend(patches, labels, loc='center', frameon=False)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s