首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用全局ColumnDataSource时替换布局中的图形和表

在使用全局ColumnDataSource时替换布局中的图形和表
EN

Stack Overflow用户
提问于 2017-10-11 21:29:42
回答 1查看 791关注 0票数 0

我使用的是bokeh 0.12.9。在回调的全局布局中,我有一个表和一个图形。我通常在构建新的图/表之前构建ColumnDataSource。现在,我想看看是否可以拥有一个全局ColumnDataSource,这样我就可以通过一个CDSView来调整数据(那时不需要替换表/图)。

不幸的是,即使为表和绘图保留单独的CDS和视图也会失败。当单击单选按钮几次时,我收到以下javascript错误:Uncaught TypeError: Cannot read property 'data' of undefined

代码语言:javascript
复制
from datetime import date
from random import randint

from bokeh.models import Line
import numpy as np
import pandas as pd

from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
import bokeh.layouts as layouts
import bokeh.models.widgets as widgets
from bokeh.io import curdoc
from bokeh.models import CustomJS, Slider
from bokeh import palettes
from bokeh.layouts import layout
from bokeh.models import ColumnDataSource, CDSView, IndexFilter
from bokeh.models import widgets


def gen_plot(source=None, view=None):
    p = figure(title='test',
               x_axis_type="datetime",
               plot_width=600, plot_height=400)
    colors = palettes.Category10[10]
    cols = [str(col) for col in source.column_names]
    for ix, col in enumerate(cols):
        if col == 'index':
            continue
        r = p.line(x='index', y=col, source=source, view=view,
                   legend='_' + col,
                   color=colors[ix])
    p.legend.location = "bottom_left"
    return p


def gen_table(source=None, view=None):
    columns = [TableColumn(field=ele, title=ele) for ele
               in source.column_names]
    tab = widgets.DataTable(source=source, view=view, columns=columns,
                            selectable=False,
                            reorderable=False,
                            width=600, height=400)
    return tab



def update(attr, old, new):
    p = gen_plot(source=cdss[0], view=vs[0])
    t = gen_table(source=cdss[1], view=vs[1])

    print l.children
    l.children[1] = p
    l.children[2].children[0] = t


# set up data
cols = ['col1', 'col2', 'col3', 'col4']
df1 = pd.DataFrame(pd.util.testing.getTimeSeriesData())
df1.columns = cols
df2 = pd.DataFrame(pd.util.testing.getTimeSeriesData())
df2.columns = cols
dfs = [df1, df2]
cds1 = ColumnDataSource(df1)
cds2 = ColumnDataSource(df2)
cdss = [cds1, cds2]
filters = [IndexFilter([0, 1, 2, 4])]
filters = []
v1 = CDSView(source=cds1, filters=filters)
v2 = CDSView(source=cds2, filters=filters)
vs = [v1, v2]


# initialize items to replace
p = gen_plot(source=cdss[0], view=vs[0])
t = gen_table(source=cdss[1], view=vs[1])

# initialize controls
radio_wghting = widgets.RadioButtonGroup(labels=["Equal", "Exponential"],
                                         active=0)
radio_wghting.on_change('active', update)

# set up layout
sizing_mode = 'fixed'
l = layout([radio_wghting, p, t], sizing_mode=sizing_mode)

curdoc().add_root(l)
curdoc().title = 'blub'


# call callback initially
update('value', 0, 0)

任何提示都非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-12 15:19:30

现在,我想看看是否可以拥有一个全局ColumnDataSource,这样我就可以通过一个CDSView来调整数据(那时不需要替换表/图)。

正在显示的代码是试图替换图形和表的代码。

当以这种方式替换布局对象的子对象时,实际上并不是从curdoc中删除以前的数字,而且文档中的其他元素的引用中仍然有旧的数字和表。

您可以尝试这样的方法来直接更新源。

代码语言:javascript
复制
for rend in p.renderers:
    try:
        rend.data_source
    except AttributeError:
        pass
    else:
        rend.data_source.data.update(new_data_dictionary)

代码语言:javascript
复制
t.source.data.update(new_data_dictionary)

编辑以回答评论

代码语言:javascript
复制
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, Button
from bokeh.layouts import gridplot, widgetbox

from random import random, choice

import numpy as np

my_data = {1:{'x':[],'y':[],'colo':[],'size':[]}}

kelly_colors = [    '#F3C300','#875692', '#F38400', '#A1CAF1','#BE0032', '#C2B280', '#848482','#008856', '#E68FAC', '#0067A5',
                    '#F99379', '#604E97', '#F6A600','#B3446C', '#DCD300', '#882D17','#8DB600', '#654522', '#E25822','#2B3D26',      ]

x = np.arange(0,50,0.1)

def rand_dict():

    rand_x = [choice(x) for i in range(7)]

    return {'x':rand_x,'y':np.array([random()*100 for i in rand_x]),'colo':np.array([choice(kelly_colors) for i in rand_x]),'size':np.array([(5+int(random()*50)) for i in rand_x])}

def add_stuff():

    global my_data

    my_data[max(my_data.keys())+1] = rand_dict()

    make_doc()

def change_stuff():

    global my_data

    myfig = curdoc().select_one({"name":"myfig"})

    for i,rend in enumerate(myfig.renderers):
        try:
            rend.data_source
        except AttributeError:
            pass
        else:
            my_data[i+1] = rand_dict()
            rend.data_source.data.update(my_data[i+1])

def clear_stuff():

    global my_data

    my_data = {1:{'x':[],'y':[],'colo':[],'size':[]}}

    make_doc()

def make_doc():

    curdoc().clear()

    myfig = figure(plot_width=1000,plot_height=800,outline_line_alpha=0,name='myfig')
    myfig.x_range.start = -5
    myfig.x_range.end = 55
    myfig.y_range.start = -10
    myfig.y_range.end = 110

    myfig.renderers = []

    add_button = Button(label='add stuff',width=100)
    change_button = Button(label='change stuff',width=100)
    clear_button = Button(label='clear stuff',width=100)

    add_button.on_click(add_stuff)
    change_button.on_click(change_stuff)
    clear_button.on_click(clear_stuff)

    grid = gridplot([[myfig,widgetbox(add_button,change_button,clear_button)]],toolbar_location=None)

    curdoc().add_root(grid)

    update_doc()

def update_doc():

    myfig = curdoc().select_one({"name":"myfig"})

    for key in my_data:
        myfig.scatter(x='x',y='y',color='colo',size='size',source=ColumnDataSource(data=my_data[key]))

curdoc().title = 'mytitle'

make_doc()

我喜欢这样做的是,您只需保存带有numpy的my_data字典,稍后加载它,然后继续从那里更改绘图。

代码语言:javascript
复制
def load_data():

    global my_data

    my_data = np.load(path_to_saved_data).item()

    make_doc()

你也许可以用熊猫的数据来做类似的事情,我只是对普通的字典比较满意。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46697867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档