0

Consider the following stackplot, created using pyplot from matplotlib using stackplot(). There are two types of variables, earnings and expenses. Both of them are listed in the same legend. double stackplot

I'd like to have two separate legends, one for earnings and one for expenses. There is already one example of how this can be done on this site, which however does not work with the PolyCollection created by stackplot().

Here's a MWE with a single legend:

from matplotlib import pyplot as plt
fig, ax = plt.subplots()

xVector = range(3)
earnings = {'fare': [2, 4, 6], 'tip': [1, 2, 3]}
expenses = {'maintenance': [-0.5, -1, -1.5], 'gas': [-1, -1.5, -2]}

ax.stackplot(xVector, earnings.values(), labels=earnings.keys())
ax.stackplot(xVector, expenses.values(), labels=expenses.keys())

plt.legend(loc='upper left')
plt.xlabel('time')
plt.ylabel('currency')

plt.show()
  1. How can I split up the above legend into two, one for earnings shown at the top left, and one for expenses, shown at the bottom left?
  2. Is there a way to ensure that the order of the legend entries matches the order in the stack plot (in my original example, this is the case for the expenses, but not for the earnings)?
Mr. T
  • 11,960
  • 10
  • 32
  • 54
Unis
  • 614
  • 1
  • 5
  • 17
  • 1
    What version of matplotlib are you using? The linked question works for me using a PolyCollection – DavidG May 14 '21 at 08:36

1 Answers1

0

Using the current version of Matplotlib, multiple legends can be achieved in accordance with this answer from a different thread as follows (reversing the order of legend entries turned out to be straightforward, too).

from matplotlib import pyplot as plt
fig, ax = plt.subplots()

xVector = range(3)
earnings = {'fare': [2, 4, 6], 'tip': [1, 2, 3]}
expenses = {'maintenance': [-0.5, -1, -1.5], 'gas': [-1, -1.5, -2]}

earningsPlot = ax.stackplot(xVector, earnings.values())
expensesPlot = ax.stackplot(xVector, expenses.values())

plt.xlabel('time')
plt.ylabel('currency')

earningPlotLegend = plt.legend(earningsPlot[::-1], list(earnings.keys())[::-1], loc='upper left')
plt.legend(expensesPlot, expenses.keys(), loc='lower left')
plt.gca().add_artist(earningPlotLegend)

plt.show()

Graph with dedicated legends

Unis
  • 614
  • 1
  • 5
  • 17