【问题标题】:Issue when updating plots in Bokeh在 Bokeh 中更新绘图时的问题
【发布时间】:2019-11-25 23:14:43
【问题描述】:

所以我又一次在 Bokeh 上苦苦挣扎,这次是来自 Select-menu 的 callbacks...

下面是一个包含分类数据的工作示例。绘图工作正常,但是当尝试更改类别(来自Select 对象)时,什么也没有发生!我真的不明白我在这里做错了什么......

import pandas as pd
import math
import numpy as np

from bokeh.models import ColumnDataSource, FactorRange, Select
from bokeh.transform import factor_cmap
from bokeh.plotting import figure, show
from bokeh.palettes import Spectral5
from bokeh.layouts import layout, widgetbox

import random

""" Coloring based on universe """
index_cmap = factor_cmap('x', palette=Spectral5, factors=['Universe_1', 'Universe_2'], start=1)

universe_list = []
category_list_1 = []
category_list_2 = []
category_dependence = {'a' : ['A', 'B', 'C', 'D'], 'b' : ['E', 'F', 'G', 'H'], 'c' : ['I', 'J', 'K', 'L']}

N = 20

for x in range(N):
    universe_list.append(random.choice(['Universe_1', 'Universe_2']))
    category_list_1.append(random.choice(['a', 'b', 'c']))
    # Category 2 is dependent on Category 1
    category_list_2.append(random.choice(category_dependence[category_list_1[-1]]))

data = pd.DataFrame({'X' : category_list_1, 'Y' : category_list_2, 'Z' : np.random.randint(0,N,size=(N, 1)).flatten().tolist(), 'W' : universe_list})
data = data.drop_duplicates(subset=['X','Y','W'])

# Dropdown choices
dropdown_choices = sorted(data['X'].drop_duplicates().tolist())
menu_dropdown = Select(title="Category", options=dropdown_choices, value='a')

def select_category():

    val = menu_dropdown.value 
    selected = data.copy()

    return selected[selected.X.str.contains(val)==True]

def create_plot():

    df_ = select_category()

    x = zip(df_['Y'], df_['W'])
    y = df_['Z'].values
    legend = df_['W'].tolist()

    """ Create new figure... """
    p = figure(x_range=FactorRange(*x), y_range=(0.0, round(y.max()*1.1,0)), plot_height=500, plot_width=800, title='Some fancy title...', toolbar_location=None, tools="hover")
    p.x_range.range_padding = 0.1
    p.xaxis.major_label_orientation = math.pi/3
    p.xaxis.major_label_text_font_size = "0pt"
    p.xgrid.grid_line_color = None

    plot_source = ColumnDataSource(data=dict(x=x, top=y, legend=legend))
    p.vbar(x='x', top='top', width=0.9, source=plot_source, line_color="white", legend='legend', fill_color=index_cmap)

    return p

def update():
    l.children[1] = create_plot()  

controls = [menu_dropdown]
for control in controls:
    control.on_change('value', lambda attr, old, new: update)

inputs = widgetbox(*controls, sizing_mode='fixed')
l = layout([inputs, create_plot()], sizing_mode='fixed') 
show(l)

对于上面的代码,我想在用户每次更改 Select 对象时创建一个新图,因为 x-/y 轴和所有类别都会不同 - 而不是仅仅更改plot_source(对或错...)。

任何帮助将不胜感激...

【问题讨论】:

  • 您正尝试在回调中运行真正的 Python 代码。这将需要创建和running a Bokeh Server Application,而不是您在上面创建的独立(纯 HTML+JS)文档。在事件上运行真正的 python 代码是 Bokeh Server 的目的。浏览器没有 Python 的概念或运行 Python 代码的能力。
  • @bigreddot 公平点。但是,我似乎仍然无法运行它,即使我添加“from bokeh.plotting import curdoc”,用“curdoc().add_root(l)”替换我的“show(l)”并运行服务器为“bokeh serve --show categories.py”。这方面的线索?

标签: python pandas bokeh


【解决方案1】:

您实际上并没有在 lambda 中调用您的 update 函数。这一行:

control.on_change('value', lambda attr, old, new: update)

应该是这样的:

control.on_change('value', lambda attr, old, new: update())

尽管我会提到版本0.12.14(今天发布),它也应该可以更新现有地块上的数据和因素,而不是批量替换地块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多