Search code examples
javascripthtmlplotlyplotly.js

Plotly js will not display more than one plot in HTML without using subplot


I would like to plot two different plots with Plotly on an HTML page, but only one will show.

I've tried to make Plotly.js plots based on this codepen.io I found but it will not display multiple plots properly. I have two CSV URLs. If I comment out one URL's code, the other will appear fine. However, if I include both code, only one will display and the other is blank. Is there a certain code I'm missing that will enable multiple plots to exist in an HTML site? I do not want to use subplot.

Partial code:

// Place urls for cvs files here
var url1 = 'https://raw.githubusercontent.com/cherryleh/testcsvs/main/RS04-ET.csv';
var x1SeriesName = 'datetime';
var y1SeriesName = 'ET';
var y1NameToBeDisplayed = 'ET';
var y1Mode = 'lines';


var url2 = 'https://raw.githubusercontent.com/cherryleh/testcsvs/main/RS04-ndvi.csv';
var x2SeriesName = 'datetime';
var y2SeriesName = 'NDVI';
var y2NameToBeDisplayed = 'NDVI';
var y2Mode = 'lines';


//URL1
function makeplot() {
  Plotly.d3.csv(url1, function(data){ processData(data,x1SeriesName,y1SeriesName,y1NameToBeDisplayed) } );
};

function processData(allRows,xLabel,yLabel,yTraceName) {

  console.log(allRows.length);
  var x = [], y = [];

  for (var i=0; i<allRows.length; i++) {
    row = allRows[i];
 
    x.push(row[xLabel]);
    y.push(row[yLabel]);
    if(i === 0) {
      console.log(i);
      console.log(row);
    }
  }
  makePlotly( x, y,  yTraceName);
}

function makePlotly( x, y, yTraceName){
  var traces = [{
    x: x,
    y: y,
    name: yTraceName
  }];

  Plotly.newPlot(myDiv1, traces,layout,options);
};

makeplot();

//instruction resizes plot
window.onresize = function() {
  Plotly.Plots.resize(my_Div);
};




//URL2
function makeplot() {
  Plotly.d3.csv(url2, function(data){ processData(data,x2SeriesName,y2SeriesName,y2NameToBeDisplayed) } );
};

function processData(allRows,xLabel,yLabel,yTraceName) {

  console.log(allRows.length);
  var x = [], y = [];

  for (var i=0; i<allRows.length; i++) {
    row = allRows[i];
 
    x.push(row[xLabel]);
    y.push(row[yLabel]);
    if(i === 0) {
      console.log(i);
      console.log(row);
    }
  }
  makePlotly( x, y,  yTraceName);
}

function makePlotly( x, y, yTraceName){
  var traces = [{
    x: x,
    y: y,
    name: yTraceName
  }];

  Plotly.newPlot(myDiv1, traces,layout,options);
};

makeplot();

//instruction resizes plot
window.onresize = function() {
  Plotly.Plots.resize(my_Div);
};


Full code including HTML and layout code can be found here.


Solution

  • I think there's a few things you can clean up in your code. It's better to reuse functions by adding more parameters rather than redefine the same function twice (and have to hardcode the data and div tag into each function definition)

    I restructured your code so that the makeplot function plots data from both url1 and url2, and added an additional divName parameter so that you can reuse the processData and makePlotly functions.

    You can find the jsfiddle here

    // Place urls for cvs files here
    var url1 = 'https://raw.githubusercontent.com/cherryleh/testcsvs/main/RS04-ET.csv';
    var x1SeriesName = 'datetime';
    var y1SeriesName = 'ET';
    var y1NameToBeDisplayed = 'ET';
    var y1Mode = 'lines';
    
    
    var url2 = 'https://raw.githubusercontent.com/cherryleh/testcsvs/main/RS04-ndvi.csv';
    var x2SeriesName = 'datetime';
    var y2SeriesName = 'NDVI';
    var y2NameToBeDisplayed = 'NDVI';
    var y2Mode = 'lines';
    
    
    //var url3 = 'XXXX';
    //var url4 = 'XXXX';
    //var url5 = 'XXXX';
    
    
    // Section deals with buttons for time range selection
    var selectorOptions = {
      buttons: [{
        step: 'month',
        stepmode: 'backward',
        count: 1,
        label: '1m'
      }, {
        step: 'month',
        stepmode: 'backward',
        count: 6,
        label: '6m'
      }, {
        step: 'year',
        stepmode: 'todate',
        count: 1,
        label: 'YTD'
      }, {
        step: 'year',
        stepmode: 'backward',
        count: 1,
        label: '1y'
      }, {
        step: 'all',
      }],
    };
    
    // set layout down here
    var layout = {
      xaxis: {
        rangeselector: selectorOptions,
        rangeslider: {}
      },
      yaxis: {
        fixedrange: true,
        side: 'right'
      },
      showlegend: false
    };
    
    // set display options
    var options ={
      showLink: false,
      displayModeBar: false
    };
    
    // Next piece of code deals with responsiveness
    var d3 = Plotly.d3;
    var WIDTH_IN_PERCENT_OF_PARENT = 100,
      HEIGHT_IN_PERCENT_OF_PARENT = 97;
    
    var gd3_div1 = d3.select("div[id='myDiv1']")
      .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT) / 2 + '%',
        height: HEIGHT_IN_PERCENT_OF_PARENT + 'vh',
        'margin-top': (100 - HEIGHT_IN_PERCENT_OF_PARENT) / 2 + 'vh'
      });
      
    var gd3_div2 = d3.select("div[id='myDiv2']")
      .style({
        width: WIDTH_IN_PERCENT_OF_PARENT + '%',
        'margin-left': (100 - WIDTH_IN_PERCENT_OF_PARENT) / 2 + '%',
        height: HEIGHT_IN_PERCENT_OF_PARENT + 'vh',
        'margin-top': (100 - HEIGHT_IN_PERCENT_OF_PARENT) / 2 + 'vh'
      });
    
    var my_Div1 = gd3_div1.node();
    var my_Div2 = gd3_div2.node();
    
    
    //URL1 and URL2
    function makeplot() {
      Plotly.d3.csv(url1, function(data){ processData(data,x1SeriesName,y1SeriesName,y1NameToBeDisplayed, "myDiv1") } );
      Plotly.d3.csv(url2, function(data){ processData(data,x2SeriesName,y2SeriesName,y2NameToBeDisplayed, "myDiv2") } );
    };
    
    function processData(allRows,xLabel,yLabel,yTraceName, divName) {
    
      console.log(allRows.length);
      var x = [], y = [];
    
      for (var i=0; i<allRows.length; i++) {
        row = allRows[i];
     
        x.push(row[xLabel]);
        y.push(row[yLabel]);
        if(i === 0) {
          console.log(i);
          console.log(row);
        }
      }
      makePlotly( x, y,  yTraceName, divName);
    }
    
    function makePlotly( x, y, yTraceName, divName){
      var traces = [{
        x: x,
        y: y,
        name: yTraceName
      }];
    
      Plotly.newPlot(divName,traces,layout,options);
    };
    
    makeplot();
    
    //instruction resizes plot
    window.onresize = function() {
      Plotly.Plots.resize(my_Div1);
      Plotly.Plots.resize(my_Div2);
    };
    

    enter image description here