Resizing Matplotlib Legend Markers

By Evan Sangaline | August 24, 2017
Follow @sangaline

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.

Plot with small legend markers

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.

Plot with big legend markers

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!.