I have a bunch of scatter-lines that I want to plot. There are some that have values between 0 and 10k and some where the range is -1 -> 1. The value-ranges are different for different applications, so I can not set them to fixed values.
My question is kind of similar to this one: plotly two y-axis same position of zero-line But I have negative values on my second Y-Axis, thus the rangemode='tozero' is not working for me.
I want both axis to share the same X-axis/have the y=0 value on the same position. I made a codepen with my code. https://codepen.io/kesslerf/pen/mdQJQbY
Here is the code: HTML:
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-2.16.1.min.js'></script>
</head>
<body>
<div id='ts' class='ts' style="width:1200px; height:800px; background-color: aliceblue"></div>
</body>
And the JS-Part:
var data_all = {
"b02": {
"min_value": 562,
"max_value": 1007,
"values": [
{
"date": "2018-07-01 00:00:00",
"value": "587"
},
{
"date": "2018-07-04 00:00:00",
"value": "562"
},
{
"date": "2018-07-16 00:00:00",
"value": "794"
},
{
"date": "2018-07-19 00:00:00",
"value": "966"
},
{
"date": "2018-07-24 00:00:00",
"value": "1007"
}
]
},
"b04": {
"min_value": 1091,
"max_value": 2549,
"values": [
{
"date": "2018-07-01 00:00:00",
"value": "1091"
},
{
"date": "2018-07-04 00:00:00",
"value": "1175"
},
{
"date": "2018-07-16 00:00:00",
"value": "1553"
},
{
"date": "2018-07-19 00:00:00",
"value": "2409"
},
{
"date": "2018-07-24 00:00:00",
"value": "2549"
}
]
},
"evi": {
"min_value": 0,
"max_value": 1,
"values": [
{
"date": "2018-07-01 00:00:00",
"value": "1"
},
{
"date": "2018-07-04 00:00:00",
"value": "1"
},
{
"date": "2018-07-16 00:00:00",
"value": "0"
},
{
"date": "2018-07-19 00:00:00",
"value": "0"
},
{
"date": "2018-07-24 00:00:00",
"value": "0"
}
]
},
"ndvi": {
"min_value": 0,
"max_value": 1,
"values": [
{
"date": "2018-07-01 00:00:00",
"value": "1"
},
{
"date": "2018-07-04 00:00:00",
"value": "0"
},
{
"date": "2018-07-16 00:00:00",
"value": "0"
},
{
"date": "2018-07-19 00:00:00",
"value": "0"
},
{
"date": "2018-07-24 00:00:00",
"value": "0"
}
]
}
}
var unpack = function(rows, key) {
return rows.map(function(row) { return row[key]; })
};
var layout = {
autosize: false,
width: 1000,
height: 420,
margin: {
l:50,
r:150,
b: 50,
t: 50,
pad: 4
},
xaxis: {title: 'Datum',
type: 'date',
tickformat: '%d-%m-%y'},
yaxis: {title: 'Wert',
side: 'left'},
yaxis2: {
title: 'yaxis2 title',
overlaying: 'y',
side: 'right',
},
legend: {
x: 1.1,
y: 0
}
}
var plotly_config = {
displaylogo: false,
showSendToCloud: true,
};
var traces = [];
for (var key1 in data_all){
var idx_data = data_all[key1]['values'];
var dates = unpack(idx_data,'date').map(n => n.substr(0,10));
var values_dates = unpack(idx_data,'value').map(n => parseFloat(n));
if (key1.substr(0,1) !== 'b') {
var cur_col = 'red';
var trace = {
x: dates,
y: values_dates,
name: key1,
xaxis: 'x',
yaxis: 'y2',
type: 'scatter'
};
traces.push(trace);
}else {
var cur_col = 'blue';
var trace = {
x: dates,
y: values_dates,
name: key1,
xaxis: 'x',
yaxis: 'y',
type: 'scatter'
};
traces.push(trace);
}
}
Plotly.newPlot('ts', traces, layout, plotly_config);
$('.ts')[0].on('plotly_hover', function(data){
if(data.points[0].data.yaxis=='y'){
layout.yaxis.linewidth = 5;
}else if (data.points[0].data.yaxis == 'y2'){
layout.yaxis2.linewidth = 5;
}
Plotly.update('ts',{},layout);
});
$('.ts')[0].on('plotly_unhover', function(data){
layout.yaxis.linewidth = 1;
layout.yaxis2.linewidth = 1;
Plotly.update('ts',{},layout);
});
I just wrote a function to calculate it, added a possibility to use it on zoom/relayout using the new x-range if it is in Date-Format.
var adjustYAxis = function(traces,layout,new_x_min, new_x_max){
var y1_max = 0;
var y1_min = 0;
var y2_max = 0;
var y2_min = 0;
for (let t=0;t<traces.length;t++){
var curtrac = traces[t];
if(new_x_min && new_x_max){
var dates_act = curtrac.x.map(n => (new Date(n) > new Date(new_x_min) && new Date(n) < new Date(new_x_max)));
var relevant_vals = curtrac.y.slice(dates_act.indexOf(true),dates_act.lastIndexOf(true));
}else{
relevant_vals = curtrac.y;
}
if(traces[t].yaxis === 'y'){
if (Math.max(...relevant_vals) > y1_max){
y1_max = Math.max(...relevant_vals);
}
if (Math.min(...relevant_vals) < y1_min){
y1_min = Math.min(...relevant_vals);
}
}else{
if (Math.max(...relevant_vals) > y2_max){
y2_max = Math.max(...relevant_vals);
}
if (Math.min(...relevant_vals) < y2_min){
y2_min = Math.min(...relevant_vals);
}
}
}
if(y1_max > 1){
y1_max = y1_max - y1_max%250 + 250;
y2_max = y2_max - y2_max%0.2 + 0.2;
y2_min = y2_min - y2_min%0.2 - 0.2;
if(y2_min < y1_min){
y1_min = -1 * Math.abs(y2_min) * Math.abs(y1_max) / Math.abs(y2_max);
}
}else{
y1_max = 1;
y1_min = 0;
}
layout.yaxis.autorange = false;
layout.yaxis2.autorange = false;
layout.xaxis.autorange = false;
layout.yaxis.range = [y1_min, y1_max];
layout.yaxis2.range = [y2_min, y2_max];
if(new_x_min && new_x_max){
layout.xaxis.range = [new_x_min, new_x_max];
}
layout.shapes[0].y0 = y1_min;
layout.shapes[0].y1 = y1_max;
return layout;
};