简体   繁体   English

为什么我的散景服务器应用程序不会更新图形

[英]Why my bokeh server app won't update the figure

here's my data : https://drive.google.com/drive/folders/1CabmdDQucaKW2XhBxQlXVNOSiNRtkMm-?usp=sharing i want to use the select to choose the stock i want to show;这是我的数据: https://drive.google.com/drive/folders/1CabmdDQucaKW2XhBxQlXVNOSiNRtkMm-?usp=sharing我想用 select 来选择我想显示的股票and slider to choose the year range i want to show;和 slider 选择我要显示的年份范围; and checkboxgroup to choose the index i want to compare with.和 checkboxgroup 来选择我想要比较的索引。 the problem is when i adjust the slider, the figure will update, but when i use the select and checkboxgroup, the figure won't update, what's the reason?问题是当我调整slider时,图形会更新,但是当我使用select和checkboxgroup时,图形不会更新,是什么原因?

from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Slider, TextInput , Select , Div, CheckboxGroup
from bokeh.plotting import figure
import pandas as pd
import numpy as np

price=pd.read_excel('price.xlsx',index_col=0)
# input control

stock = Select(title='Stock',value='AAPL',options=[x for x in list(price.columns) if x not in ['S&P','DOW']])
yr_1 = Slider(title='Start year',value=2015,start=2000,end=2020,step=1)
yr_2 = Slider(title='End year',value=2020,start=2000,end=2020,step=1)
index = CheckboxGroup(labels=['S&P','DOW'],active=[0,1])

def get_data():
    compare_index = [index.labels[i] for i in index.active]
    stocks = stock.value
    start_year = str(yr_1.value)
    end_year = str(yr_2.value)

    select_list = []
    select_list.append(stocks)
    select_list.extend(compare_index)
    selected = price[select_list]
    selected = selected [start_year:end_year]
    for col in selected.columns:
        selected[col]=selected[col]/selected[col].dropna()[0]

    return ColumnDataSource(selected)

def make_plot(source):
    fig=figure(plot_height=600, plot_width=700, title="",sizing_mode="scale_both", x_axis_type="datetime")
    data_columns = list(source.data.keys())
    for data in data_columns[1:]:
        fig.line(x=data_columns[0],y=data,source=source,line_width=3, line_alpha=0.6, legend_label=data)
    return fig

def update(attrname, old, new):
    new_source = get_data()

    source.data.clear()
    source.data.update(new_source.data)


#get the initial value and plot
source = get_data()
plot = make_plot(source)

#control_update

stock.on_change('value', update)
yr_1.on_change('value', update)
yr_2.on_change('value', update)
index.on_change('active', update)


# Set up layouts and add to document
inputs = column(stock, yr_1, yr_2, index)

curdoc().add_root(row(inputs, plot, width=800))
curdoc().title = "Stocks"

You're creating a new ColumnDataSource for new data.您正在为新数据创建一个新的ColumnDataSource That's not a good approach.这不是一个好方法。 Instead, create it once and then just assign its data as appropriate.相反,创建一次,然后根据需要分配其data

In your case, I would do it like this:在你的情况下,我会这样做:

  1. Create ColumnDataSource just once, as described above如上所述,只创建一次ColumnDataSource
  2. Do not use .update on CDS, just reassign .data不要在 CDS 上使用.update ,只需重新分配.data
  3. Create the legend manually手动创建图例
  4. For that one line that's susceptible to the select change choose a static x field and use it everywhere instead对于易受 select 更改影响的那一行,选择 static x字段并在任何地方使用它
  5. Change the first legend item's label when you change the select's value to instead of that x field it has the correct name当您将选择的值更改为而不是x字段时,更改第一个图例项的 label 它具有正确的名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM