Bokeh多选在无限循环中打印,扭曲打印



我正试图根据用户的"多选"选项将多条线绘制到一个图中。我读入了两个独立的excel数据文件,并根据用户的要求绘制了它们的轴。我使用的是Python 3.5,并且运行在MAC上。

1) 。一旦我进行了多重选择,图形就会失真

2) 。情节似乎在无限循环中运行。

3) 。当用户更改选择时,绘图剂量不会正确更新。它只是添加了更多的绘图,而没有删除以前的绘图。

from os.path import dirname, join
from pandas import *
import numpy as np
import pandas.io.sql as psql
import sqlite3 as sql
import sys, os
from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource, HoverTool, Div
from bokeh.models.widgets import Slider, Select, TextInput, MultiSelect
from bokeh.io import curdoc
import matplotlib.pyplot as plt
files = list()
path = os.getcwd()
for x in os.listdir(path):
if x.endswith(".xlsx"):
if x != 'template.xlsx' :
files.append(x)
axis_map = {
"0% void": "0% void",
"40% void": "40% void",
"70% void": "70% void",
}

files_list = MultiSelect(title="Files", value=["dummy2.xlsx"],       
options=open(join(dirname(__file__), 'files.txt')).read().split())
voids = MultiSelect(title="At what void[s]", value=["0% void"], options=sorted(axis_map.keys()))
p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None)
pline = figure(plot_height=600, plot_width=700, title="")
path = os.getcwd()
data_dict = {}
for file in os.listdir(path):
if file.endswith(".xlsx"):
xls = ExcelFile(file)
df = xls.parse(xls.sheet_names[0])
data = df.to_dict()
data_dict[file] = data

# converting dictionary  to dataframe
newdict = {(k1, k2):v2 for k1,v1 in data_dict.items() 
for k2,v2 in data_dict[k1].items()}
xxs = DataFrame([newdict[i] for i in sorted(newdict)],
index=MultiIndex.from_tuples([i for i in  sorted(newdict.keys())]))  
master_data = xxs.transpose()
def select_data():
for vals in files_list.value:
for vox in voids.value:
pline.line(x=master_data[vals]['Burnup'], y=  master_data[vals][vox])
pline.circle(x=master_data[vals]['Burnup'], y=  master_data[vals][vox])
return 

def update():
select_data()
controls = [  files_list, voids]
for control in controls:
control.on_change('value', lambda attr, old, new: update())
sizing_mode = 'fixed'  # 'scale_width' also looks nice with this example
inputs = widgetbox(*controls, sizing_mode=sizing_mode)
l = layout([
[inputs, pline],
], sizing_mode=sizing_mode)
update()  
curdoc().add_root(l)
curdoc().title = "Calculations"

我不能100%确定,因为上面的代码不是自包含的,无法运行和调查,但在某些情况下,向文档中添加组件存在一些问题(截至Bokeh0.12.4)。这些问题是下一个两点发布的优先事项。

数据大小是否合理,以便您可以提前创建所有组合?如果是这样,我建议您这样做,然后让多选值适当地打开/关闭可见性。例如,这里有一个使用复选框的类似示例:

import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.palettes import Viridis3
from bokeh.plotting import figure
from bokeh.models import CheckboxGroup
p = figure()
props = dict(line_width=4, line_alpha=0.7)
x = np.linspace(0, 4 * np.pi, 100)
l0 = p.line(x, np.sin(x), color=Viridis3[0], legend="Line 0", **props)
l1 = p.line(x, 4 * np.cos(x), color=Viridis3[1], legend="Line 1", **props)
l2 = p.line(x, np.tan(x), color=Viridis3[2], legend="Line 2", **props)
checkbox = CheckboxGroup(labels=["Line 0", "Line 1", "Line 2"], active=[0, 1, 2], width=100)
def update(attr, old, new):
l0.visible = 0 in checkbox.active
l1.visible = 1 in checkbox.active
l2.visible = 2 in checkbox.active
checkbox.on_change('active', update)
layout = row(checkbox, p)
curdoc().add_root(layout)

如果数据大小是而不是,这样你就可以提前创建所有的组合,那么我建议在项目问题上做一个问题ckerhttps://github.com/bokeh/bokeh/issues)它有一个完整的、最小的、自包含的、可按原样运行的代码来重现问题(即生成随机或合成数据,但在其他方面是相同的)。这是帮助核心开发人员更迅速地解决问题的首要因素。

@bigreddot感谢您的回复。

我对代码进行了编辑,使其成为独立的代码。

1) 。绘图不会重置。新选定的绘图覆盖上一个绘图。

2) 。当用户进行多次选择(ctrl+shift)时,绘图轴会失真,并且似乎在无限循环中运行

from pandas import *
import numpy as np
import sys, os
from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models.widgets import MultiSelect
from bokeh.io import curdoc
from bokeh.plotting import reset_output
import math
axis_map = {
"y1": "y3",
"y2": "y2",
"y3": "y1",
}
x1 = np.linspace(0,20,62)
y1 = [1.26 * math.cos(x) for x in np.linspace(-1,1,62) ]
y2 = [1.26 * math.cos(x) for x in np.linspace(-0.95,.95,62) ]
y3 = [1.26 * math.cos(x) for x in np.linspace(-.9,.90,62) ]
TOOLS = "pan,wheel_zoom,box_zoom,reset,save,hover"
vars = MultiSelect(title="At what void[s]", value=["y1"], options=sorted(axis_map.keys()))
master_data = { 'rate' : x1, 
'y1'   : y1, 
'y2'   : y2,
'y3'   : y3             
}

p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None)
pline = figure(plot_height=600, plot_width=700, title="", tools=TOOLS)
def select_data():
for vox in vars.value:
pline.line(x=master_data['rate'], y= master_data[vox], line_width=2)
pline.circle(x=master_data['rate'], y=master_data[vox], line_width=2)
return 
controls = [  vars]
for control in controls:
control.on_change('value', lambda attr, old, new: select_data())
sizing_mode = 'fixed'  
inputs = widgetbox(*controls)
l = layout([
[inputs, pline],
])
select_data() 
curdoc().add_root(l)
curdoc().title = "Plot"

最新更新