8

I would like to generate labels inside the areas of a matplotlib stackplot. I would settle for labeling a line used to bound the area. Consider the example:

import numpy as np
from matplotlib import pyplot as plt

fnx = lambda : np.random.randint(5, 50, 10)
x = np.arange(10)
y1, y2, y3 = fnx(), fnx(), fnx()
areaLabels=['area1','area2','area3']
fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3)
plt.show()

This produces:enter image description here

But I would like to produce something like this:

enter image description here

The matplotlib contour plots have this type of labeling functionality (though the lines are labeled in the case of the contour plot).

Any help (or even redirection to a post I might have missed) is appreciated.

Docuemada
  • 1,703
  • 2
  • 25
  • 44
  • Newcomers to this question may be confused because [the documentation](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.stackplot) suggests that labels are supported, but this [appears to be a lie](https://github.com/matplotlib/matplotlib/issues/1943). I get this error: `AttributeError: Unknown property labels` – Neil Traft Jan 21 '16 at 04:11

1 Answers1

5

Ah, heuristics. Something like this?:

import numpy as np
from matplotlib import pyplot as plt

length = 10
fnx = lambda : np.random.randint(5, 50, length)
x = np.arange(length)
y1, y2, y3 = fnx(), fnx(), fnx()
areaLabels=['area1','area2','area3']
fig, ax = plt.subplots()
ax.stackplot(x, y1, y2, y3)

loc = y1.argmax()
ax.text(loc, y1[loc]*0.25, areaLabels[0])

loc = y2.argmax()
ax.text(loc, y1[loc] + y2[loc]*0.33, areaLabels[1])

loc = y3.argmax()
ax.text(loc, y1[loc] + y2[loc] + y3[loc]*0.75, areaLabels[2]) 

plt.show()

which in test runs is okayish:

enter image description here

enter image description here

enter image description here

Finding the best loc could be fancier -- maybe one wants the x_n, x_(n+1) with the highest average value.

cphlewis
  • 15,759
  • 4
  • 46
  • 55
  • very clever. What I like about this is that it has the potential to be applied in a loop for an arbitrary number of labels. And even if it isn't perfect, I find your chart easier to quickly interpret than a comparable chart with a color key--especially when stacking >10 plots. – Docuemada Jul 23 '15 at 01:40
  • There are plots you can't label this way -- if area2 was all tiny, or if the values leapt up and down so there wasn't much horizontal area. It could maybe be a little clearer if the area colors were tied to the text colors somehow (text bordered with area color?). – cphlewis Jul 23 '15 at 03:07
  • yeah, `loc` should be defined in a loop for an arbitrary series of y?. Left as an exercise for the reader! – cphlewis Jul 23 '15 at 03:08