我正在使用以下格式的数据(见下表)绘制交互式Bokeh choropleth,使我能够1)在两个数据集(total_orders、total_revention)之间调整数据源,2)实现两个月和年的滑块。
<class 'geopandas.geodataframe.GeoDataFrame'>
Int64Index: 555 entries, 0 to 554
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 year 555 non-null int64
1 month 555 non-null int64
2 geolocation_state 555 non-null object
3 total_orders 555 non-null int64
4 total_revenue 555 non-null float64
5 geometry 555 non-null geometry
6 total_orders_log 555 non-null float64
dtypes: float64(2), geometry(1), int64(3), object(1)
memory usage: 50.9+ KB
到目前为止,我使用的代码允许我渲染几何体,但不能渲染我期望的着色。我已经重复了几次,到目前为止,每一次修改都失败了。有人能感觉到我在这里可能错过了什么吗?
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models import GeoJSONDataSource, HoverTool, Select, Slider, LinearColorMapper, CustomJS
from bokeh.palettes import Spectral6
from bokeh.layouts import column, widgetbox
import json
import pandas as pd
# create a GeoJSONDataSource from the geometry column in your data
geo_source = GeoJSONDataSource(geojson=brazil_ecommerce.to_json())
# create a color mapper to map states to colors based on the data being shown
color_mapper = LinearColorMapper(palette=Spectral6, low=brazil_ecommerce.total_orders.min(), high=brazil_ecommerce.total_orders.max())
# create a figure and add a patch glyph to render the states
fig = figure(title='Brazil E-commerce', plot_width=800, plot_height=500)
states = fig.patches('xs', 'ys', source=geo_source, fill_color={'field': 'data', 'transform': color_mapper}, line_color='black', line_width=0.5)
# create a hover tool to show information about the states
hover = HoverTool(tooltips=[('State', '@geolocation_state'), ('Data', '@data')], renderers=[states])
fig.add_tools(hover)
# create a select tool to switch between total_orders and total_revenue
select = Select(title='Data', value='total_orders', options=['total_orders', 'total_revenue'])
# create a year slider to control the year
year_slider = Slider(title='Year', start=int(brazil_ecommerce['year'].min()), end=int(brazil_ecommerce['year'].max()), step=1, value=int(brazil_ecommerce['year'].min()))
# create a month slider to control the month
month_slider = Slider(title='Month', start=int(brazil_ecommerce['month'].min()), end=int(brazil_ecommerce['month'].max()), step=1, value=int(brazil_ecommerce['month'].min()))
brazil_ecommerce_dict = json.loads(geojson_data)
# create a CustomJS callback to update the data shown on the map
callback = CustomJS(args=dict(geo_source=geo_source, select=select, year_slider=year_slider, month_slider=month_slider, color_mapper=color_mapper, brazil_ecommerce=brazil_ecommerce_dict), code="""
const new_data = {
'geolocation_state': [],
'xs': [],
'ys': [],
'data': []
}
const selected_data = select.value;
const selected_month = month_slider.value;
const selected_year = year_slider.value;
for (var i = 0; i < brazil_ecommerce['year_month'].length; i++) {
if (brazil_ecommerce['year_month'][i] == selected_month) {
new_data['geolocation_state'].push(brazil_ecommerce['geolocation_state'][i]);
new_data['xs'].push(brazil_ecommerce['xs'][i]);
new_data['ys'].push(brazil_ecommerce['ys'][i]);
new_data['data'].push(brazil_ecommerce[selected_data][i]);
}
}
geo_source.geojson = JSON.stringify(new_data);
if (selected_data == 'total_orders') {
color_mapper.low = brazil_ecommerce.total_orders.min();
color_mapper.high = brazil_ecommerce.total_orders.max();
} else {
color_mapper.low = brazil_ecommerce.total_revenue.min();
color_mapper.high = brazil_ecommerce.total_revenue.max();
}
""")
# add the callback to the select tool and slider
select.js_on_change('value', callback)
year_slider.js_on_change('value', callback)
month_slider.js_on_change('value', callback)
# create a layout with the map and the controls
layout = column(fig, widgetbox(select, year_slider, month_slider))
# show the output in the notebook
output_notebook()
show(layout)
欢迎任何支持!