13

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.

TOTORO
  • 131
  • 1
  • 3

3 Answers3

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
        )
    )
)