導讀:柱狀圖是當前應(yīng)用最廣泛的圖表之一,你幾乎每天都可以在電子產(chǎn)品上看到它。它有哪些分類?可以展示哪些數(shù)據(jù)關(guān)系?怎樣用Python繪制?本文帶你逐一了解。
作者:屈希峰,資深Python工程師,知乎多個專欄作者
來源:華章科技
01 概述
柱狀圖(Histogram)是一種以長方形的長度為變量的表達圖形的統(tǒng)計報告圖,由一系列高度不等的縱向條紋表示數(shù)據(jù)分布的情況,用來比較兩個或兩個以上的價值(不同時間或者不同條件),只有一個變量,通常用于較小的數(shù)據(jù)集分析。
柱狀圖也可橫向排列,或用多維方式表達。其主要用于數(shù)據(jù)統(tǒng)計與分析,早期主要用于數(shù)學統(tǒng)計學科中,用柱狀圖表示數(shù)碼相機的曝光值,到現(xiàn)代使用已經(jīng)比較廣泛,比如現(xiàn)代的電子產(chǎn)品和一些軟件的分析測試,如電腦、數(shù)碼相機的顯示器和Photoshop上都能看到相應(yīng)的柱狀圖。
1. 基礎(chǔ)柱狀圖
基礎(chǔ)柱狀圖經(jīng)常用來對比數(shù)值的大小,使用范圍非常廣泛,例如科比在不同賽季的得分、不同游戲App下載量、不同時期手機端綜合搜索用戶規(guī)模等,圖2-33顯示不同種類水果的銷量。
▲圖2-33 基本柱狀圖
需要注意的是,分類太多不適合使用豎向柱狀圖,如圖2-34所示。
▲圖2-34 豎向柱狀圖
此時,需要用到橫向柱狀圖,如圖2-35所示。
▲圖2-35 橫向柱狀圖
2. 分組柱狀圖
分組柱狀圖,又叫聚合柱狀圖。當使用者需要在同一個軸上顯示各個分類下不同的分組時,需要用到分組柱狀圖。
跟柱狀圖類似,使用柱子的高度來映射和對比數(shù)據(jù)值。每個分組中的柱子使用不同顏色或者相同顏色不同透明的方式區(qū)別各個分類,各個分組之間需要保持間隔。
分組柱狀圖經(jīng)常用于不同組間數(shù)據(jù)的比較,這些組都包含了相同分類的數(shù)據(jù)。例如,展示改革開放以來城鎮(zhèn)與農(nóng)村人口的變化,不同游戲公司的休閑、益智、格斗類App的下載量對比等。圖2-36對比了2015—2017年間不同水果的銷量。
▲圖2-36 分組柱狀圖
3. 堆疊柱狀圖
與并排顯示分類的分組柱狀圖不同,堆疊柱狀圖將每個柱子進行分割以顯示相同類型下各個數(shù)據(jù)的大小情況。它可以形象地展示一個大分類包含的每個小分類的數(shù)據(jù),以及各個小分類的占比,顯示的是單個項目與整體之間的關(guān)系。我們將堆疊柱狀圖分為兩種類型:
- 一般的堆疊柱狀圖:每一根柱子上的值分別代表不同的數(shù)據(jù)大小,各層的數(shù)據(jù)總和代表整根柱子的高度。非常適用于比較每個分組的數(shù)據(jù)總量。
- 百分比的堆疊柱狀圖:柱子的各個層代表的是該類別數(shù)據(jù)占該分組總體數(shù)據(jù)的百分比。
堆疊柱狀圖的一個缺點是當柱子上的堆疊太多時會導致數(shù)據(jù)很難區(qū)分對比,同時很難對比不同分類下相同維度的數(shù)據(jù),因為它們不是按照同一基準線對齊的。
圖2-37是顯示2015—2017年間不同水果的累計數(shù)量。
▲圖2-37 堆疊柱狀圖
4. 雙向柱狀圖
雙向柱狀圖,又名正負條形圖,使用正向和反向的柱子顯示類別之間的數(shù)值比較。其中分類軸表示需要對比的分類維度,連續(xù)軸代表相應(yīng)的數(shù)值,分為兩種情況,一種是正向刻度值與反向刻度值完全對稱,另一種是正向刻度值與反向刻度值反向?qū)ΨQ,即互為相反數(shù)。
圖2-38是顯示2015—2017年間不同水果的進出口數(shù)量。
▲圖2-38 雙向柱狀圖
5. 瀑布圖
瀑布圖是由麥肯錫顧問公司所獨創(chuàng)的圖表類型,因為形似瀑布流水而稱之為瀑布圖(Waterfall Plot)。此種圖表采用絕對值與相對值結(jié)合的方式,適用于表達數(shù)個特定數(shù)值之間的數(shù)量變化關(guān)系。圖2-39顯示歷年短跑冠軍的時間跨度,由此可以看出人類體能極限越來越高了。
▲圖2-39 瀑布圖
接下來,我們看看如何用Bokeh依次實現(xiàn)這些柱狀圖。
02 實例
柱狀圖代碼示例如下所示。
- 代碼示例 2-27
1p = figure(plot_width=400, plot_height=400)2p.vbar(x=[1, 2, 3], width=0.5, bottom=0,3 top=[1.2, 2.5, 3.7], color="red") # 垂直柱狀圖4show(p) # 顯示
運行結(jié)果如圖2-40所示。
▲圖2-40 代碼示例2-27運行結(jié)果
代碼示例2-27第2行采用vbar()方法實現(xiàn)垂直柱狀圖,該方法具體的參數(shù)說明如下。
p.vbar(x, width, top, bottom=0, **kwargs)參數(shù)說明。
- x (:class:`~bokeh.core.properties.NumberSpec` ) : 柱中心x軸坐標
- width (:class:`~bokeh.core.properties.NumberSpec` ) : 柱寬
- top (:class:`~bokeh.core.properties.NumberSpec` ) : 柱頂部y軸坐標
- bottom (:class:`~bokeh.core.properties.NumberSpec` ) : 柱底部y軸坐標
- 代碼示例 2-28
1p = figure(plot_width=400, plot_height=400) 2p.hbar(y=[1, 2, 3], height=0.5, left=0, 3 right=[1.2, 2.5, 3.7], color="navy") # 水平柱狀圖 4show(p) # 顯示
運行結(jié)果如圖2-41所示。
▲圖2-41 代碼示例2-28運行結(jié)果
代碼示例2-28第2行采用hbar()方法實現(xiàn)橫向柱狀圖,該方法具體的參數(shù)說明如下。
p.hbar(y, height, right, left=0, **kwargs)參數(shù)說明。
- y (:class:`~bokeh.core.properties.NumberSpec` ) : 柱中心y軸坐標
- height (:class:`~bokeh.core.properties.NumberSpec` ) :柱的高度(寬度)
- right (:class:`~bokeh.core.properties.NumberSpec` ) :柱右側(cè)邊界x軸坐標
- left (:class:`~bokeh.core.properties.NumberSpec` ) :柱左側(cè)邊界x軸坐標
- 代碼示例 2-29
1from bokeh.models import ColumnDataSource 2from bokeh.palettes import Spectral6 3import pandas as pd 4df=pd.read_csv('data/visualization-20190505.csv') 5p = figure(x_range=df['Visualization_tools'],title="2019年5月常見可視化工具源碼GitHub標星數(shù)量") 6p.vbar(x=df['Visualization_tools'], top=df['Star'] , width=0.8, color=Spectral6)7p.xgrid.grid_line_color = None 8p.y_range.start = 0 9show(p)
運行結(jié)果如圖2-42所示。
▲圖2-42 代碼示例2-29運行結(jié)果
代碼示例2-29第6行采用vbar()方法展示集中可視化開源工具在GitHub上的Stars數(shù),可以看出Bokeh已經(jīng)超過了Matplotlib。
- 代碼示例 2-30
1# 數(shù)據(jù) 2fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 3counts = [5, 3, 4, 2, 4, 6] 4# 畫布 5p = figure(x_range=fruits, plot_height=350, title="Fruit Counts", 6# toolbar_location=None, 7# tools="" 8 ) 9# 柱狀圖 10p.vbar(x=fruits, top=counts, width=0.9) 11# 坐標軸設(shè)置 12p.xgrid.grid_line_color = None 13p.y_range.start = 0 14# 顯示 15show(p)
運行結(jié)果如圖2-43所示。
▲圖2-43 代碼示例2-30運行結(jié)果
代碼示例2-30第10行采用vbar()方法展示了幾種水果的銷量。
- 代碼示例 2-31
1# 數(shù)據(jù) 2fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 3counts = [5, 3, 4, 2, 4, 6] 4# 排序 5sorted_fruits = sorted(fruits, key=lambda x: counts[fruits.index(x)]) 6# 畫布 7p = figure(x_range=sorted_fruits, plot_height=350, title="Fruit Counts", 8# toolbar_location=None, tools="" 9 ) 10# 繪圖 11p.vbar(x=fruits, top=counts, width=0.9) 12# 其他 13p.xgrid.grid_line_color = None 14p.y_range.start = 0 15# 顯示 16show(p)
運行結(jié)果如圖2-44所示。
▲圖2-44 代碼示例2-31運行結(jié)果
代碼示例2-31第5行先用sorted()方法對原始數(shù)據(jù)進行排序;然后在第11行采用vbar()方法展示了幾種水果的銷量。
- 代碼示例 2-32
1from bokeh.models import ColumnDataSource 2from bokeh.palettes import Spectral6 3from bokeh.transform import factor_cmap 4# 數(shù)據(jù) 5fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 6counts = [5, 3, 4, 2, 4, 6] 7source = ColumnDataSource(data=dict(fruits=fruits, counts=counts)) 8# 畫布 9p = figure(x_range=fruits, plot_height=350, toolbar_location=None, title="Fruit Counts") 10# 繪圖,分組顏色映射 11p.vbar(x='fruits', top='counts', width=0.9, source=source, legend="fruits", 12 line_color='white', fill_color=factor_cmap('fruits', palette=Spectral6, factors=fruits)) 13# 坐標軸、圖例設(shè)置 14p.xgrid.grid_line_color = None 15p.y_range.start = 0 16p.y_range.end = 9 17p.legend.orientation = "horizontal" 18p.legend.location = "top_center" 19show(p)
運行結(jié)果如圖2-45所示。
▲圖2-45 代碼示例2-32運行結(jié)果
代碼示例2-32第11行采用vbar()方法展示了幾種水果的銷量,其中l(wèi)ine_color、fill_color分別為柱的輪廓線顏色和填充顏色,factor_cmap采用數(shù)據(jù)分類進行顏色映射。在代碼實例2-27中,也可以通過color直接定義顏色列表。
- 代碼示例 2-33
1from bokeh.models import ColumnDataSource 2from bokeh.palettes import Spectral6 # ['#3288bd', '#99d594', '#e6f598', '#fee08b', '#fc8d59', '#d53e4f'] 3fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 4counts = [5, 3, 4, 2, 4, 6] 5source = ColumnDataSource(data=dict(fruits=fruits, counts=counts, color=Spectral6)) 6p = figure(x_range=(0,9), y_range=fruits, plot_height=250, title="Fruit Counts", 7# toolbar_location=None, tools="" 8 ) 9p.hbar(y='fruits',left=0,right='counts', height=0.5 ,color='color', legend="fruits", source=source) 10p.xgrid.grid_line_color = None 11# p.legend.orientation = "horizontal" 12p.legend.location = "top_right" 13show(p)
運行結(jié)果如圖2-46所示。
代碼示例2-33第9行采用hbar()方法展示了幾種水果的銷量,并使用color直接定義顏色列表。
▲圖2-46 代碼示例2-33運行結(jié)果
- 代碼示例 2-34
1fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 2years = ['2015', '2016', '2017'] 3data = {'fruits' : fruits, 4 '2015' : [2, 1, 4, 3, 2, 4], 5 '2016' : [5, 3, 3, 2, 4, 6], 6 '2017' : [3, 2, 4, 4, 5, 3]} 7# 創(chuàng)建復合列表 [ ("Apples", "2015"), ("Apples", "2016"), ("Apples", "2017"), ("Pears", "2015), ... ] 8x = [ (fruit, year) for fruit in fruits for year in years ] 9counts = sum(zip(data['2015'], data['2016'], data['2017']), ()) # 分組求和(堆疊總數(shù))10source = ColumnDataSource(data=dict(x=x, counts=counts)) 11# 畫布 12p = figure(x_range=FactorRange(*x), plot_height=350, title="Fruit Counts by Year", 13# toolbar_location=None, tools="" 14 ) 15# 柱狀圖 16p.vbar(x='x', top='counts', width=0.9, source=source) 17# 其他 18p.y_range.start = 0 19p.x_range.range_padding = 0.1 20p.xaxis.major_label_orientation = 1 21p.xgrid.grid_line_color = None 22# 顯示 23show(p)
運行結(jié)果如圖2-47所示。
代碼示例2-34第8、9行數(shù)據(jù)預(yù)處理,讀者可以打印數(shù)據(jù)格式;筆者建議在實踐中多采用Pandas進行數(shù)據(jù)預(yù)處理,其DataFrames的復合序列可以直接作為分組柱狀圖的數(shù)據(jù)。
▲圖2-47 代碼示例2-34運行結(jié)果
- 代碼示例 2-35
1# 數(shù)據(jù) 2fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 3years = ['2015', '2016', '2017'] 4data = {'fruits' : fruits, 5 '2015' : [2, 1, 4, 3, 2, 4], 6 '2016' : [5, 3, 3, 2, 4, 6], 7 '2017' : [3, 2, 4, 4, 5, 3]} 8palette = ["#c9d9d3", "#718dbf", "#e84d60"] 9x = [ (fruit, year) for fruit in fruits for year in years ] 10counts = sum(zip(data['2015'], data['2016'], data['2017']), ()) # like an hstack11source = ColumnDataSource(data=dict(x=x, counts=counts)) 12# 畫布 13p = figure(x_range=FactorRange(*x), plot_height=350, title="Fruit Counts by Year",14# toolbar_location=None, tools="" 15 ) 16# 繪圖 17p.vbar(x='x', top='counts', width=0.9, source=source, line_color="white", 18 fill_color=factor_cmap('x', palette=palette, factors=years, start=1, end=2))19# 其他 20p.y_range.start = 0 21p.x_range.range_padding = 0.1 22p.xaxis.major_label_orientation = 1 23p.xgrid.grid_line_color = None 24# 顯示 25show(p)
運行結(jié)果如圖2-48所示。
▲圖2-48 代碼示例2-35運行結(jié)果
代碼示例2-35在代碼示例2-33的基礎(chǔ)上增加了柱狀圖顏色(第18行),factor_cmap方法是將色板對應(yīng)的顏色列表映射到相應(yīng)的分類數(shù)據(jù)上。
- 代碼示例 2-36
1from bokeh.core.properties import value 2from bokeh.transform import dodge 3# 數(shù)據(jù) 4fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 5years = ['2015', '2016', '2017'] 6data = {'fruits' : fruits, 7 '2015' : [2, 1, 4, 3, 2, 4], 8 '2016' : [5, 3, 3, 2, 4, 6], 9 '2017' : [3, 2, 4, 4, 5, 3]} 10source = ColumnDataSource(data=data) 11# 畫布 12p = figure(x_range=fruits, y_range=(0, 10), plot_height=350, title="Fruit Counts by Year", 13# toolbar_location=None, tools="" 14 ) 15# 繪圖,采用doge數(shù)據(jù)轉(zhuǎn)換,按產(chǎn)品種類不同年份分組顯示 16p.vbar(x=dodge('fruits', -0.25, range=p.x_range), top='2015', width=0.2, source=source, 17 color="#c9d9d3", legend=value("2015")) 1819p.vbar(x=dodge('fruits', 0.0, range=p.x_range), top='2016', width=0.2, source=source, 20 color="#718dbf", legend=value("2016")) 2122p.vbar(x=dodge('fruits', 0.25, range=p.x_range), top='2017', width=0.2, source=source, 23 color="#e84d60", legend=value("2017")) 24# 其他參數(shù)設(shè)置 25p.x_range.range_padding = 0.1 26p.xgrid.grid_line_color = None 27p.legend.location = "top_left" 28p.legend.orientation = "horizontal" 29# 顯示 30show(p)
運行結(jié)果如圖2-49所示。
▲圖2-49 代碼示例2-36運行結(jié)果
代碼示例2-36第16、19、22使用vbar()方法分別繪制2015—2017年各種水果的銷量;其中dodge方法按每年不同種類水果的數(shù)據(jù)分散繪制在x軸范圍內(nèi),是將色板對應(yīng)的顏色列表映射到相應(yīng)的分類數(shù)據(jù)上,dodge第二個參數(shù)表示該分類的起始繪制點。
- 代碼示例 2-37
1from bokeh.core.properties import value 2# 數(shù)據(jù) 3fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 4years = ["2015", "2016", "2017"] 5colors = ["#c9d9d3", "#718dbf", "#e84d60"] 6data = {'fruits' : fruits, 7 '2015' : [2, 1, 4, 3, 2, 4], 8 '2016' : [5, 3, 4, 2, 4, 6], 9 '2017' : [3, 2, 4, 4, 5, 3]} 10# 畫布 11p = figure(x_range=fruits, plot_height=250, title="Fruit Counts by Year", 12# toolbar_location=None, 13# tools="hover", 14 tooltips="$name @fruits: @$name") 15# 繪圖,直接堆疊各年數(shù)據(jù) 16p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=data, 17 legend=[value(x) for x in years]) # legend=[{'value': '2015'}, {'value': '2016'}, {'value': '2017'}] 18# 其他 19p.y_range.start = 0 20p.x_range.range_padding = 0.1 21p.xgrid.grid_line_color = None 22p.axis.minor_tick_line_color = None 23p.outline_line_color = None 24p.legend.location = "top_left" 25p.legend.orientation = "horizontal" 26# 顯示 27show(p)
運行結(jié)果如圖2-50所示。
▲圖2-50 代碼示例2-37運行結(jié)果
代碼示例2-37第16行使用vbar_stack()方法實現(xiàn)豎向堆疊柱狀圖,該方法具體的參數(shù)說明如下。
p.vbar_stack(stackers, **kw)參數(shù)說明。
- stackers (seq[str]) : 列表,由繪圖數(shù)據(jù)中需要進行堆疊的數(shù)據(jù)列名稱組成。
其他參數(shù)基本上同vbar()方法。
- 代碼示例 2-38
1from bokeh.models import Legend 2p = figure(y_range=fruits, plot_height=250,title="Fruit Counts by Year", 3# toolbar_location=None, tools="" 4 ) 5source = ColumnDataSource(data=data) 6p.hbar_stack(years, y='fruits',height=0.8, color=colors, source=source, 7 legend=[value(x) for x in years] ) # 堆疊柱狀圖,逐年堆疊 8p.x_range.start = 0 9p.y_range.range_padding = 0.1 # x軸兩側(cè)空白 10p.ygrid.grid_line_color = None 11p.axis.minor_tick_line_color = None 12p.outline_line_color = None 13p.legend.location = "top_right" 14# p.legend.orientation = "horizontal" 15p.legend.click_policy="hide" 16show(p)
運行結(jié)果如圖2-51所示。
▲圖2-51 代碼示例2-38運行結(jié)果
代碼示例2-38第6行使用hbar_stack()方法實現(xiàn)橫向堆疊柱狀圖,該方法具體的參數(shù)說明如下。
p.hbar_stack(stackers, **kw)參數(shù)說明。
- stackers (seq[str]) : 列表,由繪圖數(shù)據(jù)中需要進行堆疊的數(shù)據(jù)列名稱組成。
其他參數(shù)基本上同vbar()方法。
在學習或時間過程中,圖例可能遮蓋圖表,此時可以將圖例移到坐標軸外或單獨作為一個圖層。
- 代碼示例 2-39
1from bokeh.palettes import Spectral5 2from bokeh.sampledata.autompg import autompg as df 3from bokeh.transform import factor_cmap 4# 數(shù)據(jù),預(yù)處理 5df.cyl = df.cyl.astype(str) 6group = df.groupby('cyl') 7cyl_cmap = factor_cmap('cyl', palette=Spectral5, factors=sorted(df.cyl.unique())) # 分組顏色映射 8# 畫布 9p = figure(plot_height=350, x_range=group, title="MPG by # Cylinders", 10# toolbar_location=None, tools="" 11 ) 12# 繪圖 13p.vbar(x='cyl', top='mpg_mean', width=0.9, source=group, 14 line_color=cyl_cmap, fill_color=cyl_cmap) 15# 其他 16p.y_range.start = 0 17p.xgrid.grid_line_color = None 18p.xaxis.axis_label = "some stuff" 19p.xaxis.major_label_orientation = 1.2 20p.outline_line_color = None 21# 顯示 22show(p)
運行結(jié)果如圖2-52所示。
▲圖2-52 代碼示例2-39運行結(jié)果
代碼示例2-39第13行使用vbar()用柱狀圖展示了汽車缸數(shù)與每加侖汽油能行駛的英里數(shù)之間的關(guān)系。
- 代碼示例 2-40
1from bokeh.sampledata.autompg import autompg_clean as df 2df.cyl = df.cyl.astype(str) 3df.yr = df.yr.astype(str) 4group = df.groupby(['cyl', 'mfr']) # 復合條件分組,[缸數(shù)、廠家] 5index_cmap = factor_cmap('cyl_mfr', palette=Spectral5, factors=sorted(df.cyl.unique()), end=1) 6# 畫布 7p = figure(plot_width=800, plot_height=300, title="Mean MPG by # Cylinders and Manufacturer", 8 x_range=group, tooltips=[("MPG", "@mpg_mean"), ("Cyl, Mfr", "@cyl_mfr")]) 9# 繪圖 10p.vbar(x='cyl_mfr', top='mpg_mean', width=1, source=group, 11 line_color="white", fill_color=index_cmap, ) # 尾氣排放量均值 12# 其他 13p.y_range.start = 0 14p.x_range.range_padding = 0.05 # 同css中的padding 15p.xgrid.grid_line_color = None 16p.xaxis.axis_label = "Manufacturer grouped by # Cylinders" 17p.xaxis.major_label_orientation = 1.2 # x軸標簽旋轉(zhuǎn) 18p.outline_line_color = None 19# 顯示 20show(p)
運行結(jié)果如圖2-53所示。
▲圖2-53 代碼示例2-40運行結(jié)果
代碼示例2-40第10行使用vbar()繪制分組柱狀圖,數(shù)據(jù)分組采用Pandas的groupby方法,該數(shù)據(jù)為復合序列,展示了汽車缸數(shù)與每加侖汽油能行駛的英里數(shù)之間的關(guān)系。
- 代碼示例 2-41
1# 數(shù)據(jù) 2from bokeh.sampledata.sprint import sprint 3sprint.Year = sprint.Year.astype(str) 4group = sprint.groupby('Year') 5source = ColumnDataSource(group) 6# 畫布 7p = figure(y_range=group, x_range=(9.5,12.7), plot_width=400, plot_height=550, 8# toolbar_location=None, 9 title="Time Spreads for Sprint Medalists (by Year)") 10# 繪圖 11p.hbar(y="Year", left='Time_min', right='Time_max', height=0.4, source=source) # 水平柱狀圖 12# 其他 13p.ygrid.grid_line_color = None 14p.xaxis.axis_label = "Time (seconds)" 15p.outline_line_color = None 16# 顯示 17show(p)
運行結(jié)果如圖2-54所示。
▲圖2-54 代碼示例2-41運行結(jié)果
代碼示例2-41第11行使用hbar()繪制瀑布圖,參數(shù)中l(wèi)eft、right為柱左、右坐標。若左側(cè)的起始坐標均為某一定值,則變回橫向柱狀圖。
- 代碼示例 2-42
1from bokeh.core.properties import value 2from bokeh.models import ColumnDataSource, FactorRange 3# 數(shù)據(jù) 4factors = [ 5 ("Q1", "jan"), ("Q1", "feb"), ("Q1", "mar"), 6 ("Q2", "apr"), ("Q2", "may"), ("Q2", "jun"), 7 ("Q3", "jul"), ("Q3", "aug"), ("Q3", "sep"), 8 ("Q4", "oct"), ("Q4", "nov"), ("Q4", "dec"), 910] 11regions = ['east', 'west'] 12source = ColumnDataSource(data=dict( 13 x=factors, 14 east=[ 5, 5, 6, 5, 5, 4, 5, 6, 7, 8, 6, 9 ], 15 west=[ 5, 7, 9, 4, 5, 4, 7, 7, 7, 6, 6, 7 ], 16)) 17# 畫布 18p = figure(x_range=FactorRange(*factors), plot_height=250, 19# toolbar_location=None, tools="" 20 ) 21# 繪圖 22p.vbar_stack(regions, x='x', width=0.9, alpha=0.5, color=["blue", "red"], source=source,23 legend=[value(x) for x in regions]) 24# 其他 25p.y_range.start = 0 26p.y_range.end = 18 27p.x_range.range_padding = 0.1 28p.xaxis.major_label_orientation = 1 29p.xgrid.grid_line_color = None 30p.legend.location = "top_center" 31p.legend.orientation = "horizontal" 32# 顯示 33show(p)
運行結(jié)果如圖2-55所示。
▲圖2-55 代碼示例2-42運行結(jié)果
代碼示例2-42第18行使用FactorRange ()方法預(yù)定義x軸的范圍(factors的數(shù)據(jù)格式與Pandas復合序列相似);第19行繪制豎向堆疊柱狀圖。與常規(guī)豎向堆疊柱狀圖相比,該圖采用了復合序列,多展示了一個維度。
- 代碼示例 2-43
1from bokeh.models import ColumnDataSource 2from bokeh.palettes import GnBu3, OrRd3 3# 數(shù)據(jù) 4fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] 5years = ["2015", "2016", "2017"] 6exports = {'fruits' : fruits, 7 '2015' : [2, 1, 4, 3, 2, 4], 8 '2016' : [5, 3, 4, 2, 4, 6], 9 '2017' : [3, 2, 4, 4, 5, 3]} 10imports = {'fruits' : fruits, 11 '2015' : [-1, 0, -1, -3, -2, -1], 12 '2016' : [-2, -1, -3, -1, -2, -2], 13 '2017' : [-1, -2, -1, 0, -2, -2]} 14# 畫布 15p = figure(y_range=fruits, plot_height=350, x_range=(-16, 16), title="Fruit import/export, by year", 16# toolbar_location=None 17 ) 18# 水平堆積柱狀圖出口(正向) 19p.hbar_stack(years, y='fruits', height=0.9, color=GnBu3, source=ColumnDataSource(exports), 20 legend=["%s exports" % x for x in years]) 21# 水平堆積柱狀圖進口(負向) 22p.hbar_stack(years, y='fruits', height=0.9, color=OrRd3, source=ColumnDataSource(imports), 23 legend=["%s imports" % x for x in years]) 24# 其他25p.y_range.range_padding = 0.1 26p.ygrid.grid_line_color = None 27p.legend.location = "top_left" 28p.axis.minor_tick_line_color = None 29p.outline_line_color = None 30# 顯示31show(p)
運行結(jié)果如圖2-56所示。
代碼示例2-43第19、22行分別使用hbar_stack ()方法向左、右兩個方向繪制,實現(xiàn)橫向堆疊柱狀圖;注意,當y軸為分類數(shù)據(jù)(字符串)時,一般需要預(yù)先定義y_range。筆者在實踐中習慣用該圖,不受縱向長度約束,適合數(shù)據(jù)較多的長圖,例如全國各省某類型數(shù)據(jù)的比較。
▲圖2-56 代碼示例2-43運行結(jié)果
- 代碼示例 2-44
1from bokeh.models import FactorRange 2factors = [ 3 ("Q1", "jan"), ("Q1", "feb"), ("Q1", "mar"), 4 ("Q2", "apr"), ("Q2", "may"), ("Q2", "jun"), 5 ("Q3", "jul"), ("Q3", "aug"), ("Q3", "sep"), 6 ("Q4", "oct"), ("Q4", "nov"), ("Q4", "dec"), 7 8] # 復合數(shù)列 9p = figure(x_range=FactorRange(*factors), plot_height=350, 10# toolbar_location=None, tools="" 11 ) # 如果不采用ColumnDataSource,就必須預(yù)定義factors 12x = [ 10, 12, 16, 9, 10, 8, 12, 13, 14, 14, 12, 16 ] 13# 水平柱狀圖 14p.vbar(x=factors, top=x, width=0.9, alpha=0.5) 15# 折線 16p.line(x=["Q1", "Q2", "Q3", "Q4"], y=[12, 9, 13, 14], color="red", line_width=2)17# 其他 18p.y_range.start = 0 19p.x_range.range_padding = 0.1 20p.xaxis.major_label_orientation = 1 21p.xgrid.grid_line_color = None 22# 顯示 23show(p)
運行結(jié)果如圖2-57所示。
▲圖2-57 代碼示例2-44運行結(jié)果
關(guān)于作者:屈希峰,資深Python工程師,Bokeh領(lǐng)域的實踐者和布道者,對Bokeh有深入的研究。擅長Flask、MongoDB、Sklearn等技術(shù),實踐經(jīng)驗豐富。知乎多個專欄(Python中文社區(qū)、Python程序員、大數(shù)據(jù)分析挖掘)作者,專欄累計關(guān)注用戶十余萬人。
本文摘編自《Python數(shù)據(jù)可視化:基于Bokeh的可視化繪圖》,經(jīng)出版方授權(quán)發(fā)布。
延伸閱讀《Python數(shù)據(jù)可視化》
推薦語:從圖形繪制、數(shù)據(jù)動態(tài)展示、Web交互等維度全面講解Bokeh功能和使用,不含復雜數(shù)據(jù)處理和算法,深入淺出,適合零基礎(chǔ)入門,包含大量案例。
(正文已結(jié)束)
推薦閱讀:adobe公司
免責聲明及提醒:此文內(nèi)容為本網(wǎng)所轉(zhuǎn)載企業(yè)宣傳資訊,該相關(guān)信息僅為宣傳及傳遞更多信息之目的,不代表本網(wǎng)站觀點,文章真實性請瀏覽者慎重核實!任何投資加盟均有風險,提醒廣大民眾投資需謹慎!