【问题标题】:How to update a ColumnDataSource data for a MultiLine glyph?如何更新多行字形的 ColumnDataSource 数据?
【发布时间】:2016-04-19 06:17:21
【问题描述】:

我正在尝试创建一个绘制多个时间序列的 Bokeh 应用程序,并允许用户使用 CheckboxButtonGroup 小部件选择时间序列的子集。我想从 python 更改显示的图形,而不是尝试在 javascript 端隐藏/取消隐藏行。我试图通过添加多行并从回调函数更改其数据源中的值来做到这一点。当我更改时间序列的内容或删除时间序列时,这可以正常工作,但是一旦我尝试将时间序列添加到多行,我在 javascript 端(chrome控制台打印Bokeh: Error handling message)。

具体来说,我有一个带有 data 列的 pandas 数据框,该列由存储桶名称和时间戳索引:

data = pandas.DataFrame(...)
buckets = data.index.levels[0]
timestamps = data.index.levels[1]

我有一个多线图和一个控件:

plot = bokeh.plotting.Figure(x_axis_type = "datetime")
multiline = plot.multi_line(xs = [], ys = [])
bucketsControl = bokeh.models.widgets.CheckboxButtonGroup(labels = list(buckets))

而且我有一个回调函数,更新数据源,由控件触发:

def update(value):
    xs = []
    ys = []
    for bucketIndex in bucketsControl.active:
        bucketName = bucketsControl.labels[bucketIndex]
        bucketData = data.loc[bucketName]
        series = bucketData["data"]
    xs.append(series.index.values)
    ys.append(series.values)
    multiline.data_source.data["xs"] = xs
    multiline.data_source.data["ys"] = ys

bucketsControl.on_click(update)

我不确定是什么导致了这里的问题,但是当我尝试添加另一个时间序列时,我查看了 Bokeh 服务器和 Web 浏览器之间的 Web 套接字流量,并且我看到它导致两个ModelChanged 更新:第一个将另一个列表添加到xs,第二个将一个列表添加到ys。我怀疑 BokehJS 客户端无法处理第一次更新,其中 x 系列比 y 系列多一个。

有没有办法让这个多行更新工作?或者,是否有另一种方法可以从 python 更新绘图的结构(例如,向绘图添加一个全新的线,而不是更改现有字形的数据源)?

【问题讨论】:

    标签: javascript python python-3.x bokeh multiline


    【解决方案1】:

    因为您更新了数据源两次。您只能通过以下方式更新一次:

    data = dict(xs=xs, ys=ys)
    multiline.data_source.data = data
    

    【讨论】:

      【解决方案2】:

      您可以使用patch 仅更新新数据,最大限度地减少要发送到前端的数据

      • 更新整行:

        source = ColumnDataSource(dict(
            xs=[[1, 2, 3, 4, 5, 6]],
            ys=[[1, 2, 3, 4.2, 2.2, 0.5]],
        ))
        source.patch({
            'ys' : [(0, [1, 2, 3, 4, 5, 6])]
        })
        
      • 要更新行片段:

        source = ColumnDataSource(dict(
            xs=[np.array([1, 2, 3, 4, 5, 6])],
            ys=[np.array([1, 2, 3, 4.2, 2.2, 0.5])],
        ))
        source.patch({
            'ys' : [([0, slice(3, 6)], np.array([4, 5, 6]))]
        })
        
      • 有一种方法可以去除整体,因为散景不支持这种方法

        source.patch({
            'ys' : [(0,[''])],     # or 'ys' : [(0,numpy.array([numpy.nan]))], 
        })
        

      另外,您可以同时更新许多列,只需将键添加到补丁字典

      【讨论】:

        猜你喜欢
        • 2021-06-04
        • 2015-04-20
        • 2021-06-09
        • 1970-01-01
        • 2021-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多