Search code examples
javascriptplotlylinechartstacked-chartplotly.js

Stack series in Plotly.js line chart


Is there an option in Plotly.js to stack line series (series "type": "")? In the example below the three lines to sum to 100%. enter image description here

It is possible to show series as either stacked (e.g. "barmode":"stack") or side-by-side (e.g. "barmode": "group") when they are shown as bars (series "type": "bar"), as below. That doesn't seem to work for lines.

CodePen: https://codepen.io/__proto__/pen/OJwOeWv

enter image description here

How to add series lines to 100% stacked bar charts with plotly

PowerPoint has a similar feature to show lines stacked or not

PowerPoint has a similar feature


Solution

  • Yes, you can set the traces to be stacked by assigning them to a stackgroup :

    Set several scatter traces (on the same subplot) to the same stackgroup in order to add their y values (or their x values if orientation is "h"). If blank or omitted this trace will not be stacked. Stacking also turns fill on by default and sets the default mode to "lines" irrespective of point count.

    And use groupnorm to normalize the sum of the stackgroup as a percentage : groupnorm: 'percent'.

    Now, since "stacking turns fill on by default and sets the default mode to "lines" irrespective of point count", Plotly will draw a stacked area chart by default, with no marker, ie. :

    stacked area chart

    So you will need to be explicit in order to obtain stacked lines with markers, that is, by setting fill: 'none' and mode: 'lines+markers' to each trace.

    You might also need to explicitly set the yaxis rangemode so that the yaxis range always extends to zero regardless of the input data (as it is the case above when fill is enabled).

    In the end you should obtain stacked lines :

    stacked lines chart

    Here the code used for the example above :

    var traces = [{
      x: [1,2,3], 
      y: [2,1,4], 
      stackgroup: 0, 
      mode: 'lines+markers',
      fill: 'none',
      groupnorm: 'percent' // nb. only the 1st groupnorm found in the group is used
    }, {
      x: [1,2,3], 
      y: [1,1,2], 
      stackgroup: 0,
      mode: 'lines+markers',
      fill: 'none'
    }, {
      x: [1,2,3], 
      y: [3,0,2], 
      stackgroup: 0,
      mode: 'lines+markers',  
      fill: 'none'
    }];
    
    let layout = {
      title: 'Normalized Stacked Lines',
      yaxis: { rangemode: 'tozero' } 
      width: 600,
    };
    
    Plotly.newPlot('plot', traces, );