Repository: holoviz/holoviews

Issue:
Stacked area only show last label
@Pill-GZ found a bug (and a solution!) for the legend of a stacked area plot only showing the last label. See https://discourse.holoviz.org/t/how-to-add-legend-for-stacked-area-plots/2193



Discussion:
The "solution" fixed the problem for areas passed in as hv.Overlay, i.e., when `is_overlay = isinstance(areas, Overlay)` is True.

I was not sure what other types of input are intended. I'd appreciate if someone familiar with the class and its design can take a look.

The best way to get people familiar with the class to look at it is to make a PR! I think the change you made to the following line is correct.
https://github.com/holoviz/holoviews/blob/5e4135662e0eca1c5c989954402122e3e63b274d/holoviews/element/chart.py#L292

I have taken a took a quick look at the different inputs `hv.Area.stack` accept according to the docstring and plotted it with and without your correction (`stacked[key] = areas[key].clone(sdf, vdims=vdims)`). 

| Without| With |
| ---| --- |
| ![2021-05-10 19_37_14](https://user-images.githubusercontent.com/19758978/117701919-1a6f2800-b1c8-11eb-8bf2-4917c48481f2.png) | ![2021-05-10 19_38_40](https://user-images.githubusercontent.com/19758978/117701931-1cd18200-b1c8-11eb-9555-b2bad03d04f6.png) | 

<details>
  <summary>Code</summary>
  
``` python

import numpy as np
import holoviews as hv
import panel as pn
from holoviews import opts

hv.extension("bokeh")

python = np.array([2, 3, 7, 5, 26, 221, 44, 233, 254, 265, 266, 267, 120, 111])
pypy = np.array([12, 33, 47, 15, 126, 121, 144, 233, 254, 225, 226, 267, 110, 130])
jython = np.array([22, 43, 10, 25, 26, 101, 114, 203, 194, 215, 201, 227, 139, 160])

dims = dict(kdims="time", vdims="memory")
python = hv.Area(python, label="python", **dims)
pypy = hv.Area(pypy, label="pypy", **dims)
jython = hv.Area(jython, label="jython", **dims)

opts.defaults(opts.Area(fill_alpha=0.5))
overlay = (python * pypy * jython).relabel("Overlay")
overlay1 = hv.Area.stack(overlay).relabel("Overlay")
nd_overlay = hv.NdOverlay({i: el for i, el in zip(["python", "pypy", "jython"], overlay)}).relabel("NdOverlay")
nd_overlay1 = hv.Area.stack(nd_overlay)
curve = (hv.Curve(python) * hv.Curve(pypy) * hv.Curve(jython)).relabel("Curve overlay")
curve2 = hv.Area.stack(curve).relabel("Curve overlay")

pn.Column(
    pn.Row(overlay, overlay1),
    pn.Row(nd_overlay, nd_overlay1),
    pn.Row(curve, curve2)
).servable()

```
</details>


Resolving patch:
diff --git a/holoviews/element/chart.py b/holoviews/element/chart.py
--- a/holoviews/element/chart.py
+++ b/holoviews/element/chart.py
@@ -289,5 +289,5 @@ def stack(cls, areas, baseline_name='Baseline'):
                 sdf[vdim.name] = sdf[vdim.name] + baseline
                 sdf[baseline_name] = baseline
             baseline = sdf[vdim.name]
-            stacked[key] = areas.last.clone(sdf, vdims=vdims)
+            stacked[key] = areas[key].clone(sdf, vdims=vdims)
         return Overlay(stacked.values()) if is_overlay else stacked


Test patch:
diff --git a/holoviews/tests/plotting/bokeh/testareaplot.py b/holoviews/tests/plotting/bokeh/testareaplot.py
--- a/holoviews/tests/plotting/bokeh/testareaplot.py
+++ b/holoviews/tests/plotting/bokeh/testareaplot.py
@@ -138,3 +138,17 @@ def test_area_padding_logy(self):
         self.assertEqual(y_range.start, 0.033483695221017122)
         self.assertEqual(y_range.end, 3.3483695221017129)
         self.log_handler.assertContains('WARNING', 'Logarithmic axis range encountered value less than')
+
+    def test_area_legend(self):
+        python = np.array([2, 3, 7, 5, 26, 221, 44, 233, 254, 265, 266, 267, 120, 111])
+        pypy = np.array([12, 33, 47, 15, 126, 121, 144, 233, 254, 225, 226, 267, 110, 130])
+        jython = np.array([22, 43, 10, 25, 26, 101, 114, 203, 194, 215, 201, 227, 139, 160])
+
+        dims = dict(kdims="time", vdims="memory")
+        python = Area(python, label="python", **dims)
+        pypy = Area(pypy, label="pypy", **dims)
+        jython = Area(jython, label="jython", **dims)
+
+        overlay = Area.stack(python * pypy * jython)
+        labels = [n[1] for n in overlay.data]
+        self.assertEqual(labels, ['Python', 'Pypy', 'Jython'])