基於Bokeh庫,手把手教你製作子彈圖和瀑布圖!
首先,讓我們進行匯入並使 Bokeh 的輸出顯示在我們的筆記本中:
from
bokeh。io
import
show
,
output_notebook
from
bokeh。palettes
import
PuBu4
from
bokeh。plotting
import
figure
from
bokeh。models
import
Label
output_notebook
()
子彈圖
在這個例子中,我們將用 python 列表填充資料。 我們可以修改它以適應Pandas資料框,但我們將堅持使用簡單的 Python 資料型別作為本示例:
data
=
[(
“John Smith”
,
105
,
120
),
(
“Jane Jones”
,
99
,
110
),
(
“Fred Flintstone”
,
109
,
125
),
(
“Barney Rubble”
,
135
,
123
),
(
“Mr T”
,
45
,
105
)]
limits
=
[
0
,
20
,
60
,
100
,
160
]
labels
=
[
“Poor”
,
“OK”
,
“Good”
,
“Excellent”
]
cats
=
[
x
[
0
]
for
x
in
data
]
一個棘手的程式碼部分,是在 y 軸上的 cat 變數中構建一個類別列表。
下一步是建立散景圖並設定幾個與 x 軸和網格線顯示方式相關的選項。 如上所述,我們使用cats變數來定義y_range中的所有類別。
p
=
figure
(
title
=
“Sales Rep Performance”
,
plot_height
=
350
,
plot_width
=
800
,
y_range
=
cats
)
p
。
x_range
。
range_padding
=
0
p
。
grid
。
grid_line_color
=
None
p
。
xaxis
[
0
]
。
ticker
。
num_minor_ticks
=
0
下一部分將使用散景的 hbar 建立彩色範圍條。 為了完成這項工作,我們需要定義每個條的左右範圍以及顏色。 我們可以使用python的zip函式來建立我們需要的資料結構。
zip
(
limits
[:
-
1
],
limits
[
1
:],
PuBu4
[::
-
1
])
# 結果如下:
[(
0
,
20
,
‘#f1eef6’
),
(
20
,
60
,
‘#bdc9e1’
),
(
60
,
100
,
‘#74a9cf’
),
(
100
,
160
,
‘#0570b0’
)]
以下是如何將它們組合在一起以建立顏色範圍。
for
left
,
right
,
color
in
zip
(
limits
[:
-
1
],
limits
[
1
:],
PuBu4
[::
-
1
]):
p
。
hbar
(
y
=
cats
,
left
=
left
,
right
=
right
,
height
=
0。8
,
color
=
color
)
結果如下:
我們使用類似的過程,為每個效能度量新增一個黑條。
perf
=
[
x
[
1
]
for
x
in
data
]
p
。
hbar
(
y
=
cats
,
left
=
0
,
right
=
perf
,
height
=
0。3
,
color
=
“black”
)
我們需要新增的最後一個標記是一個顯示目標值的段。
comp
=
[
x
[
2
]
for
x
in
data
]
p
。
segment
(
x0
=
comp
,
y0
=
[(
x
,
-
0。5
)
for
x
in
cats
],
x1
=
comp
,
y1
=
[(
x
,
0。5
)
for
x
in
cats
],
color
=
“white”
,
line_width
=
2
)
結果如下:
最後一步是為每個範圍新增標籤。 我們可以使用 zip 來建立我們需要的標籤結構,然後將每個標籤新增到佈局中。
for
start
,
label
in
zip
(
limits
[:
-
1
],
labels
):
p
。
add_layout
(
Label
(
x
=
start
,
y
=
0
,
text
=
label
,
text_font_size
=
“10pt”
,
text_color
=
‘black’
,
y_offset
=
5
,
x_offset
=
15
))
結果如下:
瀑布圖
構造資料框,用於作為演示的資料框。
# Create the initial dataframe
index
=
[
‘sales’
,
‘returns’
,
‘credit fees’
,
‘rebates’
,
‘late charges’
,
‘shipping’
]
data
=
{
‘amount’
:
[
350000
,
-
30000
,
-
7500
,
-
25000
,
95000
,
-
7000
]}
df
=
pd
。
DataFrame
(
data
=
data
,
index
=
index
)
# Determine the total net value by adding the start and all additional transactions
net
=
df
[
‘amount’
]
。
sum
()
結果如下:
最終的瀑布程式碼將要求我們為每個段定義幾個附加屬性,包括: - 起始位置; - 條形顏色; - 標籤位置; - 標籤文字;
透過將其新增到單個數據框中,我們可以使用 Bokeh 的內建功能來簡化最終程式碼。
對於下一步,我們將新增執行總計、段開始位置和標籤的位置。
df
[
‘running_total’
]
=
df
[
‘amount’
]
。
cumsum
()
df
[
‘y_start’
]
=
df
[
‘running_total’
]
-
df
[
‘amount’
]
# Where do we want to place the label?
df
[
‘label_pos’
]
=
df
[
‘running_total’
]
接下來,我們在包含淨值的資料框底部新增一行。
df_net
=
pd
。
DataFrame
。
from_records
([(
net
,
net
,
0
,
net
)],
columns
=
[
‘amount’
,
‘running_total’
,
‘y_start’
,
‘label_pos’
],
index
=
[
“net”
])
df
=
df
。
append
(
df_net
)
對於這個特定的瀑布,我希望將負值設定為不同的顏色,並設定圖表下方的標籤格式。 讓我們使用值向資料框中新增列。
df
[
‘color’
]
=
‘grey’
df
。
loc
[
df
。
amount
<
0
,
‘color’
]
=
‘red’
df
。
loc
[
df
。
amount
<
0
,
‘label_pos’
]
=
df
。
label_pos
-
10000
df
[
“bar_label”
]
=
df
[
“amount”
]
。
map
(
‘
{:,。0f}
’
。
format
)
這是包含我們需要的所有資料的最終資料框。 確實需要對資料進行一些操作才能達到這種狀態,但它是相當標準的 Pandas 程式碼,如果出現問題,很容易除錯。
建立實際繪圖是相當標準的 Bokeh 程式碼,因為資料框具有我們需要的所有值。
TOOLS
=
“box_zoom,reset,save”
source
=
ColumnDataSource
(
df
)
p
=
figure
(
tools
=
TOOLS
,
x_range
=
list
(
df
。
index
),
y_range
=
(
0
,
net
+
40000
),
plot_width
=
800
,
title
=
“Sales Waterfall”
)
透過將 ColumnDataSource 定義為我們的資料框,Bokeh 負責建立所有段和標籤,而無需進行任何迴圈。
p
。
segment
(
x0
=
‘index’
,
y0
=
‘y_start’
,
x1
=
“index”
,
y1
=
‘running_total’
,
source
=
source
,
color
=
“color”
,
line_width
=
55
)
我們將做一些小的格式化來新增標籤並很好地格式化 y 軸。
p
。
grid
。
grid_line_alpha
=
0。3
p
。
yaxis
[
0
]
。
formatter
=
NumeralTickFormatter
(
format
=
“($ 0 a)”
)
p
。
xaxis
。
axis_label
=
“Transactions”
最後一步是使用 LabelSet 將所有標籤新增到條形圖上。
labels
=
LabelSet
(
x
=
‘index’
,
y
=
‘label_pos’
,
text
=
‘bar_label’
,
text_font_size
=
“8pt”
,
level
=
‘glyph’
,
x_offset
=-
20
,
y_offset
=
0
,
source
=
source
)
p
。
add_layout
(
labels
)
結果如下:
上一篇:內容運營框架參考
下一篇:我喜歡的男生說饞我身子怎麼辦?