gpt4 book ai didi

python - 简单的 Bokeh 应用程序 : Chart does not update as expected

转载 作者:行者123 更新时间:2023-12-01 03:24:53 25 4
gpt4 key购买 nike

所以我一直在尝试从 Bokeh 示例中构建一些东西:

https://demo.bokeh.org/weather .

我的数据集非常相似,这应该非常简单,但我有一个无法解释的问题。

import os , pickle
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource, Select
from bokeh.plotting import figure


base_path = '/Users/xxxxxx/Desktop/data/'
domain = 'IEM_Domain'
metric = 'total_area_burned'

def get_dataset(dic , selection , scenario):
def _get_mean(thing):
_df = pd.DataFrame(thing)
_df = _df.mean(axis = 1).cumsum(axis=0)
return _df

data = { model : _get_mean( dic[model] ) for model in dic.keys() if all([scenario in model , selection in model])}
df = pd.DataFrame(data)

return ColumnDataSource(data=df)

def make_plot(source, title):
plot = figure(x_axis_type="datetime", plot_width=800, tools="")
plot.title.text = title

for _df in source :
for col in _df.to_df().columns :
if 'index' not in col :
plot.line( _df.to_df()['index'] , _df.to_df()[col] , source = _df)
else : pass

# fixed attributes
plot.xaxis.axis_label = 'Year'
plot.yaxis.axis_label = "Area burned (km)"
plot.axis.axis_label_text_font_style = "bold"

return plot

def update_plot(attrname, old, new):
rcp45 = rcp45_select.value
rcp85 = rcp85_select.value

src45 = get_dataset(dic , rcp45 , 'rcp45')
src85 = get_dataset(dic , rcp85 , 'rcp85')

source45.data = src45.data
source85.data = src85.data


rcp45 = 'CCSM4_rcp45'
rcp85 = 'CCSM4_rcp85'

dic = pickle.load(open(os.path.join(base_path , "_".join([domain , metric ]) + '.p'), 'rb'),encoding='latin1')

rcp45_models = [ i for i in dic.keys() if 'rcp45' in i]
rcp85_models = [ i for i in dic.keys() if 'rcp85' in i]

rcp45_select = Select(value=rcp45, title='RCP 45', options=sorted(rcp45_models))
rcp85_select = Select(value=rcp85, title='RCP 85', options=sorted(rcp85_models))

source45 = get_dataset(dic , rcp45 , 'rcp45')
source85 = get_dataset(dic , rcp85 ,'rcp85')
print(source45.data)
plot = make_plot([source45 , source85], "Total area burned ")

rcp45_select.on_change('value', update_plot)
rcp85_select.on_change('value', update_plot)

controls = column(rcp45_select, rcp85_select)

curdoc().add_root(row(plot, controls))
curdoc().title = "Total Area burned"

一切都会运行 find ,直到我尝试更改下拉列表中的值,我可以看到函数 update_plot() 正在完成这项工作,在使用下拉列表时更新数据。但由于某种原因,情节没有改变,但该示例运行良好。我一直在代码中到处挖掘,但似乎找不到我做错了什么。

我试图简化 make_plot() 以查看它是否可以来自那里,但这并没有改变任何东西,所以我没有想法。

我发现了但无法应用它:Bokeh: chart from pandas dataframe won't update on trigger

第一个回答后进行编辑

我尝试摆脱列数据源并将其替换为传统字典,但仍然遇到相同的问题。这是更新后的代码:

import os , pickle
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource, Select
from bokeh.plotting import figure


base_path = '/Users/julienschroder/Desktop/data/'
domain = 'IEM_Domain'
metric = 'total_area_burned'
scenarios = ['rcp45','rcp85']


def get_dataset(dic ,selection , scenario = scenarios):
#function taking the raw source as dic and a selection of models, it return a dictionnary
# like this {scenario : pd.Dataframe(models)} that way i can plot each scenario on their own

def _get_mean_cumsum(df ,name):
#Extract, average and cumsum the raw data to a dataframe
_df = pd.DataFrame(df)
_df = _df.mean(axis = 1).cumsum(axis=0)
_df = _df.to_frame(name=name)
return _df

#Just one model at a time for now but hoping to get multilines and so multi models in the future
data = { scenario : pd.concat([_get_mean_cumsum(dic[model] , model) for model in selection if scenario in model ] ,axis=1) for scenario in scenarios }

return data

def make_plot(source, title):
plot = figure(x_axis_type="datetime", plot_width=800, tools="")
plot.title.text = title
#for now it will just deal with one model at a time but in the future I hope to have some multiline plotting hence the for loops
for col in source['rcp45']:
plot.line(source['rcp45'].index,source['rcp45'][col] )

for col in source['rcp85']:
plot.line(source['rcp85'].index , source['rcp85'][col])

# fixed attributes
plot.xaxis.axis_label = 'Year'
plot.yaxis.axis_label = "Area burned (km)"
plot.axis.axis_label_text_font_style = "bold"

return plot

def update_plot(attrname, old, new):
rcp45 = rcp45_select.value
rcp85 = rcp85_select.value

source = get_dataset(dic,[rcp45 ,rcp85])

#check to see if source gets updated
print(source) # <- gets updated properly after dropdown action

rcp45 = 'CCSM4_rcp45'
rcp85 = 'CCSM4_rcp85'

# dic = pickle.load(open(os.path.join(base_path , "_".join([domain , metric ]) + '.p'), 'rb'),encoding='latin1')

dic = pickle.load(open('IEM_Domain_total_area_burned.p', 'rb'),encoding='latin1') #data available there : https://github.com/julienschroder/Bokeh_app/tree/master/1

rcp45_models = [ i for i in dic.keys() if 'rcp45' in i]
rcp85_models = [ i for i in dic.keys() if 'rcp85' in i]

rcp45_select = Select(value=rcp45, title='RCP 45', options=sorted(rcp45_models))
rcp85_select = Select(value=rcp85, title='RCP 85', options=sorted(rcp85_models))

source = get_dataset(dic,[rcp45 ,rcp85])

plot = make_plot(source , "Total area burned ")

rcp45_select.on_change('value', update_plot)
rcp85_select.on_change('value', update_plot)

controls = column(rcp45_select, rcp85_select)

curdoc().add_root(row(plot, controls))
curdoc().title = "Total Area burned"

我得到了前两行,但使用下拉菜单时没有任何反应。如果有人想尝试这些数据,我在此 github 页面上上传了一个较小的数据集 https://github.com/julienschroder/Bokeh_app/tree/master/1

最佳答案

嗯,我不能 100% 肯定地说,因为没有数据我就无法运行代码,但我很清楚问题可能是什么。 .data 属性 ColumnDataSource 实际上并不是一个简单的 Python 字典:

In [4]: s = ColumnDataSource(data=dict(a=[1,2], b=[3,4]))

In [5]: type(s.data)
Out[5]: bokeh.core.property.containers.PropertyValueDict

它实际上是一个特殊包装的字典,当其内容发生更改时可以自动发出事件通知。这是让 Bokeh 以如此方便的方式自动响应和更新内容的机制的一部分。我猜测通过使用另一个源的 .data 设置一个源的 .data 是导致问题的原因。我假设使用真正的 Python 字典之外的其他内容设置 .data 可以防止事件处理程序无法正确连接。

因此,建议立即采取解决方法:不要在 get_dataset 中构造 ColumnDataSource。只构造并返回一个普通的 Python 字典。 df.to_dict 可能会为您提供完全正确的字典类型。或者您可以手动制作一个字典,放入您需要的列。

还有一个请求:这个限制有可能得到解决。或者如果没有,如果用户这样做,当然可能会发出响亮的警告。请在 GitHub issue tracker 上提交错误报告包含所有这些信息。

关于python - 简单的 Bokeh 应用程序 : Chart does not update as expected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41476781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com