繁体   English   中英

Python:如何更新散景中的数据选择?

[英]Python: how to update data selection in bokeh?

我是使用bokeh新手。

这就是我在做的事情。 osmnx我获得海地学校和医院的数据。

没有编写我到达的所有代码来获得以下内容

data1=dict(
    x=list(schools['x'].values),
    y=list(schools['y'].values)
)

data2=dict(
    x=list(hospitals['x'].values),
    y=list(hospitals['y'].values)
)

building = 'Schools'

buildings = {
    'Schools': {
    'title': 'Schools',
    'data': data1,
    'color': 'black'
    },

    'Hospitals': {
    'title': 'Hospitals',
    'data': data2,
    'color': 'red'
    }
}

building_select = Select(value=building, title='Building', options=sorted(buildings.keys()))

我想通过选择它来改变学校和医院之间的可视化。 我定义了更改要采用的数据和颜色的函数。

def returnInfo(building):
    dataPoints = buildings[building]['data']
    color = buildings[building]['color']
    return dataPoints, color

dataPoints, color = returnInfo(building)

我定义了函数make_plot

def make_plot(dataPoints, title, color):

    TOOLS = "pan, wheel_zoom, reset,save"

    p = figure(plot_width=800,
           tools=TOOLS,
           x_axis_location=None, 
           y_axis_location=None)

# Add points on top (as black points)
    buildings = p.circle('x', 'y', size=4, source=data1, color=color)


    hover_buildings = HoverTool(renderers = [buildings], point_policy="follow_mouse", tooltips = [("(Long, Lat)", "($x, $y)")])

    p.add_tools(hover_buildings)

    return p

plot = make_plot(dataPoints,“Data for”+ buildings [building] ['title'],color)

然后我更新

def update_plot(attrname, old, new):
    building = building_select.value
    p.title.text = "Data for " + buildings[building]['title']
    src = buildings[building]['data']
    dataPoints, color = returnInfo(building)
    dataPoints.update

building_select.on_change('value', update_plot)

controls = column(building_select)
curdoc().add_root(row(plot, controls))

但它不起作用:即使我有光标,我也无法改变从学校到医院的积分。 更新部分中的错误在哪里?

作为第一个解决方案,我建议使用legend.click_plolicy = 'hide'来切换地图上建筑物的可见性(Bokeh v1.1.0)

from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show
from bokeh.tile_providers import CARTODBPOSITRON_RETINA
import osmnx as ox

amenities = ['hospital', 'school']
for i, amenity in enumerate(amenities):
    buildings = ox.pois_from_address("Port-au-Prince, Haiti", amenities = [amenity], distance = 3500)[['geometry', 'name', 'element_type']]
    for item in ['way', 'relation']:
        buildings.loc[buildings.element_type == item, 'geometry'] = buildings[buildings.element_type == item]['geometry'].map(lambda x: x.centroid)
        buildings.name.fillna('Hospital' if i == 0 else 'School', inplace = True)
        amenities[i] = buildings.to_crs(epsg = 3857)

p = figure(title = "Port-au-Prince, Haiti", tools = "pan,wheel_zoom,hover,reset", x_range = (-8057000, -8048500), y_range = (2098000, 2106000), 
           tooltips = [('Name', '@name'), ("(Long, Lat)", "($x, $y)")], x_axis_location = None, y_axis_location = None, active_scroll = 'wheel_zoom')
p.add_tile(CARTODBPOSITRON_RETINA)
p.grid.grid_line_color = None

for i, b in enumerate(amenities):
    source = ColumnDataSource(data = dict(x = b.geometry.x, y = b.geometry.y, name = b.name.values))
    p.circle('x', 'y', color = 'red' if i == 0 else 'blue', source = source, legend = 'Hospital' if i == 0 else 'School')

p.legend.click_policy = 'hide' 

show(p)

在此输入图像描述

如果你想要Select小部件,那么这里是另一种选择(Bokeh v1.1.0):

from bokeh.models import ColumnDataSource, Column, Select, CustomJS
from bokeh.plotting import figure, show
from bokeh.tile_providers import CARTODBPOSITRON_RETINA
import osmnx as ox

amenities = ['hospital', 'school']
for i, amenity in enumerate(amenities):
    buildings = ox.pois_from_address("Port-au-Prince, Haiti", amenities = [amenity], distance = 3500)[['geometry', 'name', 'element_type']]
    for item in ['way', 'relation']:
        buildings.loc[buildings.element_type == item, 'geometry'] = buildings[buildings.element_type == item]['geometry'].map(lambda x: x.centroid)
        buildings.name.fillna('Hospital' if i == 0 else 'School', inplace = True)
        buildings = buildings.to_crs(epsg = 3857)      
    amenities[i] = dict(x = list(buildings.geometry.x), y = list(buildings.geometry.y), name = list(buildings.name.values), color = (['red'] if i == 0 else ['blue']) * len(buildings.name.values))

source = ColumnDataSource(amenities[0])
p = figure(title = "Hospitals", tools = "pan,wheel_zoom,hover,reset", x_range = (-8057000, -8048500), y_range = (2098000, 2106000), 
           tooltips = [('Name', '@name'), ("(Long, Lat)", "($x, $y)")], x_axis_location = None, y_axis_location = None, active_scroll = 'wheel_zoom')
p.add_tile(CARTODBPOSITRON_RETINA)
p.circle(x = 'x', y = 'y', color = 'color', source = source)
p.grid.grid_line_color = None

code = '''  source.data = (cb_obj.value == 'Hospitals' ? data[0] : data[1]); p.title.text =  cb_obj.value; '''
select = Select(options = ['Hospitals', 'Schools'], callback = CustomJS(args=dict(p = p, source = source, data = amenities), code = code))

show(Column(p, select))

在此输入图像描述

如果您需要有关此代码的任何说明,请与我们联系。

以下是使代码工作所需的更改:

make_plot方法中,由于您要更新选择更改的图表标题,请替换

p = figure(plot_width=800,
           tools=TOOLS,
           x_axis_location=None, 
           y_axis_location=None)

p = figure(plot_width=800,
                tools=TOOLS,
                title=title,
                x_axis_location=None, 
                y_axis_location=None)

此外,由于您要更新建筑物的数据和颜色,请在方法中返回buildings ,以便完整方法现在如下所示:

def make_plot(dataPoints, title, color):

            TOOLS = "pan, wheel_zoom, reset,save"

            p = figure(plot_width=800,
                tools=TOOLS,
                title=title,
                x_axis_location=None, 
                y_axis_location=None)

        # Add points on top (as black points)
            buildings = p.circle('x', 'y', size=4, source=data1, color=color)


            hover_buildings = HoverTool(renderers = [buildings], point_policy="follow_mouse", tooltips = [("(Long, Lat)", "($x, $y)")])

            p.add_tools(hover_buildings)

            return p, buildings

接下来,而不是呼吁

plot = make_plot(dataPoints, "Data for " + buildings[building]['title'], color)

您还需要将返回的建筑物放在变量中,以便可以直接更新。 所以现在你的电话会是这样的

plot, b = make_plot(dataPoints, "Data for " + buildings[building]['title'], color)

最后,更改update_plot方法,使其如下所示:

def update_plot(attrname, old, new):
            building = building_select.value
            plot.title.text = "Data for " + buildings[building]['title']
            src = buildings[building]['data']
            dataPoints, color = returnInfo(building)
            b.data_source.data = dataPoints
            b.glyph.fill_color = color

通过这些更改,它将按预期工作。 查看附件。 使用的样本数据是:

data1=dict(
        x=[1,2,3],
        y=[2,1,3]
    )

data2=dict(
        x=[1,2,3],
        y=[1,3,2]
    )

在此输入图像描述

暂无
暂无

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

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