By Evan Sangaline | August 24, 2017
How to Resize Matplotlib Legend Markers
I frequently find myself plotting clusters of points in Matplotlib with relatively small marker sizes. This is a useful way to visualize the data, but the plot’s legend will use the same marker sizes by default and it can be quite difficult to discern the color of a single point in isolation. Let’s plot a few random clusters of points to see what this problem looks like in practice.
import numpy as np
import matplotlib.pyplot as plt
# make the plot reproducible by setting the seed
np.random.seed(12)
# create the figure
fig = plt.figure(figsize=single_figsize)
ax = fig.add_subplot(1, 1, 1)
# plot five blobs of data points
for i in range(5):
# generate normally distributed points to plot
mean = [np.random.random()*10, np.random.random()*10]
covariance = [
[1 + np.random.random(), np.random.random() - 1],
[0, 1 + np.random.random()],
]
covariance[1][0] = covariance[0][1] # must be symmetric
x, y = np.random.multivariate_normal(mean, covariance, 3000).T
# plot them
plt.plot(x, y, 'o', ms=1.5, label=f'Cluster {i + 1}')
# draw the legend
ax.legend()
# show the figure
fig.tight_layout()
plt.show()
This code will display a plot which looks like this.
As you can see, the basic distributions are portrayed nicely, but the legend is quite difficult to read.
There are some questions on StackOverflow and I often find myself reading through these after searching for how to resize the legend markers. A number of the solutions don’t work with newer versions of Matplotlib, but it’s usually possible to find one that does work. Here’s the solution that I’ve usually ended up using in the past:
legend = ax.legend(frameon=True)
for legend_handle in legend.legendHandles:
legend_handle._legmarker.set_markersize(9)
This is obviously a bit of a hack, due to the use of the internal _legmarker
variable, and previous solutions have stopped working in the past because they used similar approaches (e.g. legend_handle._sizes = [30]
).
I was recently digging through some of the legend handling code while trying to figure out how to do something else when I discovered that Matplotlib actually has a built-in option for this!
The legend()
function takes a markerscale
parameter which allows you to scale up the marker sizes in the legend.
Our original marker sizes were 1.5 so to scale them up to 9 we would want to scale them by a factor of 6 (because 1.5*6=9).
This allows us to simply plot our legend with
ax.legend(markerscale=6)
to get nice big legend markers that are easy to read.
It’s a simple solution that is part of the public API, but I felt like sharing it because all of the StackOverflow answers out there focus on the more hackish approaches.
Those are still required if you want to scale up different markers in different ways, but the markerscale
parameter is easier to remember and accomplishes the same thing when you have a single marker size in your plot.
I was happy to discover it and I hope that this might be of use to some future Googlers out there.
By the way, if you’re in need of any data science consulting then please don’t hesitate to get in touch!.
Suggested Articles
If you enjoyed this article, then you might also enjoy these related ones.
Breaking Out of the Chrome/WebExtension Sandbox
A short guide to breaking out of the WebExtension content script sandbox.
Recreating Python's Slice Syntax in JavaScript Using ES6 Proxies
A gentle introduction to JavaScript proxies where we use them to recreate Python's extended slice syntax.
Building a YouTube MP3 Downloader with Exodus, FFmpeg, and AWS Lambda
A short guide to building a practical YouTube MP3 downloader bookmarklet using Amazon Lambda.
Comments