Beautifully annotated line plots in Python with Labellines

A reimagining of the Legend in a line plot

Michael Taverner
3 min readAug 17, 2022

--

Line plots are a great visual tool for displaying many things, not least of all timeseries data. They are also great for displaying changes in multivariate data over time — but what happens when you start to amass a large number of variables.

All visualisations and code snippets are taken from an analysis project I completed to illustrate the effect of the Iran-Iraq war on life expectancy of the Iraqi Male and Female population.

Very obviously, this needs a legend. The reader will have no idea what these three lines represent without having to read the code for the plot. Let’s make the colours a little more distinct as well.

This is much better, but good data visualisation strategy tells us that we shouldn’t force our readers eyes to jump around the screen to get a sense for the story we are trying to convey. The more work we ask of the viewer, the less impact the story of the data will have.

We can move the legend around to a different position in the plot, but we’d be walking a fine line between convenience and clutter.

Introducing: Labellines

One line of code (well, three I guess..) to annotate your lines with the labels you would normally see in a legend — and make them look rather excellent in the process.

pip install matplotlib-label-lines to install, and:

from labellines import labelLines will get you started.

That’s all there is to it! With three very short lines of code (that really could have been a single line) we have moved the labels directly onto the lines themselves, making the job of the reader much, much easier. You could almost ditch the legend altogether here.

What’s going on here?

A quick note on the arguments for LabelLines:

plt.gca().get_lines() returns a list of matplotlib 2d line objects as shown below, which as passed as the variable lines in this case, to the first argument of LabelLines.

[<matplotlib.lines.Line2D at 0x222b391a430>,
<matplotlib.lines.Line2D at 0x222b391a880>,
<matplotlib.lines.Line2D at 0x222b391acd0>]

align=True tells LabelLines to rotate the labels to match the slope of the line at the respective xvals.

xvals tells LabelLines where along the x-axis to place the labels. This should be a list of values with the same number of elements as the number of lines you are annotating. These can of course be different values for each line — letting you be very flexible with your label positioning.

--

--

Michael Taverner

I'm an Australian Fraud Prevention Data Analyst, live sound engineer and data science enthusiast.