英文:
plotly.js y-axis same position of zero-line
问题
我有一堆散点线要绘制。其中一些值在0到10k之间,而另一些范围在-1到1之间。不同应用程序的值范围不同,因此我不能将它们设置为固定值。
我的问题有点类似于这个问题:
https://stackoverflow.com/questions/71798553/plotly-two-y-axis-same-position-of-zero-line
但是我的第二个Y轴上有负值,因此rangemode='tozero'对我不起作用。
我希望两个轴共享相同的X轴/在相同位置具有y=0的值。我在CodePen中使用了我的代码。
https://codepen.io/kesslerf/pen/mdQJQbY
以下是代码:
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>
JS部分:
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"
}
]
},
// 其他数据...
}
// 其余代码...
希望这对你有所帮助。
英文:
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:
https://stackoverflow.com/questions/71798553/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);
});
答案1
得分: 0
这是您提供的代码的中文翻译:
我刚刚编写了一个用于计算的函数,并添加了在 Date-Format 中使用新的 x 范围进行缩放/重新布局的可能性。
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;
};
希望这对您有所帮助!如果您有任何其他问题,请随时提出。
英文:
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;
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论