Home > Mobile >  Matplotlib legend in separate figure with PolyCollection object
Matplotlib legend in separate figure with PolyCollection object

Time:10-29

I need to create the legend as a separate figure, and more importantly separate instance that can be saved in a new file. My plot consists of lines and a filled in segment.

The problem is the fill_between element, I can not add it to the external figure/legend.

I realise, this is a different type of object, it is a PolyCollection, while to line-plots are Line2D elements.

How do I handle the PolyCollection so that I can use it in the external legend?

INFO: matplotlib version 3.3.2

import matplotlib.pyplot as plt
import numpy as np

# Dummy data
x = np.linspace(1, 100, 1000)
y = np.log(x)
y1 = np.sin(x)


# Create regular plot and plot everything
fig = plt.figure('Line plot')
ax = fig.add_subplot(111)

line1, = ax.plot(x, y)
line2, = ax.plot(x, y1)
fill   = ax.fill_between(x, y, y1)

ax.legend([line1, line2, fill],['Log','Sin','Area'])
ax.plot()


# create new plot only for legend
legendFig = plt.figure('Legend plot')

legendFig.legend([line1, line2],['Log','Sin']) <----- This works
# legendFig.legend([line1, line2, fill],['Log','Sin', 'Area']) <----- This does not work

CodePudding user response:

You forgot to mention what does not work means here. Apparently, you get an error message: RuntimeError: Can not put single artist in more than one figure.

Matplotlib doesn't allow elements placed in one figure to be reused in another. It is just a lucky coincidence that the line don't give an error.

To use an element in another figure, you can create a new element, and that copy the style from the original element:

from matplotlib.lines import Line2D
from matplotlib.collections import PolyCollection

legendFig = plt.figure('Legend plot')

handle_line1 = Line2D([], [])
handle_line1.update_from(line1)
handle_line2 = Line2D([], [])
handle_line2.update_from(line2)
handle_fill = PolyCollection([])
handle_fill.update_from(fill)
legendFig.legend([handle_line1, handle_line2, handle_fill], ['Log', 'Sin', 'Area'])
  • Related