Matt Pitkin - 1 year ago 70

Python Question

I want to customise a Matplotlib legend so that one of the labels is represented by two markers with different styles (e.g. ☆/▽ My label). I have seen that you can customise legend markers by making a patch for the marker, but can you create and use two patches (and at a push maybe add a "/" as a separator)? An option may also be to create a LaTeX string for the marker using TikZ, but that seems like overkill.

Answer Source

One way to do it would be to define custom markers using mathtext (see matplotlib documentation) and define the legend handle of the subclass with a proxy:

```
import numpy as np
import matplotlib.pyplot as plt
plt.close('all')
# Generate some data :
x1 = np.arange(1, 20)
y1 = np.log(x1) + np.random.uniform(-1, 1, size=len(x1))/5
x2 = np.arange(1, 20)
y2 = np.log(x2) + np.random.uniform(-1, 1, size=len(x2))/5
# Plot data :
fig, ax = plt.subplots()
h1, = ax.plot(x1[x1>5], y1[x1>5], ls='none', marker=r'$\star$',
ms=12, mec='0.15', mfc='0.15', mew=1, alpha=0.5)
h2, = ax.plot(x2[x2>5], y2[x2>5], ls='none', marker=r'$\blacktriangledown$',
ms=12, mec='0.15', mfc='0.15', mew=1, alpha=0.5)
ax.plot(x1[x1<=5], y1[x1<=5], ls='none', marker=r'$\star$',
ms=12, mec='red', mfc='red', mew=1, alpha=0.5)
ax.plot(x2[x2<=5], y2[x2<=5], ls='none', marker=r'$\blacktriangledown$',
ms=12, mec='red', mfc='red', mew=1, alpha=0.5)
# Create a proxy for the subclass :
h3, = ax.plot([], ls='none', marker=r'$\star/\blacktriangledown$',
ms=24, mec='red', mfc='red', mew=1, alpha=0.5)
# Generate legend :
handles = [h1, h2, h3]
labels = ['dataset1', 'dataset2', 'transient state']
ax.legend(handles, labels, loc=4, ncol=1, numpoints=1, frameon=False)
# Save and show the figure :
fig.savefig('custom_legend_markers.png')
plt.show()
```