Search code examples
pythonmatplotlibplotstacked-chartstacked-area-chart

Label Areas in Python Matplotlib stackplot


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.


Solution

  • 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.