首頁>技術>

【導語】通過幾節基礎的學習,本篇文章我們將會進階學習利用 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

希望本文的內容對大家的學習或者工作能帶來一定的幫助,每天進步一點點,加油。

26
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 淺析開源蜜罐識別與全網測繪