Search code examples
javascriptangularplotly

Plotly.js : Overlaying two different graphs with same x-axis and different y-axis scales


I have a scenario in my application while using Plotly.js where I need to overlay two different line graphs in the same plane, with the same x-axis and different y-axis scales, stacked on top of each other as shown in the image below. I imagine it to look something like this : enter image description here

How can I do this?


Solution

  • You can create a secondary yaxis, then set the range of the primary and secondary yaxes differently, and also set which tickmarks are displayed for each of the yaxes. To make things a bit more generlizeable, I included a function that creates linearly spaced arrays that you can use for tickmarks, and some scaling factors for the min and max of the yaxis ranges.

    You can view the codepen here.

    function linspace(start, stop, num, endpoint = true) {
        const div = endpoint ? (num - 1) : num;
        const step = (stop - start) / div;
        return Array.from({length: num}, (_, i) => start + step * i);
    }
    
    var yaxis_data = [40, 50, 60];
    var yaxis2_data = [4,5,6];
    
    var yaxis_data_min = Math.min(...yaxis_data);
    var yaxis_data_max = Math.max(...yaxis_data);
    
    var yaxis2_data_min = Math.min(...yaxis2_data);
    var yaxis2_data_max = Math.max(...yaxis2_data);
    
    var yaxis_data_range = [0.5*yaxis_data_min, yaxis_data_max];
    var yaxis2_data_range = [yaxis2_data_min, 1.5*yaxis2_data_max];
    
    var yaxis_ticks = linspace(yaxis_data_min, yaxis_data_max, 3)
    var yaxis2_ticks = linspace(yaxis2_data_min, yaxis2_data_max, 3)
    
    var trace1 = {
      x: [1, 2, 3],
      y: yaxis_data,
      name: 'yaxis data',
      type: 'scatter'
    };
    
    var trace2 = {
      x: [2, 3, 4],
      y: yaxis2_data,
      name: 'yaxis2 data',
      yaxis: 'y2',
      type: 'scatter'
    };
    
    var data = [trace1, trace2];
    
    var layout = {
      title: 'Double Y Axis Example',
      yaxis: {
        title: 'yaxis title',
        range: yaxis_data_range,
        tickvals: yaxis_ticks
      },
      yaxis2: {
        title: 'yaxis2 title',
        titlefont: {color: 'rgb(148, 103, 189)'},
        tickfont: {color: 'rgb(148, 103, 189)'},
        overlaying: 'y',
        side: 'right',
        range: yaxis2_data_range,
        tickvals: yaxis2_ticks
      }
    };
    
    Plotly.newPlot('myDiv', data, layout);
    

    enter image description here