【導語】通過幾節基礎的學習,本篇文章我們將會進階學習利用 bokeh 實現聯動互動,懸浮、滑塊、下拉選單。
如下圖所示:
from bokeh.io import output_notebook, show, curdocfrom bokeh.plotting import figurefrom bokeh.models import HoverTool, ColumnDataSource, Selectfrom bokeh.models import CategoricalColorMapperfrom bokeh.palettes import Spectral6from bokeh.layouts import row, columnfrom bokeh.models import Sliderimport pandas as pddata = pd.read_csv('./demo.csv')# 製作 ColumnDataSource: sourcesource = ColumnDataSource(data={ 'x': data[data.Year == 1970].fertility, 'y': data[data.Year == 1970].life, 'country': data[data.Year == 1970].Country, 'pop': (data[data.Year == 1970].population / 20000000) + 2, 'region': data[data.Year == 1970].region,})# 儲存 fertility 列的最大值和最小值: xmin, xmaxxmin, xmax = min(data.fertility), max(data.fertility)# 儲存 life expectancy 列的最大值和最小值: ymin, ymaxymin, ymax = min(data.life), max(data.life)# 列出 region 列中的唯一值: regions_listregions_list = data.region.unique().tolist()# 製作顏色對映器: color_mappercolor_mapper = CategoricalColorMapper(factors=regions_list, palette=Spectral6)# 建立畫布: plotplot = figure(title='Gapminder Data for 1970', plot_height=400, plot_width=700, x_range=(xmin, xmax), y_range=(ymin, ymax))# 將顏色對映器新增到圓形字形plot.circle(x='x', y='y', fill_alpha=0.8, source=source, color=dict(field='region', transform=color_mapper), legend_label='region')# 設定 x 軸標籤plot.xaxis.axis_label = 'Fertility (children per woman)'# 設定 y 軸標籤plot.yaxis.axis_label = 'Life Expectancy (years)'# 建立圖例位置 'top_right'plot.legend.location = 'top_right'# 定義回撥函式: update_plotdef update_plot(attr, old, new): # 將 yr 名稱設定為 slider.value,將 new_data 設定為 source.data yr = slider.value x = x_select.value y = y_select.value # Label axes of plot plot.xaxis.axis_label = x plot.yaxis.axis_label = y # Set new_data new_data = { 'x' : data[data.Year == yr][x], 'y' : data[data.Year == yr][y], 'country' : data[data.Year == yr].Country, 'pop' : (data[data.Year == yr].population / 20000000) + 2, 'region' : data[data.Year == yr].region, } source.data = new_data # Set the range of all axes plot.x_range.start = min(data[x]) plot.x_range.end = max(data[x]) plot.y_range.start = min(data[y]) plot.y_range.end = max(data[y]) # Add title to figure plot.title.text = 'Gapminder data for %d' % yr### 新增滑塊# 製作滑塊物件: sliderslider = Slider(start=1970, end=2010, step=1, value=1970, title='Year')# 將回調附加到滑塊的'value'屬性slider.on_change('value', update_plot)### 新增懸停工具# 建立一個懸停工具: hoverhover = HoverTool(tooltips=[('Country', '@country')])# 在圖片中新增懸停工具plot.add_tools(hover)### 新增下拉選單# 建立 x 的下拉選單 : x_selectx_select = Select( options=['fertility', 'life', 'child_mortality', 'gdp'], value='fertility', title='x-axis data')# 將 update_plot 回撥附加到 x_select 的 'value' 屬性x_select.on_change('value', update_plot)# 建立 y 的下拉選單: y_selecty_select = Select( options=['fertility', 'life', 'child_mortality', 'gdp'], value='life', title='y-axis data')# 將 update_plot 回撥附加到 y_select 的 'value' 屬性y_select.on_change('value', update_plot)layout = row(column(slider, x_select, y_select), plot)curdoc().add_root(layout)curdoc().title = 'Gapminder'
學會使用 Boken 實現資料視覺化【業務場景】分析各個城市餐飲行業情況,要求製作一個選項卡,實現聯動分析。
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsimport warningswarnings.filterwarnings('ignore') from bokeh.io import output_notebook, show, curdocfrom bokeh.plotting import figurefrom bokeh.models import ColumnDataSource, Selectfrom bokeh.layouts import rowimport matplotlib as mplimport matplotlib.dates as mdateimport datetime as dtmpl.rcParams['font.family'] = 'SimHei'data=pd.read_csv('./foods.csv',encoding='gbk')#------------------------------------------------------------------# 建立下拉小部件: selectcity = list(data['city'].unique())select1=Select(options=city,value='北京')data_leixing=data[data.city == '北京']data_leixing_a = data_leixing.groupby('type').size().sort_values(ascending=False).head(10)data_leixing_b=pd.DataFrame(data=data_leixing_a,columns=['shuliang'])data_leixing_b['ind']=data_leixing_b.index# 建立資料來源: sourcesource1 = ColumnDataSource(data={ 'x': data_leixing_b['ind'], 'y': data_leixing_b['shuliang']})TOOLTIPS = [ ("城市", "@x"), ("數量", " @y")]p1 = figure(title='餐飲業的統計圖',x_range=data_leixing_a.index.to_list(),plot_width = 620, plot_height = 500, x_axis_label = '城市', y_axis_label = '數量',tooltips=TOOLTIPS)p1.vbar('x', width=0.5, bottom=0, top='y',source=source1, color='#BCEE68')# 定義回撥函式: update_plotdef update_plot1(attr, old, new): yr = select1.value data_leixing=data[data.city == yr] data_leixing_a = data_leixing.groupby('type').size().sort_values(ascending=False).head(10) data_leixing_b = pd.DataFrame(data=data_leixing_a, columns=['shuliang']) data_leixing_b['ind'] = data_leixing_b.index source1.data={ 'x': data_leixing_b['ind'], 'y': data_leixing_b['shuliang'] } p1.title.text = '%s餐飲業統計圖' % yr# update_plot 回撥附加到 select 的 'value' 屬性select1.on_change('value', update_plot1)# 建立佈局並新增到當前文件layout1 = row(select1,p1)#-------------------------------------------------------------# 建立下拉小部件: selecttypes = list(data['type'].unique())select2=Select(options=types, value='西餐')data_qudao=data[data.type == '西餐']data_qudao_a = data_qudao.groupby('city').size().sort_values(ascending=False).head(10)data_qudao_b=pd.DataFrame(data=data_qudao_a,columns=['shuliang'])data_qudao_b['ind']=data_qudao_b.index# 建立資料來源: sourcesource2 = ColumnDataSource(data={ 'x': data_qudao_b['ind'], 'y': data_qudao_b['shuliang']})TOOLTIPS = [ ("型別", "@x"), ("數量", " @y")]p2 = figure(title='餐飲型別統計圖',x_range=data_qudao_a.index.to_list(),plot_width = 620, plot_height = 500, x_axis_label = '型別', y_axis_label = '數量',tooltips=TOOLTIPS)p2.vbar('x', width=0.5, bottom=0, top='y',source=source2, color='#BCD2EE')# show(p2)# 定義回撥函式: update_plotdef update_plot2(attr, old, new): yr = select2.value data_qudao=data[data.type == yr] data_qudao_a = data_qudao.groupby('city').size().sort_values(ascending=False).head(10) data_qudao_b = pd.DataFrame(data=data_qudao_a, columns=['shuliang']) data_qudao_b['ind'] = data_qudao_b.index source2.data={ 'x': data_qudao_b['ind'], 'y': data_qudao_b['shuliang'] } p2.title.text = '%s型別統計圖' % yrselect2.on_change('value', update_plot2)layout2 = row(select2,p2)from bokeh.models.widgets import Paneltab1 = Panel(child=layout1, title='城市')tab2 = Panel(child=layout2,title='型別')from bokeh.models.widgets import Tabslayout = Tabs(tabs=[tab1,tab2])curdoc().add_root(layout)
下面我們啟動 bokeh 服務:
bokeh serve --show aa.py
希望本文的內容對大家的學習或者工作能帶來一定的幫助,每天進步一點點,加油。
最新評論