Easily hiding items from the legend in matplotlib
When producing some graphs for a client recently, I wanted to hide some labels from a legend in matplotlib. I started investigating complex arguments to the plt.legend
function, but it turned out that there was a really simple way to do it…
If you start your label for a plot item with an underscore (_
) then that item will be hidden from the legend.
For example:
plt.plot(np.random.rand(20), label='Random 1')
plt.plot(np.random.rand(20), label='Random 2')
plt.plot(np.random.rand(20), label='_Hidden label')
plt.legend()
produces a plot like this:
You can see that the third line is hidden from the legend – just because we started its label with an underscore.
I found this particularly useful when I wanted to plot a load of lines in the same colour to show all the data for something, and then highlight a few lines that meant specific things. For example:
for i in range(20):
plt.plot(np.random.rand(20), label='_Hidden', color='gray', alpha=0.3)
plt.plot(np.random.rand(20), label='Important Line 1')
plt.plot(np.random.rand(20), label='Important Line 2')
plt.legend()
My next step was to do this when plotting from pandas. In this case I had a dataframe that had a column for each line I wanted to plot in the ‘background’, and then a separate dataframe with each of the ‘special’ lines to highlight.
This code will create a couple of example dataframes:
df = pd.DataFrame()
for i in range(20):
df[f'Data{i}'] = np.random.rand(20)
special = pd.Series(data=np.random.rand(20))
Plotting this produces a legend with all the individual lines showing:
df.plot(color='gray', alpha=0.3)
However, just by changing the column names to start with an underscore you can hide all the entries in the legend. In this example, I actually set one of the columns to a name without an underscore, so that column can be used as a label to represent all of these lines:
cols = ["_" + col for col in df.columns]
cols[0] = 'All other data'
df.columns = cols
Plotting again using exactly the same command as above gives us this – along with some warnings saying that a load of legend items are going to be ignored (in case we accidentally had pandas columns starting with _
)
Putting it all together, we can plot both dataframes, with a sensible legend:
ax = df.plot(color='gray', alpha=0.3)
special.plot(ax=ax, label='Special data')
plt.legend()
Advert: I do freelance data science work – please see here for more details.
If you found this post useful, please consider buying me a coffee.
This post originally appeared on Robin's Blog.
Categorised as: Programming, Python
Really helpful! Thanks Robin!
Matplotlib never ceases to amaze me. Thank you; this is really helpful for both classes and research!
I’ve been banging my head at the problem of how to hide legend items in pandas for 36 hours ! Thank you for explaining the connection between using the underscore with matplot and pandas ! This was extremely helpful for a work project
You can use the option legend=None with DataFrame, eg df.plot(legend=None)
https://stackoverflow.com/questions/5735208/remove-the-legend-on-a-matplotlib-figure