如何在平移时动态调整y_range

时间:2017-04-25 20:58:30

标签: python r bokeh

我有很长的时间序列,在不同时间内有不同的Y范围。同时将X范围/视口限制在较小的时间段内,以便可以看到细节。由于数据是水平平移的,因此散景不会根据视口中的可见数据调整Y范围。

以下是rbokeh中的一个示例(如果有用,可以提供python中的等价物):

require(rbokeh)

x <- seq(as.Date('2010-1-1'), as.Date('2017-1-1'), by='days')
len <- NROW(x)
y <- (1:len) * 5e-2 + rnorm(len, sd=10)

range <- c(x[1], x[200])

figure(width=800,height=300, xlim=range) %>%
    ly_lines (x, y) %>%
    tool_pan(dimensions='width')

它产生的视觉效果显示-25到150的y范围,表示整个系列的范围,但由于可见数据的范围较小,减少了视口中可见的细节: what I get now

我希望看到初始范围显示-25到30,与可见点一致(如下所示),并随后在水平平移数据时更改Y范围。 what I would like to see

问题

有没有办法打开散景中的自动缩放/范围调整行为,以便在客户端完成。是否有一个小部件选项或js注入,这将使这工作?

Bokeh的python和R实现都使用了核心咖啡/ JS库,因此怀疑这个问题与两者都相关。

1 个答案:

答案 0 :(得分:1)

通过散景社区的一些指示,确定了解决方案。我希望将来可以添加它作为一个选项,以避免编写(有点脆弱)JS代码。

以下是解决方案:

yrange.callback <- function (var, margin=0.15)
{    
    code <- sprintf ("
        var plot = cb_obj.plots[0];

        var data = %s_data.get('data');
        var x = data['x'];
        var y = data['y'];

        var Xstart = plot.x_range.start;
        var Xend = plot.x_range.end;

        function sGE (e) { return e >= Xstart; } 
        function eGE (e) { return e >= Xend; } 
        function fixstart (i) { return i >= 0 ? i : x.length - 20; } 
        function fixend (i) { return i > 0 ? i : x.length - 1; } 

        var Istart = fixstart(x.findIndex(sGE))
        var Iend = fixend(x.findIndex(eGE))

        var yview = y.slice(Istart, Iend+1);
        var ymin = Math.min(...yview);
        var ymax = Math.max(...yview);
        var dy = ymax - ymin;

        var margin = %f * dy;
        cb_obj.start = ymin - margin;
        cb_obj.end = ymax + margin;", var, margin)

    custom_callback(code, lnames=var)
}

x <- seq(as.Date('2010-1-1'), as.Date('2017-1-1'), by='days')
len <- NROW(x)
y <- (1:len) * 5e-2 + rnorm(len, sd=10)

## render
range <- c(x[1], x[200])

figure(width=800,height=300, xlim=range) %>%
    ly_lines (x, y, lname = "points", lgroup='g1') %>%
    y_range(callback = yrange.callback('points'))

我必须将此附加到r_range回调而不是x_range回调,因为x_range回调上的cb_obj将是x_range对象,因此将事件回调放在上面y_range提供了y范围对象以进行修改。我无法确定一种方法来修改绘图对象上的y_range,以便更新。