Afaik, y-axis cant be made to auto scale when using x-range sliders. Y range is chosen with respect to the y values of the whole x range and does not change after zooming-in. This is especially annoying with candlestick charts in volatile periods. When you zoom-in using x-range slider, you essentially get flat candlesticks as their fluctuations only cover a very small part of the initial range. After doing some research it seems that some progress has been made here: https://github.com/plotly/plotly.js/pull/2364. Anyone knows if there is a working solution for plotly.py ? Thanks for your time.
Asked
Active
Viewed 8,161 times
3 Answers
7
If it can help, I am using fixedrange = False on yaxis, to be able to zoom manually and adapt the window to the suited y range:
yaxis = dict(
fixedrange = False
)

5md
- 121
- 1
- 5
0
if you are using datestrings for your x axis, use myDiv for the id, and you store your data in a dictionary (chart_dict) this should do the trick (if your chart only has one trace this can be simplified of course):
$('#myDiv').on('plotly_relayout', function(event, arguments){
var _arg=arguments;
var _keys = Object.keys(_arg);
var _str=_keys[0];
window.console.log("relayout for ..",_str);
if( _str == "xaxis.range") {
var new_range = _arg[_str];
var newMax = null;
var newMin = null;
for (var key in chart_data){
var lowIdx = chart_data[key][0].find(x => x.includes(new_range[0].split(" ")[0]));
var highIdx = chart_data[key][0].find(x => x.includes(new_range[1].split(" ")[0]));
if (lowIdx == null || highIdx == null)
{
return;
}
var subChartData = chart_data[key][1].slice(chart_data[key][0].indexOf(lowIdx), chart_data[key][0].indexOf(highIdx));
var netMax = Math.max.apply(Math, subChartData);
var netMin = Math.min.apply(Math, subChartData);
if (newMax == null || newMax < netMax)
{
newMax = netMax;
}
if (newMin == null || newMin > netMin)
{
newMin = netMin;
}
}
var update = {
'yaxis.range': [newMin, newMax]
};
Plotly.relayout('myDiv', update);
}
});

nickw
- 171
- 5
-4
The only solution I could find was to remove the slider and then you can just use the regular zoom tool.
layout = go.Layout(
xaxis = dict(
rangeslider = dict(
visible = False
)
)
)

LooksMoneyStatus
- 23
- 1
- 5