简体   繁体   English

改变散景片上的颜色实时绘制

[英]Changing colors on bokeh patches plot real time

I'm trying to create a bokeh plot of the US States, and color each of the state according to some data. 我正在尝试创建美国各州的散景图,并根据一些数据为每个州着色。 Now using this tutorial I managed to create this, but I also want to enhance it, and add a slider to it, to change the values displayed. 现在使用这个教程我设法创建了这个,但我也想要增强它,并添加一个滑块,以更改显示的值。 For example like displaying separate years. 例如,显示单独的年份。

With the help of this tutorial, I managed to add the slider, and the underlying data does change, according to the hover text, but the colors aren't recalculated, and so the visual representation does not match the values. 教程的帮助下,我设法添加了滑块,根据悬停文本,底层数据确实发生了变化,但颜色没有重新计算,因此可视化表示与值不匹配。

This is the code I've used, from a Jupyter notebook, so anybody who wants to try can reproduce 这是我使用的代码,来自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)

Sample images of the plot: 情节的样本图片: 第一个可视化 第二次可视化

What I would like to accomplish, is that when I change the slider, the colors on the plot should change. 我想要完成的是,当我更改滑块时,绘图上的颜色应该改变。 Now I think the JS callback should call some kind of redraw or recalculate, but I haven't found any documentation about it. 现在我认为JS回调应该调用某种重绘或重新计算,但我还没有找到任何关于它的文档。 Is there a way to do this? 有没有办法做到这一点?

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

Appending source.trigger("change"); 附加source.trigger("change"); to the CustomJS seems to solve the problem, now as the slider changes, the colors change. 到CustomJS似乎解决了问题,现在当滑块改变时,颜色会发生变化。

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

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