散景MultiSelect绘制无限循环,扭曲绘图

时间:2017-01-30 04:49:29

标签: loops multi-select bokeh infinite

我试图根据用户" MultiSelect"将多行绘制到图表中。选项。我读了两个单独的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"

2 个答案:

答案 0 :(得分:0)

我不是100%肯定,因为上面的代码不是自包含的,无法运行和调查,但是有一些问题(截至Bokeh 0.12.4)并添加 new 在某些情况下文档的组件存在问题。这些问题在下两个版本的优先级列表中占据重要位置。

数据大小是否合理,您可以预先创建所有组合?如果是这样,我建议这样做,然后使用多选值可以适当地切换可见性。例如,这是一个使用复选框的类似示例:

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)

如果数据大小,您可以预先创建所有组合,那么我建议您在project issue tracker https://github.com/bokeh/bokeh/issues)上创建一个问题完整的,最小的,自包含的,可运行的原始代码来重现问题(即生成随机或合成数据,但在其他方面相同)。这是帮助核心开发者更迅速地解决问题的头号事。

答案 1 :(得分:0)

@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"