plotly two y-axis same position of zero-line - javascript

I want to plot two axis (bar + scatter) on a plotly chart with javascript, but I can't get the zero baseline of the second y-axis to align with the first axis.
Here is the result of the current version:
The Zero-line of the right y-axis (the scatter line) is higher than the zero-line of the left y-axis. I would want to have them on the same height in the plot, basically overlapping.
I create the Plotly object like this:
const trace1 = { x: dates, y: y1, name: 'item', type: 'bar' };
const trace2 = { x: dates, y: y1_cumsum, name: 'Total', yaxis: 'y2', type: 'scatter' };
Plotly.newPlot(MYDIV, [trace1,trace2], {
margin: {t: 0},
barmode: 'group',
hovermode: 'x unified',
yaxis: {title: 'item', dtick: 1},
yaxis2: {
title: 'total',
overlaying: 'y',
side: 'right'
},
showlegend: true,
legend: {
x: 0.25,
xanchor: 'right',
y: 1
}
});
I tried to change position in the config, but this does only affect the x-position, not where the y-axis starts. I can't find any suitable attribute in the docs (https://plotly.com/javascript/reference/layout/yaxis/) that would achieve that.
How can I set the position of the second y-axis to be the same as the first one?
Thanks.

Assuming you don't have negative values in your data, you can set layout.yaxis.rangemode = 'tozero'for one or both of your axes.
const trace1 = {
x: [3, 4, 5],
y: [0, 15, 13],
mode: 'markers+lines',
type: 'scatter',
yaxis: 'y2'
};
const trace2 = {
x: [3, 4, 5],
y: [1, 0, 3],
type: 'bar'
};
Plotly.newPlot('myDiv', [trace1,trace2], {
margin: {t: 0},
barmode: 'group',
hovermode: 'x unified',
yaxis: {title: 'item', dtick: 1},
yaxis2: {
title: 'total',
overlaying: 'y',
side: 'right',
rangemode: 'tozero'
},
showlegend: true,
legend: {
x: 0.25,
xanchor: 'right',
y: 1
}
});
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-2.11.1.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>

Related

Plotly.js Axis Click/Drag Event

I have multiple y-axis in a line chart. Only the last y-axis related grid lines are shown by default. If the user clicks on any other y-axis, grid lines for that y-axis should be shown. But I am unable to find any event in plotly.js which triggers when the axis is clicked or dragged.
Sorry, I can't comment yet. Here's a rather hacky way of registering clicks on yaxis labels. Not sure if that's helpful.
var trace1 = {
x: [1, 2, 3],
y: [40, 50, 60],
name: 'yaxis data',
type: 'scatter'
};
var trace2 = {
x: [2, 3, 4],
y: [4, 5, 6],
name: 'yaxis2 data',
yaxis: 'y2',
type: 'scatter'
};
var data = [trace1, trace2];
var layout = {
title: 'Double Y Axis Example',
yaxis: {title: 'yaxis title'},
yaxis2: {
title: 'yaxis2 title',
titlefont: {color: 'rgb(148, 103, 189)'},
tickfont: {color: 'rgb(148, 103, 189)'},
overlaying: 'y',
side: 'right'
}
};
Plotly.newPlot('chart', data, layout);
var myPlot = document.getElementById('chart');
myPlot.on('plotly_afterplot', function(){
Plotly.d3.selectAll(".nsdrag.drag.cursor-ns-resize")
.on("click", function() {
var target = Plotly.d3.event.target;
console.log('clicked on', target.dataset.subplot);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/1.49.5/plotly.min.js"></script>
<div id="chart">
</div>

Highcharts: completely custom label positions on x-axis

I'm trying to make a histogram using highcharts, but the data is being bucketed by the server so as far as I can tell, I can't use the histogram chart type.
Here's my chart:
Highcharts.chart('container', {
credits: {
enabled: false
},
title: {
text: null
},
xAxis: {
type: 'category',
labels: {
rotation: -45
}
},
series: [
{
type: 'variwide',
showInLegend: false,
data: [
{ name: '0.00 - 10.10', y: 13, z: 1260000 },
{ name: '10.10 - 34.14', y: 10, z: 3000000 },
{ name: '34.14 - 54.56', y: 9, z: 2550000 },
{ name: '54.56 - 71.43', y: 15, z: 2110000 },
{ name: '71.43 - 102.09', y: 4.6, z: 3830000 },
{ name: '102.09 - 161.56', y: 1.8, z: 7430000 },
{ name: '161.56 - 217.26', y: 5.7, z: 6960000 },
{ name: '217.26 - 301.65', y: 0.7, z: 10550000 },
{ name: '301.65 - 382.82', y: 2.8, z: 10150000 },
{ name: '382.82 - 874.80', y: 0.2, z: 61500000 }
]
}
]
});
#container {
max-width: 800px;
min-width: 380px;
margin: 0 auto;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/variwide.js"></script>
<div id="container"></div>
As you can see, the labels look pretty bad.
Two solutions, neither of which I can work out how to do:
Rename the points (I can do this) and move them to the right so that they're under the ticks
Better solution: make the x axis linear and have the labels appear in natural places like they would usually on a linear graph, similar to https://www.highcharts.com/demo/histogram . Changing the axis to linear seems to mess everything up on a variwide chart, though…
Any ideas?
Variwide series doesn't support non categorized x axis. It's reported as an issue on github: https://github.com/highcharts/highcharts/issues/7359
Workaround:
Variwide can be simulated by using column series.
Create a separate series for each point and link them together by putting linkedTo: ':previous' in each of them (except of the first one). Then set pointRange for every series. pointRange is series' property and cannot be assigned to individual points - that's why separate series has to be crated for each point.
series: [{
data: [
[5, 99]
],
pointRange: 2
}, {
linkedTo: ':previous',
data: [
[7.5, 72]
],
pointRange: 3
}, {
linkedTo: ':previous',
data: [
[14, 111]
],
pointRange: 10
}]
x position of the point indicates the middle of the column. So if the x = 5 and pointRange = 2 then the column will span from 4 to 6.
Unfortunately Highcharts doesn't handle extremes well while using multiple values of pointRange. Setting x axis minimum fixes it:
xAxis: {
min: 9, // 4 (axis' minimum) + 10 (max point range) / 2 = 9
},
These plotOptions are required to achieve proper widths of columns:
grouping: false,
groupPadding: 0,
pointPadding: 0,
Live demo: http://jsfiddle.net/BlackLabel/27gr3wh8/
API reference: https://api.highcharts.com/highcharts/

Multiple Y-Axis Legend on single data with plotly.js

I'am willing to display two legends (relative and absolute scales) on a graphic using plotly js. To do so I may use this piece of code:
var trace1 = {
x: [1, 2, 3],
y: [40, 50, 60],
name: 'absolute',
type: 'scatter'
};
var trace2 = {
x: [1, 2, 3],
y: [4, 5, 6],
name: 'relative',
yaxis: 'y2',
type: 'scatter'
};
var data = [trace1, trace2];
var layout = {
title: 'Double Y Axis',
yaxis: {title: 'absolute'},
yaxis2: {
title: 'relative',
overlaying: 'y',
side: 'right'
}
};
Plotly.newPlot('myDiv', data, layout);
But it basically draws twice the same line, which I don't want. Is their a cheaper way to add a scale + legend on the right side of my graph ?
Not with plotly.
Using a enhanced chart library such as ngx-charts however, may solve your problem

Plotly.js adding linegraph to barchart makes bars disappear

I have created a barchart that works properly the way I want. Right now, I'm trying to add a linegraph to overlap the bars, but when I run the code, the linegraph appears, but the bars disappear. It seems pretty simple to add the linegraph, but for some reason it's not working. I'm not getting any mistakes in console either.
var x_text = ["Comodities","Consumer Discretionary","Utilities",
"Health & Biotech","Global Real Estate","Financials",
"Emerging Market Bonds","Technologies","Industrials",
"Oil & Gas","China Equities","S&P500"];
//
var trace1 = [{
x: x_text, // X axis (names)
y: zValues, // Values (y axis)
hoverinfo: zValues,
type: 'bar',
orientation:"v",
marker: {
color: color_list, // Color of bars
line: {
color: 'rbg(8,48,107)',
width: 1
}},
yauto: false,
showscale: true,
}];
var trace2 = {
x: x_text,
y: [-0.1,-0.1,2.3,3.3,1.0,0.4,0.9,3.0,-0.1,-1.4,3.0,0.2],
mode: 'lines',
line:{
color:'black'
},
type: 'scatter'
};
var layout = {
font:{
// Text size and color
size:16,
family:'helvetica',
color: "white"
},
annotations: arrow(),
xaxis: {
side: 'bottom',
orientation: "right"
},
yaxis: {
autosize: true,
tickfont: "white",
ticksuffix: "%",
// Y axis scale
autorange: false,
range :[-20,20]
},
// Graph position
margin: {
l: 90,
r: 90,
b: 120,
t: 20,
pad: 10
},
// Graph background colors
paper_bgcolor: "transparent",
plot_bgcolor:"transparent",
};
var data = [trace1, trace2];
Plotly.newPlot('myDiv',data,layout);
Oh dam, my trace1 had braces+curly braces around the values, which worked for only the bar, but made it dissappear when the linegraph was called.

Chart.js How to invert (swap) axes?

Taking from inspiration from this question, I am trying to figure out how to swap the axes of a Line chart in Chart.js.
For instance, in Highcharts we have this example, although it's an area chart.
Is it possible to "swap" the X and Y axis on a line chart?
datasets: [
{
label: "data1a",
data: [1,2,3,4,5,1,2,3]
}
]
yAxes: [
{
type: "linear",
display: true,
position: "left",
}
]
Here's my fiddle modified from the above link. I'm basically trying to move it so the graph looks rotated 90 degrees. I tried changing the y position to 'top' but it still doesn't look correct.
The proposal by #dralth works fine with version 2.8.0, but for some reason showLines: true does not work anymore since version 2.9.0.
It is still possible showing the lines by using the showLine property for each dataset.
In case of #dralth's example it works as follows (tested with version 2.9.3):
new Chart(document.getElementById('myChart'), {
type: 'scatter',
data: {
datasets: [
{
label: 'My Dataset',
data: [{x: 3, y: 2}, {x: 5, y: 7}, {x: 9, y: 10}],
showLine: true
},
],
},
options: {
scales: {
xAxes: [
{
type: 'linear',
position: 'bottom',
},
],
yAxes: [
{
type: 'linear',
},
],
}
}
})
I was able to accomplish this in Chart.js 2.8.0:
Change data to a list of objects with x and y. Since the intention is to swap x and y axis, put the "x data" in the y variable and vise verse.
eg. [{x: 3, y: 2}, {x: 5, y: 7}, {x: 9, y: 10}]
Set the chart type to 'scatter'
Add showLines: true to the options
The outcome is a line chart where the line can be horizontal, vertical, or even double back on itself. The orientation of the line is defined by which values you put in x and which you put in y.
Here's an example configuration:
new Chart(document.getElementById('myChart'), {
type: 'scatter',
data: {
datasets: [
{
label: 'My Dataset',
data: [{x: 3, y: 2}, {x: 5, y: 7}, {x: 9, y: 10}],
},
],
},
options: {
showLines: true,
scales: {
xAxes: [
{
type: 'linear',
position: 'bottom',
},
],
yAxes: [
{
type: 'linear',
},
],
}
}
})
If you're using an older version of Chart.js that doesn't have scatter plots, you can use this plugin: http://dima117.github.io/Chart.Scatter/

Categories

Resources