Python 更改bokeh面片上的颜色实时打印

Python 更改bokeh面片上的颜色实时打印,python,bokeh,Python,Bokeh,我试图创建一个美国各州的bokeh图,并根据一些数据给每个州涂上颜色。现在使用教程我成功地创建了它,但我还想增强它,并添加一个滑块,以更改显示的值。例如,显示不同的年份 在教程的帮助下,我成功地添加了滑块,基础数据确实会根据悬停文本发生变化,但颜色不会重新计算,因此视觉表示与值不匹配 这是我在Jupyter笔记本上使用的代码,所以任何想尝试的人都可以复制 from bokeh.io import show, output_notebook from bokeh.models import (

我试图创建一个美国各州的bokeh图,并根据一些数据给每个州涂上颜色。现在使用教程我成功地创建了它,但我还想增强它,并添加一个滑块,以更改显示的值。例如,显示不同的年份

在教程的帮助下,我成功地添加了滑块,基础数据确实会根据悬停文本发生变化,但颜色不会重新计算,因此视觉表示与值不匹配

这是我在Jupyter笔记本上使用的代码,所以任何想尝试的人都可以复制

from bokeh.io import show, output_notebook
from bokeh.models import (
    ColumnDataSource,
    HoverTool,
    LogColorMapper,
    Range1d, CustomJS, Slider
)
from bokeh.palettes import Inferno256 as palette
from bokeh.plotting import figure

from bokeh.layouts import row, widgetbox

from bokeh.sampledata.us_counties import data as counties
from bokeh.sampledata.us_states import data as states
from bokeh.sampledata.unemployment import data as unemployment
import pandas as pd
import random
output_notebook()
palette.reverse()

states_accumulated ={}
available_state_codes = states.keys()

for key, value in counties.items():
    state_name = value["state"].upper()
    if state_name in states.keys() and "number" not in states[state_name]:
        states[state_name]["number"] = key[0]

for key,state in states.items():
    state["code"] = key

state_list = []

for key,state in states.items():
    state_list.append(state)

unemployment_transf = []
for key,value in unemployment.items():
    unemployment_transf.append({
        "State":key[0],
        "County":key[1],
        "Value":value
    })
unemp_df = pd.DataFrame(unemployment_transf)
unemp_sum = unemp_df.groupby("State").mean()["Value"]
unemp_sum = unemp_sum.sort_index()

unemp_sum_flat = {key:value for key, value in unemp_sum.items()}

for state in state_list:
    state["value"] = unemp_sum_flat[state["number"]]
state_df = pd.DataFrame(state_list)
color_mapper = LogColorMapper(palette=palette)

state_xy = (list(state_df["lons"].values),list(state_df["lats"].values))

max_x = max([max(l) for l in state_xy[0]])
max_y = max([max(l) for l in state_xy[1]])
min_x = min([min(l) for l in state_xy[0]])
min_y = min([min(l) for l in state_xy[1]])

data=dict(
    x=state_xy[0],
    y=state_xy[1],
    name=list(state_df["name"].values),
    used = list(state_df["value"].values)
)

data['1999'] = list(state_df["value"].values)
data['2000'] = [random.randrange(0,10) for i in range(len(state_xy[0]))]
source = ColumnDataSource(data)

TOOLS = "pan,wheel_zoom,reset,hover,save"

p = figure(
    title="States", tools=TOOLS,
    x_axis_location=None, y_axis_location=None
)
p.width=450
p.height = 450
p.x_range= Range1d(-170,-60)
p.y_range = Range1d(min_y-10,max_y+10)
p.grid.grid_line_color = None

renderer = p.patches('x', 'y', source=source,
          fill_color={'field': 'used', 'transform': color_mapper},
          fill_alpha=0.7, line_color="white", line_width=0.5)


hover = p.select_one(HoverTool)
hover.point_policy = "follow_mouse"
hover.tooltips = [
    ("Name", "@name"),
    ("Unemployment rate)", "@used%"),
    ("(Long, Lat)", "($x, $y)"),
]

callback = CustomJS(args=dict(source=source,plot=p,color_mapper = color_mapper,renderer = renderer), code="""
    var data = source.data;
    var year = year.value;
    used = data['used']
    should_be = data[String(year)]
    for (i = 0; i < should_be.length; i++) {
        used[i] = should_be[i];
    } 
""")


year_slider = Slider(start=1999, end=2000, value=1999, step=1,
                    title="year", callback=callback)
callback.args["year"] = year_slider

layout = row(
    p,
    widgetbox(year_slider),
)
show(layout)
从bokeh.io导入显示,输出\u笔记本
从bokeh.models导入(
ColumnDataSource,
悬停工具,
LogColorMapper,
范围1D、自定义JS、滑块
)
从bokeh.paletes导入Inferno256作为调色板
从bokeh.plotting导入图形
从bokeh.layouts导入行,widgetbox
从bokeh.sampledata.us_countries将数据导入为countries
从bokeh.sampledata.us_states将数据作为状态导入
从bokeh.sampledata.demission导入数据作为失业
作为pd进口熊猫
随机输入
输出_笔记本()
palete.reverse()
州_累计={}
可用状态代码=状态。键()
对于键,以县为单位的值。项()
state_name=值[“state”]。上限()
如果state\u name在states.keys()中,而“number”不在states[state\u name]中:
状态[状态名称][“编号”]=键[0]
对于键,状态为states.items():
状态[“代码”]=键
state_list=[]
对于键,状态为states.items():
state\u list.append(状态)
失业率_transf=[]
对于键,失业率中的值。项()
失业率({
“状态”:键[0],
“县”:键[1],
“价值”:价值
})
unemp_df=pd.DataFrame(失业率转换)
unemp_sum=unemp_df.groupby(“State”).mean()[“Value”]
unemp\u sum=unemp\u sum.sort\u index()
unemp_sum_flat={key:key的值,unemp_sum.items()中的值]
对于状态列表中的状态:
状态[“值”]=unemp_sum_flat[状态[“数字”]]
state_df=pd.DataFrame(state_列表)
颜色映射器=对数颜色映射器(调色板=调色板)
state_xy=(列表(state_df[“lons”]值),列表(state_df[“lats”]值))
max_x=max([max(l)表示处于状态的l_xy[0]]))
max_y=max([max(l)表示处于状态的l_xy[1]]))
min_x=min([min(l)表示处于状态_xy[0]]))
min_y=min([min(l)表示处于状态_xy[1]]))
数据=dict(
x=状态_xy[0],
y=状态_xy[1],
名称=列表(状态_df[“名称”].值),
已使用=列表(状态为[value].值)
)
数据['1999']=列表(状态[值]。值)
数据['2000']=[random.randrange(0,10)表示范围内的i(len(state_xy[0])]
source=ColumnDataSource(数据)
TOOLS=“平移、滚轮\缩放、重置、悬停、保存”
p=数字(
title=“States”,tools=工具,
x_轴位置=无,y_轴位置=无
)
p、 宽度=450
p、 高度=450
p、 x_范围=范围1d(-170,-60)
p、 y_范围=范围1D(最小y-10,最大y+10)
p、 grid.grid\u line\u color=无
渲染器=p.patches('x','y',源=源,
填充颜色={'field':'used','transform':颜色映射器},
填充字母=0.7,线条颜色=白色,线条宽度=0.5)
悬停=p。选择一个(悬停工具)
hover.point\u policy=“跟随鼠标”
hover.tooltips=[
(“名称”、“名称”),
(“失业率)”,“@used%”,
(""长,长","(x元,y元),,
]
callback=CustomJS(args=dict(source=source,plot=p,color\u mapper=color\u mapper,renderer=renderer),code=”“”
var数据=source.data;
var年=年值;
已使用=数据[“已使用”]
应为=数据[字符串(年)]
对于(i=0;i
绘图的示例图像:


我想完成的是,当我改变滑块时,绘图上的颜色应该改变。现在我认为JS回调应该调用某种重画或重新计算,但我还没有找到任何关于它的文档。有办法吗?

source.change.emit()
附加到Javascipt代码以触发更改事件。

附加
source.trigger(“更改”)
到CustomJS似乎解决了这个问题,现在随着滑块的改变,颜色也会改变。

对我来说,
source.change.emit()
什么都不做,在JS控制台中,我得到一个错误,说
TypeError:source.change未定义,尽管使用了
source.trigger(“更改”)
似乎解决了这个问题。@Brabulla您的bokeh版本很旧,如果更新到最新版本,您需要将
source.trigger('change')
更改为
source.change.emit()
。谢谢,更新解决了这个问题,我使用的是0.12.7,现在我已经更新到了0.12.11,它开始工作了。