Python Bokeh 庫(kù)進(jìn)行數(shù)據(jù)可視化實(shí)用指南
↑?關(guān)注 + 星標(biāo)?,每天學(xué)Python新技能
后臺(tái)回復(fù)【大禮包】送你Python自學(xué)大禮包

寫(xiě)在前面
我相信大家已經(jīng)閱讀了不少有關(guān)“機(jī)器學(xué)習(xí)”、“數(shù)據(jù)科學(xué)家”、“數(shù)據(jù)可視化”等話題的文章。有些人將數(shù)據(jù)科學(xué)稱為?21 世紀(jì)最性感的工作。?Anaconda 的《2020 年數(shù)據(jù)科學(xué)狀況報(bào)告》指出,21% 的時(shí)間用于數(shù)據(jù)可視化。使用工具或庫(kù)來(lái)幫助我們完成講故事的流程很重要。
數(shù)據(jù)可視化是預(yù)測(cè)建模中最基本、最重要的步驟之一。人們通常從數(shù)據(jù)可視化開(kāi)始以獲得更多見(jiàn)解,并嘗試通過(guò)探索性數(shù)據(jù)分析 (EDA) 來(lái)理解數(shù)據(jù)。制作圖表和視覺(jué)效果是更好的選擇,而不是研究表格和值,因?yàn)槿藗兿矚g視覺(jué)效果而不是無(wú)聊的文本或值。
所以,制作清晰、優(yōu)雅、富有洞察力的圖表,讀者可以輕松理解,始終將觀眾視為非技術(shù)人員。越少影響越大,適當(dāng)?shù)目梢暬瘞?lái)數(shù)據(jù)的清晰度,有助于決策。我們給出一個(gè)有助于Bokeh可視化的快速指南。

什么是Bokeh?
Bokeh 是 Python 中的交互式可視化庫(kù)。Bokeh提供的最佳功能是針對(duì)現(xiàn)代 Web 瀏覽器進(jìn)行演示的高度交互式圖形和繪圖。Bokeh 幫助我們制作出優(yōu)雅、簡(jiǎn)潔的圖表,其中包含各種圖表。

Bokeh 主要側(cè)重于將數(shù)據(jù)源轉(zhuǎn)換為 JSON 格式,然后用作 BokehJS 的輸入。Bokeh的一些最佳功能是:
靈活性:?Bokeh 也為復(fù)雜的用例提供簡(jiǎn)單的圖表和海關(guān)圖表。 功能強(qiáng):?Bokeh 具有易于兼容的特性,可以與 Pandas 和 Jupyter 筆記本一起使用。 樣式:?我們可以控制圖表,我們可以使用自定義 Javascript 輕松修改圖表。 開(kāi)源:?Bokeh 提供了大量的示例和想法,并在 Berkeley Source Distribution (BSD) 許可下分發(fā)。
使用Bokeh,我們可以輕松地將大數(shù)據(jù)可視化并以吸引人的優(yōu)雅方式創(chuàng)建不同的圖表。
在哪使用Bokeh圖
有很多可視化庫(kù),為什么我們只需要使用Bokeh?
我們可以使用 Bokeh 庫(kù)在網(wǎng)頁(yè)上嵌入圖表。使用Bokeh,我們可以將圖表嵌入網(wǎng)絡(luò)、制作實(shí)時(shí)儀表板和應(yīng)用程序。Bokeh 為圖表提供了自己的樣式選項(xiàng)和小部件。這是使用 Flask 或 Django 在網(wǎng)站上嵌入Bokeh圖的優(yōu)勢(shì)。
主要是Bokeh提供了兩個(gè)界面層次,簡(jiǎn)單易上手。
Bokeh模型 Bokeh圖 Bokeh應(yīng)用 Bokeh服務(wù)器
Bokeh模型
Bokeh模型提供低級(jí)接口,為應(yīng)用程序開(kāi)發(fā)人員提供高端靈活性
Bokeh圖
Bokeh繪圖提供了一個(gè)用于創(chuàng)建視覺(jué)符號(hào)的高級(jí)界面。Bokeh繪圖是 Bokeh.models 模塊的子類(lèi)。它包含圖形類(lèi)的定義;圖形類(lèi)是最簡(jiǎn)單的繪圖創(chuàng)建。
Bokeh應(yīng)用程序
Bokeh應(yīng)用程序包,用于創(chuàng)建Bokeh文件;是一家輕量級(jí)工廠。
Bokeh服務(wù)器
Bokeh 服務(wù)器用于發(fā)布和共享交互式圖表和應(yīng)用程序。
安裝Bokeh庫(kù)
用pip安裝Bokeh庫(kù),運(yùn)行以下命令
pip?install?pandas-Bokeh
為conda環(huán)境安裝Bokeh庫(kù),運(yùn)行以下命令
conda?install?-c?patrikhlobil?pandas-Bokeh
導(dǎo)入Bokeh庫(kù)
為Bokeh庫(kù)導(dǎo)入必要的包。
import?pandas?as?pd
#?pip?install?pandas_Bokeh
import?pandas_Bokeh
from?Bokeh.io?import?show,?output_notebook
from?Bokeh.plotting?import?figure
pandas_Bokeh.output_notebook()
pd.set_option('plotting.backend',?'pandas_Bokeh')
Bokeh繪圖是一個(gè)用于創(chuàng)建交互式視覺(jué)效果的界面,我們從中導(dǎo)入 它作為保存我們圖表的容器。?figure
from?Bokeh.plotting?import?figure
我們需要以下命令來(lái)顯示圖表。
from?Bokeh.io?import?show,?output_notebook
我們需要以下命令來(lái)在 jupyter notebook 中顯示圖表的輸出。
pandas_Bokeh.output_notebook()
要將圖表嵌入為 HTML,請(qǐng)運(yùn)行以下命令。
pandas_bokeh.output_file(文件名)
Hovertool 用于在我們使用鼠標(biāo)指針懸停在數(shù)據(jù)上時(shí)顯示值, ColumnDataSource 是 DataFrame 的 Bokeh 版本。
from?Bokeh.models?import?HoverTool,?ColumnDataSource
繪制圖表的語(yǔ)法
使用Pandas Bokeh
現(xiàn)在,通過(guò)以下代碼將Bokeh繪圖庫(kù)用于 Pandas 數(shù)據(jù)框。
dataframe.plot_Bokeh()
為Bokeh創(chuàng)建 Figure 對(duì)象
我們將創(chuàng)建一個(gè)圖形對(duì)象,它只不過(guò)是一個(gè)保存圖表的容器。我們可以給 figure() 對(duì)象取任何名字,這里我們給了 fig.
fig?=?figure()
'''
自定義繪圖代碼
'''
show(fig)
使用 ColumnDataSource 創(chuàng)建圖表
要將 ColumnDataSource 與渲染函數(shù)一起使用,我們至少需要傳遞 3 個(gè)參數(shù):
x?– 包含圖表 x 軸數(shù)據(jù)的 ColumnDataSource 列的名稱 y?– 包含圖表 y 軸數(shù)據(jù)的 ColumnDataSource 列的名稱 source?– ColumnDataSource 列的名稱,該列包含我們?yōu)?x 軸和 y 軸引用的數(shù)據(jù)
要在單獨(dú)的 HTML 文件中顯示輸出圖表,請(qǐng)運(yùn)行以下命令。
output_file('abc.html')
使用Bokeh庫(kù)主題
Bokeh主題有一組預(yù)定義的設(shè)計(jì),可以將它們應(yīng)用到您的繪圖中。Bokeh 提供了五個(gè)內(nèi)置主題。
caliber, dark_minimal, light_minimal, night_sky, contrast.
下圖顯示了圖表在內(nèi)置主題中的外觀。在這里,我采取了不同主題的折線圖。
運(yùn)行以下代碼以使用內(nèi)置主題繪制圖表。

圖表樣式
為了增強(qiáng)圖表,我們可以使用不同的屬性。對(duì)象共有的三組主要屬性:
線屬性 填充屬性 文本屬性
基本造型
我將只添加自定義圖表所需的代碼,您可以根據(jù)需要添加代碼。最后,我將展示帶有演示代碼的圖表,以便清楚地理解。好吧,還有更多屬性的詳細(xì)解釋請(qǐng)參見(jiàn)官方文檔。
為圖表添加背景顏色。
fig?=?figure(background_fill_color="#fafafa")
設(shè)置圖表寬度和高度的值我們需要在figure()中添加高度和寬度。
fig?=?figure(height=350,?width=500)
隱藏圖表的 x 軸和 y 軸。
fig.axis.visible=False
隱藏圖表的網(wǎng)格顏色。
fig.grid.grid_line_color?=?None
要更改圖表顏色的強(qiáng)度,我們使用 alpha 。
fig.background_fill_alpha=0.3
要為圖表添加標(biāo)題,我們需要在 figure() 中添加標(biāo)題。
fig?=?figure(title="abc")
要添加或更改 x 軸和 y 軸標(biāo)簽,請(qǐng)運(yùn)行以下命令。
fig.xaxis.axis_label='X-axis'
fig.yaxis.axis_label='Y-axis'
簡(jiǎn)單樣式的演示圖表
x?=?list(range(11))
y0?=?x
fig?=?figure(width=500,?height=250,title='Title',background_fill_color="#fafafa")
fig.circle(x,?y0,?size=12,?color="#53777a",?alpha=0.8)
fig.grid.grid_line_color?=?None
fig.xaxis.axis_label='X-axis'
fig.yaxis.axis_label='Y-axis'
show(fig)

使用 Bokeh.plotting 界面創(chuàng)建圖表的步驟是:

準(zhǔn)備數(shù)據(jù) 創(chuàng)建一個(gè)新的情節(jié) 為您的數(shù)據(jù)添加渲染,以及您對(duì)繪圖的可視化自定義 指定生成輸出的位置(在 HTML 文件中或在 Jupyter Notebook 中) 顯示結(jié)果
Python 中的Bokeh用例
我們將要處理的數(shù)據(jù)是我們當(dāng)中最著名的數(shù)據(jù)集,可以在 kaggle上找到該數(shù)據(jù)集。也可以直接在公眾號(hào)「數(shù)據(jù)STUDIO」后臺(tái)回復(fù)【Bokeh】自助獲取。同時(shí)可獲取到本指南的PDF版本。
在我們中間是人們玩手機(jī)游戲的新熱潮,它突然流行起來(lái),成為大流行中的熱門(mén)視頻游戲。在此向所有我們的粉絲簡(jiǎn)要介紹游戲的運(yùn)作方式。在我們之中是一款多人游戲,其中四到十名玩家被放入一艘外星飛船。每個(gè)玩家都有自己的Imposter或Crewmate角色;船員的任務(wù)是在飛船周?chē)軄?lái)跑去完成所有分配的任務(wù),并照顧好不被冒名頂替者殺死。玩家可以被投票下船,因此每場(chǎng)比賽都成為生存游戲。
數(shù)據(jù)
讓我們加載數(shù)據(jù)并再創(chuàng)建一個(gè)特征User ID;用戶 id 會(huì)告訴我們它像用戶 1、用戶 2 等哪個(gè)用戶。
import?glob
path?=?'archive'?
all_files?=?glob.glob(path?+?"/*.csv")
li?=?[]
usr=0
for?filename?in?all_files:
????usr+=1
????df?=?pd.read_csv(filename,?index_col=None,?header=0)
????df['User?ID']=usr
????li.append(df)
df?=?pd.concat(li,?axis=0,?ignore_index=True)
df[:2]

數(shù)據(jù)說(shuō)明
Game Completed Date-游戲完成的日期和時(shí)間 Team團(tuán)隊(duì)- 告訴我們玩家是冒名頂替者還是船員 Outcome結(jié)果- 告訴我們游戲是否贏/輸 Task Completed已完成的任務(wù) - 船員完成的任務(wù)數(shù) All Tasks Completed?– 布爾變量顯示所有任務(wù)是否由船員完成 Murdered謀殺- 船員是否被謀殺 Imposter Kills冒名頂替者殺死?– 冒名頂替者的擊殺次數(shù) Game Length游戲時(shí)長(zhǎng)——游戲的總持續(xù)時(shí)間 Ejected?- 玩家是否被其他玩家驅(qū)逐 Sabotages Fixed?– 船員修復(fù)的破壞次數(shù) Time to complete all tasks完成所有任務(wù)的時(shí)間——船員完成任務(wù)所用的時(shí)間 Rank Change排名變化- 比賽輸/贏后排名的變化 Region/Game Code地區(qū)/游戲代碼- 服務(wù)器和游戲代碼 User ID用戶 ID?–用戶數(shù)量。
注意:本文不包含 EDA,但展示了如何在 Bokeh 中使用不同的圖表
看看數(shù)據(jù)的分布。
df.describe(include='O')

我們將創(chuàng)建一個(gè)特征 Minute 并從 Game Lenght 中提取數(shù)據(jù)。
df['Min']?=?df.apply(lambda?x?:?x['Game?Length'].split("?")[0]?,?axis?=?1)
df['Min']?=?df['Min'].replace('m',?'',?regex=True)
df['Min'][:2]
0 07
1 16
Name: Min, dtype: object
現(xiàn)在,我們將替換 Murdered 特征的值。
df['Murdered'].replace(['No',?'Yes',?'-'],?['Not?Murdered',?'Murdered',?'Missing'],inplace=True)
完成必要的清潔步驟后。首先,讓我們看看Bokeh中的基本圖表。
餅形圖
檢查一下游戲中是否有更多的船員或冒名頂替者,我們有總共 2227 人的數(shù)據(jù)。
df_team?=?df.Team.value_counts()
df_team.plot_Bokeh(kind='pie',?title='Ration?of?Mposter?vs?Crewmate')

如圖所示,Cremates 占?79%,Imposters 占?21%,由此可見(jiàn)?Imposter: Crewmates?的比例為1:4。冒名頂替者較少,因此有可能贏得大部分比賽。
圓環(huán)圖
檢查游戲中是否有更多的船員或冒名頂替者被謀殺。我們將添加兩個(gè)我們將在圖表中使用的功能 Angle 和 Color。
from?math?import?pi
df_mur?=?df.Murdered.value_counts().reset_index().rename(columns={'index':?'Murdered',?'Murdered':?'Value'})
df_mur['Angle']?=?df_mur['Value']/df_mur['Value'].sum()?*?2*pi
df_mur['Color']?=?['#3182bd',?'#6baed6',?'#9ecae1']
df_mur

將用annular_wedge()做一個(gè)圓環(huán)圖。
from?Bokeh.transform?import?cumsum
fig?=?figure(plot_height=350,?
?????????????title="Ration?of?Murdered?vs?Not?Murdered",?
?????????????toolbar_location=None,
tools="hover",?tooltips="@Murdered:?@Value",?x_range=(-.5,?.5))
fig.annular_wedge(x=0,?y=1,?inner_radius=0.15,?
??????????????????outer_radius=0.25,?direction="anticlock",
start_angle=cumsum('Angle',?include_zero=True),
??????????????????end_angle=cumsum('Angle'),
line_color="white",?fill_color='Color',?legend_label='Murdered',?source=df_mur)
fig.axis.axis_label=None
fig.axis.visible=False
fig.grid.grid_line_color?=?None
show(fig)

大多數(shù)人在游戲中被謀殺,但大部分?jǐn)?shù)據(jù)丟失。所以我們不能說(shuō)大多數(shù)人是在游戲中被謀殺的。
散點(diǎn)圖
首先,將創(chuàng)建 Sabotages fixed 和 Minutes 的數(shù)據(jù)框,并更改列名并在其中添加 T。
df_min?=?pd.crosstab(df['Min'],?df['Sabotages?Fixed']).reset_index()
df_min?=?df_min.rename(columns={0.0:'0T',?1.0:'1T',
???????????????????????2.0:'2T',3.0:'3T',4.0:'4T',5.0:'5T'
????????????????????})
df_min[:2]

將 3 次破壞固定為?0,1 和 2?并創(chuàng)建一個(gè)數(shù)據(jù)框。
df_0?=?df_min[['Min',?'0T']]
df_1?=?df_min[['Min',?'1T']]
df_2?=?df_min[['Min',?'2T']]
要制作只有一個(gè)圖例的簡(jiǎn)單散點(diǎn)圖,我們可以傳遞數(shù)據(jù)并使用scatter()它來(lái)制作圖表。
df_min.plot_Bokeh.scatter(x='Min',?y='1T')

要制作包含多個(gè)圖例的散點(diǎn)圖,我們需要使用圓圈;這是圖形對(duì)象的一種方法。圓圈是Bokeh提供的眾多繪圖樣式之一,您可以使用三角形或更多。
fig?=?figure(title='Sabotages?Fixed?vs?Minutes',?
?????????????tools=?'hover',?
?????????????toolbar_location="above",?
?????????????toolbar_sticky=False)
fig.circle(x="Min",y='0T',?
?????????size=12,?alpha=0.5,?
?????????color="#F78888",?
?????????legend_label='0T',?
?????????source=df_0),
fig.circle(x="Min",y='1T',?
?????????size=12,?alpha=0.5,?
?????????color="blue",?
?????????legend_label='1T',?
?????????source=df_1),
fig.circle(x="Min",y='2T',?
?????????size=12,?alpha=0.5,?
?????????color="#626262",?
?????????legend_label='2T',?
?????????source=df_2),
show(fig)

簡(jiǎn)單直方圖
看看游戲之間的分鐘分布。將用hist來(lái)繪制直方圖。
df_minutes?=?df['Min'].astype('int64')
df_minutes.plot_Bokeh(kind='hist',?title='Distribution?of?Minutes')

大多數(shù)比賽有6分鐘到14分鐘的時(shí)間。
堆積直方圖
看看游戲長(zhǎng)度是否會(huì)增加,因此冒名頂替者和船員會(huì)減少還是增加。我們將使用?hist來(lái)制作堆疊直方圖。
df_gm_te?=?pd.crosstab(df['Game?Length'],?df['Team'])
df_gm_te

df_gm_te.plot_Bokeh.hist(title='Gamelegth?vs?Imposter/Crewmate',?figsize=(750,?350))

冒名頂替者不傾向于長(zhǎng)時(shí)間玩游戲,他們只想殺死所有火葬并贏得游戲。
不同類(lèi)型的條形圖
簡(jiǎn)單條形圖
看看給定的任務(wù)是否由人完成。如果所有任務(wù)都完成,那么自動(dòng)火葬將獲勝。
df_tc?=?pd.DataFrame(df['Task?Completed'].value_counts())[1:].sort_index().rename(columns={'Task?Completed':?'Count'})
df_tc.plot_Bokeh(kind='bar',?y='Count',?title='How?many?people?have?completed?given?task?',?figsize=(750,?350))

完成最多的任務(wù)是 7 個(gè),完成最少的任務(wù)是 10 個(gè)。
堆積條形圖
看看誰(shuí)贏了:冒名頂替者或火葬。我一直覺(jué)得冒名頂替者獲勝最多,因?yàn)樗麄冎挥幸环莨ぷ骺梢詺⑺浪腥恕?/p>
df1?=?pd.crosstab(df['Team'],?df['Outcome'])
df1.plot_Bokeh.bar(title='Who?wins:?Imposter?or?Crewmates',stacked=True,
figsize=(550,?350))

冒名頂替者比 Crewmates 贏得更多。Imposter贏得或輸?shù)舯荣悰](méi)有太大區(qū)別,價(jià)值非常接近。很多情況下,他們有5個(gè)火葬場(chǎng)和4個(gè)冒名頂替者。
堆積垂直條形圖
完成任務(wù)會(huì)不會(huì)贏得比賽讓我們拭目以待。
df['All?Tasks?Completed'].replace(['Yes','No'],?['Tasks?Completed','Tasks?Not?Completed'],?inplace=True)
df2?=?pd.crosstab(df['Outcome'],?df['All?Tasks?Completed'])
df2.plot_Bokeh.barh(title='Completeing?task:?win?or?loss',?stacked=True,
figsize=(650,?350))

完成任務(wù)將自動(dòng)贏得火葬。完成任務(wù)贏得比賽的人數(shù)更多。
雙向條形圖
用雙向條形圖看看用戶是贏了還是輸了。要制作雙向條形圖,我們需要將一個(gè)度量設(shè)為負(fù)值,這里我們將損失特征設(shè)為負(fù)值。
df_user?=?pd.crosstab(df['User?ID'],?df['Outcome']).reset_index()
df_user['Loss']?=?df_user['Loss']*-1
df_user['User?ID']?=?(df_user.index+1).astype(str)?+?'?User'
df_user?=?df_user.set_index('User?ID')
df_user[:2]
現(xiàn)在完成上面的過(guò)程后,我們只需要barh()?在兩個(gè)方向上制作一個(gè)條形圖即可。
df_user.plot_Bokeh.barh(title='Users:?Won?or?Defeat')

從圖表中,我們可以輕松區(qū)分用戶是被擊敗還是贏得了比賽。
折線圖
看看游戲中火化的排出比例。我們將line?用來(lái)制作折線圖。
df_crewmate?=?df[df['Team']?==?'Crewmate']
df_t_ej?=?pd.crosstab(df_crewmate['User?ID'],?df_crewmate['Ejected']).reset_index()
df_t_ej?=?df_t_ej[['No','Yes']]
df_t_ej.plot_Bokeh.line(title='Cremates?Memebers:?Ejected?vs?Minutes',?figsize=(750,?350))

沒(méi)有被逐出游戲的成員存在很大差異。
棒棒糖圖表
將獲勝的前 10 名用戶的圖表可視化。我在所有用戶 ID 中添加了一個(gè)用戶字符串。數(shù)據(jù)框看起來(lái)像這樣。
df_user_new?=?pd.crosstab(df['User?ID'],?df['Outcome']).reset_index().sort_values(by='Win',?ascending=False)[:10]
df_user_new['User?ID']?=?(df_user_new.index+1).astype(str)?+?'?User'
df_user_new[:2]
在此圖表中,我們將從圖表中刪除 x 軸和 y 軸網(wǎng)格線。為了制作棒棒糖圖表,我們需要結(jié)合 segment() 和circle()。
x?=?df_user_new['Win']
factors?=?df_user_new['User?ID']?#.values
fig?=?figure(title="Top?10?Users:?Win",?toolbar_location=None,tools="hover",?tooltips="@x",
y_range=factors,?x_range=[0,75],
plot_width=750,?plot_height=350)
fig.segment(0,?factors,?x,?factors,?line_width=2,?line_color="#3182bd")
fig.circle(x,?factors,?size=15,?fill_color="#9ecae1",?line_color="#3182bd",?line_width=3)
fig.xgrid.grid_line_color?=?None
fig.ygrid.grid_line_color?=?None
show(fig)

面積圖
看看在這段時(shí)間(分鐘)內(nèi)修復(fù)了多少破壞事件。在這里為了簡(jiǎn)單起見(jiàn),我們將只看到兩個(gè)破壞活動(dòng) 0th 和 1st。
from?Bokeh.models?import?ColumnDataSource
from?Bokeh.plotting?import?figure,?output_file,?show
#?data
df_min?=?pd.crosstab(df['Min'],?df['Sabotages?Fixed']).reset_index()
df_min?=?df_min.rename(columns={0.0:'0T',?1.0:'1T',2.0:'2T',3.0:'3T',4.0:'4T',5.0:'5T'})
#?chart
names?=?['0T','1T']
source?=?ColumnDataSource(data=dict(x?=?df_min.Min,
????????????????????????????????????y0?=?df_min['0T'],
????????????????????????????????????y1?=?df_min['1T']))
fig?=?figure(width=400,?height=400,?title='Sabotages?Fied?vs?Minutes')
fig.varea_stack(['y0','y1'],?x='x',?color=("grey",?"lightgrey"),legend_label=names,?source=source)
fig.grid.grid_line_color?=?None
fig.xaxis.axis_label='Minutes'
show(fig)

隨著時(shí)間的增加,破壞活動(dòng)會(huì)減少。
到目前為止,我們已經(jīng)看到了Bokeh中的所有基本圖表,現(xiàn)在看看如何在Bokeh中使用布局。這將幫助我們創(chuàng)建儀表板或應(yīng)用程序。因此,我們可以將特定用例的所有信息集中在一個(gè)地方。
Bokeh庫(kù)的布局功能
Layout 函數(shù)將讓我們構(gòu)建一個(gè)由繪圖和小部件組成的網(wǎng)格。我們可以在一個(gè)布局中擁有盡可能多的行和列或網(wǎng)格。
有許多可用的布局選項(xiàng):
如果要垂直顯示圖,請(qǐng)使用** column()**函數(shù)。如果要水平顯示圖,請(qǐng)使用** row()**函數(shù)。如果您希望以網(wǎng)格方式繪制圖形,請(qǐng)使用** gridplot()**函數(shù)。如果您希望圖表以最佳方式放置,請(qǐng)使用** layout()**函數(shù)
取一個(gè)虛擬數(shù)據(jù)。
from?Bokeh.io?import?output_file,?show
from?Bokeh.layouts?import?row,column
from?Bokeh.plotting?import?figure
output_file("layout.html")
x?=?list(range(11))
y0?=?x
y1?=?[10?-?i?for?i?in?x]
y2?=?[abs(i?-?5)?for?i?in?x]
#?create?three?plots
s1?=?figure(width=250,?height=250,?background_fill_color="#fafafa")
s1.circle(x,?y0,?size=12,?color="#53777a",?alpha=0.8)
s2?=?figure(width=250,?height=250,?background_fill_color="#fafafa")
s2.triangle(x,?y1,?size=12,?color="#c02942",?alpha=0.8)
s3?=?figure(width=250,?height=250,?background_fill_color="#fafafa")
s3.square(x,?y2,?size=12,?color="#d95b43",?alpha=0.8)
如果我們使用?column()?函數(shù),輸出將如下所示。
show(column(s1,?s2,?s3))

如果我們使用?row()?函數(shù),輸出將如下所示。
#?將結(jié)果排成一行并顯示
show(row(s1,?s2,?s3))

在 Bokeh 中制作儀表板布局。在這里我拍了三張圖表,一張是棒棒糖圖,另外兩張是Bokeh的餅圖。
在Bokeh中設(shè)置布局的主要邏輯是我們希望如何設(shè)置圖表。創(chuàng)建一個(gè)如下圖所示的設(shè)計(jì)。

layout?=?grid([[fig1],
???????????????[fig2,?fig3]])
在 Bokeh 中運(yùn)行儀表板布局的整個(gè)代碼。
from?Bokeh.io?import?output_file,?show
from?Bokeh.plotting?import?figure
from?Bokeh.layouts?import?column,?grid
#?1?layout
df_user_new?=?pd.crosstab(df['User?ID'],?df['Outcome']).reset_index().sort_values(by='Win',?ascending=False)[:10]
df_user_new['User?ID']?=?(df_user_new.index+1).astype(str)?+?'?User'
x?=?df_user_new['Win']
factors?=?df_user_new['User?ID']?
fig1?=?figure(title="Top?10?Users:?Win",?toolbar_location=None,
??????????????tools="hover",?tooltips="@x",
??????????????y_range=factors,?x_range=[0,75],?
??????????????width=700,?height=250)
fig1.segment(0,?factors,?x,?factors,?line_width=2,?line_color="#3182bd")
fig1.circle(x,?factors,?size=15,?fill_color="#9ecae1",?line_color="#3182bd",?line_width=3)
#?2?layout
df_mur?=?df.Murdered.value_counts().reset_index().rename(columns={'index':?'Murdered',?'Murdered':?'Value'})
df_mur['Angle']?=?df_mur['Value']/df_mur['Value'].sum()?*?2*pi
df_mur['Color']?=?['#3182bd',?'#6baed6',?'#9ecae1']
fig2?=?figure(height=300,width=400,?title="Ration?of?Murdered?vs?Not?Murdered",?
??????????????toolbar_location=None,?tools="hover",?tooltips="@Murdered:?@Value",?x_range=(-.5,?.5))
fig2.annular_wedge(x=0,?y=1,??inner_radius=0.15,?outer_radius=0.25,?direction="anticlock",
???????????????????start_angle=cumsum('Angle',?include_zero=True),?end_angle=cumsum('Angle'),
???????????????????line_color="white",?fill_color='Color',?legend_label='Murdered',?source=df_mur)
#?3?layout
df_team?=?pd.DataFrame(df.Team.value_counts()).reset_index().rename(columns={'index':?'Team',?'Team':?'Value'})
df_team['Angle']?=?df_team['Value']/df_team['Value'].sum()?*?2*pi
df_team['Color']?=?['#3182bd',?'#6baed6']
fig3?=?figure(height=300,?width=300,?title="Ration?of?Cremates?vs?Imposter",??
??????????????toolbar_location=None,?tools="hover",?tooltips="@Team:?@Value",?x_range=(-.5,?.5))
fig3.annular_wedge(x=0,?y=1,??inner_radius=0.15,?outer_radius=0.25,?direction="anticlock",
???????????????????start_angle=cumsum('Angle',?include_zero=True),?end_angle=cumsum('Angle'),
???????????????????line_color="white",?fill_color='Color',?legend_label='Team',?source=df_team)
#?Styling
for?fig?in?[fig1,?fig2,?fig3]:
????????fig.grid.grid_line_color?=?None
for?fig?in?[fig2,?fig3]:
????????fig.axis.visible=False
????????fig.axis.axis_label=None
layout?=?grid([
????????????????[fig1],
????????????????[fig2,?fig3]
???????])
show(layout)

原文作者:Kashish Rastogi ?
編輯:公眾號(hào) 數(shù)據(jù)STUDIO
往期推薦 點(diǎn)擊查看
推薦閱讀
推薦閱讀
