Search code examples
javascriptplotlyplotly.js

Stacked vertical bar chart in subplot


I'm trying to build a stacked vertical bar chart with plotly js but am having trouble with the syntax. Whenever I add trace3 to the data array the chart seems to merge all charts together. Here is a bit of context to the graphic:

  • I'm trying to show the relationship between price and the number of returns in a month
  • The graph on the left is a stacked bar chart showing the number of products purchased vs the number of products returned
  • The right hand side shows the average price delta of that month

Here is what I've achieved so far: https://codepen.io/andscool/pen/RwqydVW

It seems like the data array attempts to merge all charts into one (ignoring my grid specifications) when I insert this code into

var trace3 = {
    x: [2, 3, 5, 3, 2, 1, 0],
    y: ["2023.06", "2023.04", "2023.05", "2023.01", "2023.03", "2023.02", "2022.12"],
    name: 'Returns',
    orientation: 'h',
    type: 'bar',
    xaxis: 'x3',
    yaxis: 'y3',
}

var data = [trace1, trace3, trace2];

Any help would be much appreciated. FYI, here are my sources:

Please let me know if any information is missing.

Edit: I'm trying to go for something like this (a picture paints a thousand words :P )

enter image description here


Solution

  • The trace ordering in the data array has no effect on their placement in the layout. In order to stack trace 1 and trace 3 together, let them refer to the same axes and set barmode: 'stack' in the layout.

    var trace1 = {
      x: [140, 3, 17, 4, 61, 33, 47],
      y: ["2023.06", "2023.05", "2023.04", "2023.03", "2023.02", "2023.01", "2022.12"],
      type: 'bar',
      orientation: 'h',
      xaxis: 'x1',
      yaxis: 'y1',
      text: ["140 75%", "3", "17", "4", "61", "33", "47"]
    };
    
    var trace3 = {
      x: [2, 3, 5, 3, 2, 1, 0],
      y: ["2023.06", "2023.04", "2023.05", "2023.01", "2023.03", "2023.02", "2022.12"],
      name: 'Returns',
      orientation: 'h',
      type: 'bar',
      xaxis: 'x1',
      yaxis: 'y1',
    }
    
    var trace2 = {
      x: [-50, -3, 17, -4, -61, 33, 47],
      y: ["2023.06", "2023.04", "2023.05", "2023.01", "2023.03", "2023.02", "2022.12"],
      xaxis: 'x2',
      yaxis: 'y2',
      type: 'bar',
      orientation: 'h',
      text: ["-50€", -3, 17, -4, -61, 33, 47]
    };
    
    var data = [trace1, trace3, trace2];
    
    var layout = {
      barmode: 'stack',
      showlegend: false,
      grid: {rows: 1, columns: 2, pattern: 'independent'},
      xaxis1: {
        title: "Anzahl der Produkten (n)",
        showticklabels: true,
        showgrid: true,
      },
      yaxis1: {
        type: "category",
        tickmode:"array",
        tickvals: ["2023.02","2023.03","2023.01","2023.05","2023.04","2023.06", "2022.12"],
        ticktext:["2023.02","2023.03","2023.01","2023.05","2023.04","2023.06", "2022.12"]
      },
      xaxis2: {
        title: "Euro (€)"
      },
      yaxis2: {
        type: "category",
        showticklabels: false
      }
    }
    
    Plotly.newPlot('myDiv', data, layout);
    <head>
        <!-- Load plotly.js into the DOM -->
        <script src='https://cdn.plot.ly/plotly-2.24.1.min.js'></script>
    </head>
    
    <body>
        <div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
    </body>