How do I control the display order of traces in plotly.js?
Asked Answered
S

2

7

I have a large number of trace lines being displayed. 50-200 typically. I am comparing historical data to simulated data. I want to highlight a single simulated traceline by selection via a different color. All of this works fine.

However, the trace line being shown is sometimes hidden by the large number of other lines. Is there a way to force the specified trace to be drawn on top of the others, aside from redrawing the entire plot and adding that line last? Some sort of z-index equivalent or "bring to front" mechanism?

Sommer answered 12/12, 2016 at 0:49 Comment(2)
Unfortunately not as far as I know, plotly draws SVG images which don't have a z-index (#482615). Your approach of adding the line last seems to best in absence of alternatives.Doublure
Thanks. Yeah, as of now that seems like the only viable approach. Good point on the SVG factor. I might explore a little more in SVG draw order, but I suspect you're right.Sommer
D
4

Perhaps this useful to other Plotly users as well. The snippet pushed trace 7 to the foreground using Plotly's react function.

var foreground = 7; //trace which is pushed to the foreground

//generate some random data
var trace1 = {
  x: [1, 2, 3, 4],
  y: [1, 2, 0.5, 1.5],
  type: 'lines',
  name: 'trace 0',
  line: {
width: 2
  }
};

var data = [trace1];
var i = 0;
var j = 0;
for (i = 1; i < 10; i += 1) {
  var trace = {
x: [],
y: [],
type: 'lines',
name: 'trace ' + i,
'line': {
  'width': 2
}
  };
  for (j = 0; j < trace1.x.length; j += 1) {
trace.x.push(trace1.x[j])
trace.y.push(trace1.y[j] + Math.random())
  }
  data.push(trace);
}

var buttonForeground = document.getElementById("foreground");
var buttonReset = document.getElementById("reset");

var div = document.getElementById('myDiv');
Plotly.newPlot(div, data);

buttonReset.disabled = true;
buttonForeground.onclick = function() {
  var temp = data[foreground];
  data[foreground] = data[data.length - 1];
  data[data.length - 1] = temp;
  data[data.length - 1]['line']['width'] = 5;
  Plotly.react(div, data);

  switchButtons();
};

document.getElementById("reset").onclick = function() {
  var temp = data[data.length - 1];
  data[data.length - 1] = data[foreground];
  data[foreground] = temp;
  data[foreground]['line']['width'] = 2;
  Plotly.react(div, data, {});
  
  switchButtons();
};

function switchButtons() {
  buttonForeground.disabled = !buttonForeground.disabled;
  buttonReset.disabled = !buttonReset.disabled;
}
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv" style="width: 480px; height: 400px;"></div>
<button type="button" id='foreground'>Foreground</button>
<button type="button" id='reset'>Reset</button>
Doublure answered 12/12, 2016 at 22:27 Comment(3)
Interesting solution, however this changes the order of plots in the legend.Spitzer
The script has an error when clicking on Foreground button.Harrier
@Mark: Thanks for noticing! Plotly's function seem to have gotten an update, I modified the answer to have it working with latest version.Doublure
G
0

I had the top trace at the end of the data array, but it was still not appearing at the top.

Turns out, it was of a different type than the rest, and plotly seems to prioritise scattergl over the default type. So when I changed the type of all my objects in data to scattergl finally plotly respected the order in the data array.

Example before:

const data = [];

data.push({
  x: [0, 1, ...],
  y: [43, 100, ...],
  ids: ["first", "second", ...],
  type: "scattergl",
  mode: "markers",
  marker: {opacity: 1, color: "green", size: 8},
  showlegend: false,
  name: "",
});

data.push({
  x: [10],
  y: [55],
  ids: ["selected"],
  mode: "markers",
  marker: {opacity: 1, color: "green", size: 8},
  showlegend: false,
  name: "",
});

After fixing:

data.push({
  x: [10],
  y: [55],
  ids: ["selected"],
  type: "scattergl", // <---- add this
  mode: "markers",
  marker: {opacity: 1, color: "green", size: 8},
  showlegend: false,
  name: "",
});
Garlandgarlanda answered 19/3 at 16:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.