Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add item to existing Matplotlib legend

Given the following setup:

from matplotlib import pyplot as plt
fig, ax = plt.subplots()
ax.plot([0,1,2,3,4,5,6], label='linear')
ax.plot([0,1,4,9,16,25,36], label='square')
lgd = ax.legend(loc='lower right')

If a function add_patch receives only lgd as an argument, can a custom legend item be added to the legend on top of the existing items, without changing the other properties of the legend?

I was able to add an item using:

def add_patch(legend):
    from matplotlib.patches import Patch
    ax = legend.axes
    handles, labels = ax.get_legend_handles_labels()
    handles.append(Patch(facecolor='orange', edgecolor='r'))
    labels.append("Color Patch")
    ax.legend(handles=handles, labels=labels)

But this does not preserve the properties of the legend like location. How can I add an item given only the legend object after lines have been plotted?

like image 236
rovyko Avatar asked Apr 29 '19 01:04

rovyko


People also ask

How do I add another legend in Matplotlib?

Place the first legend at the upper-right location. Add artist, i.e., first legend on the current axis. Place the second legend on the current axis at the lower-right location. To display the figure, use show() method.

Can I have two legends in Matplotlib?

Multiple Legends. Sometimes when designing a plot you'd like to add multiple legends to the same axes. Unfortunately, Matplotlib does not make this easy: via the standard legend interface, it is only possible to create a single legend for the entire plot. If you try to create a second legend using plt.


2 Answers

In principle a legend is not meant to be updated, but recreated instead.

The following would do what you're after, but beware that this is a hack which uses internal methods and is hence not guaranteed to work and might break in future releases. So don't use it in production code. Also, if you have set a title to the legend with a different font(size) than default, it will be lost upon updating. Also, if you have manipulated the order of handles and labels via markerfirst, this will be lost upon updating.

from matplotlib import pyplot as plt
fig, ax = plt.subplots()
ax.plot([0,1,2,3,4,5,6], label='linear')
ax.plot([0,1,4,9,16,25,36], label='square')
lgd = ax.legend(loc='lower right')

def add_patch(legend):
    from matplotlib.patches import Patch
    ax = legend.axes

    handles, labels = ax.get_legend_handles_labels()
    handles.append(Patch(facecolor='orange', edgecolor='r'))
    labels.append("Color Patch")

    legend._legend_box = None
    legend._init_legend_box(handles, labels)
    legend._set_loc(legend._loc)
    legend.set_title(legend.get_title().get_text())


add_patch(lgd)

plt.show()

enter image description here

like image 156
ImportanceOfBeingErnest Avatar answered Oct 21 '22 00:10

ImportanceOfBeingErnest


Is adding the color patch after the lines have been plotted but before adding the legend an option?

import matplotlib.pyplot as plt
from matplotlib.patches import Patch

fig, ax = plt.subplots()
line1 = ax.plot([0,1,2,3,4,5,6], label='linear')
line2 = ax.plot([0,1,4,9,16,25,36], label='square')
patch = Patch(facecolor='orange', edgecolor='r', label='Color patch')
lgd = ax.legend(handles=[line1, line2, patch], loc='lower right')
like image 34
James Avatar answered Oct 21 '22 00:10

James