終於來到這波 Streamlit 密集學習月的最後一站 : 輸出 Altair 繪製的圖片. 與 Bokeh 一樣我之前也只是有聽過這套件卻從未用過, 所以花了兩三天先做了初步的測試, 紀錄在下面三篇筆記中 :
Streamlit 提供 st.altair_chart() 函式來輸出 Altair 繪製的圖表, 其參數結構如下 :
st.altair_chart(figure, use_container_width=True, theme="streamlit", tooltip=True)
| 參數名稱 | 說明 |
|---|---|
| chart | Altair 的圖表物件 Chart(通常由 alt.Chart() 建立) |
| use_container_width | 布林值,是否讓圖表自動填滿容器寬度,預設為 True |
| theme | 指定要套用的主題例如 "streamlit" 或 "none"(預設) |
| tooltip | 布林值,是否啟用互動工具提示,預設為 True |
必要參數為 Altair 的圖表物件 Chart, 只要將 Chart 物件傳給 st.altair_chart() 即可將圖片顯示在 Streamlit 的網頁中.
1. 折線圖 :
Altair 的折線圖繪製方法是 mark_line(), 例如 :
測試 1-1 : 輸出 Altair 折線圖 (1) [看原始碼]
# st-altair-line-test-1-1.py
import streamlit as st
import altair as alt
import pandas as pd
# 建立資料
df=pd.DataFrame({
'x': [0, 1, 2, 3, 4, 5], # x 軸資料
'y': [-5, -2, 6, 12, 4, 9] # y 軸資料
})
# 建立繪製折線圖的 Chart 物件
chart=alt.Chart(df).mark_line(
color='red', # 線的顏色
strokeWidth=4 # 線的粗細 (預設 2)
).encode(
x=alt.X('x', title='X 軸'), # 設定 X 軸標籤
y=alt.Y('y', title='Y 軸'), # 設定 Y 軸標籤
tooltip=['x', 'y'] # 資料點工具提示
).properties(
width=400, # 圖片寬 (px)
height=300, # 圖片高 (px)
title='Altair 折線圖', # 圖片標題
)
# 在 Streamlit 顯示圖表
st.altair_chart(chart, use_container_width=False)
此例因為指定了圖片尺寸, 所以要把 use_container_width 設為 False, 否則會放大到容器寬度, 結果如下 :
測試 1-2 : 輸出 Altair 折線圖 (2) [看原始碼]
# st-altair-line-test-1-2.py
import streamlit as st
import altair as alt
import pandas as pd
# 建立資料
df=pd.DataFrame({
'x': [0, 1, 2, 3, 4, 5], # x 軸資料
'y': [-5, -2, 6, 12, 4, 9] # y 軸資料
})
# 建立繪製折線圖的 Chart 物件
chart=alt.Chart(df).mark_line(
color='rgba(0, 0, 255, 0.5)', # 線的顏色
strokeWidth=4 # 線的粗細 (預設 2)
).encode(
x=alt.X('x', title='X 軸'), # 設定 X 軸標籤
y=alt.Y('y', title='Y 軸'), # 設定 Y 軸標籤
tooltip=['x', 'y'] # 資料點工具提示
).properties(
width=400, # 圖片寬 (px)
height=300, # 圖片高 (px)
title='Altair 折線圖', # 圖片標題
).configure_view(
fill='lightyellow' # 僅繪圖區背景色
).configure_title(
anchor='end', # 靠右
fontSize=16,
fontWeight='bold',
color='blue',
offset=15
)
# 在 Streamlit 顯示圖表
st.altair_chart(chart, use_container_width=False)
結果如下 :
2. 散布圖 :
Altair 的散布圖繪製方法是 mark_point(), 例如 :
測試 2-1 : 輸出 Altair 散布圖 (1) [看原始碼]
# st-altair-point-test-1.py
import streamlit as st
import altair as alt
import pandas as pd
# 建立資料
df=pd.DataFrame({
'x': [0, 1, 2, 3, 4, 5], # x 軸資料
'y': [-5, -2, 6, 12, 4, 9] # y 軸資料
})
# 建立繪製折線圖的 Chart 物件
chart=alt.Chart(df).mark_point(
filled=True, # 填滿為實心圓點
size=200, # 平方像素面積
color='red', # 填滿顏色
stroke='#0000FF', # 邊框顏色
strokeWidth=2, # 邊框
strokeOpacity=0.5 # 邊框透明度
).encode(
x='x',
y='y',
tooltip=['x', 'y'] # 資料點工具提示
).properties(
width=400, # 圖片寬 (px)
height=300, # 圖片高 (px)
title='Altair 散布圖' # 圖片標題
)
# 在 Streamlit 顯示圖表
st.altair_chart(chart, use_container_width=False)
結果如下 :
下面範例是利用分類欄位讓不同類別的資料點顯示不同之標記符號 (自動配色) :
測試 2-2 : 輸出 Altair 散布圖 (2) [看原始碼]
# st-altair-point-test-1.py
import streamlit as st
import altair as alt
import pandas as pd
# 建立資料
df=pd.DataFrame({
'x': [0, 1, 2, 3, 4, 5], # x 軸資料
'y': [-5, -2, 6, 12, 4, 9], # y 軸資料
'label': ['A', 'B', 'A', 'B', 'A', 'B'] # 資料分類
})
# 建立繪製折線圖的 Chart 物件
chart=alt.Chart(df).mark_point(
filled=True, # 填滿為實心圓點
size=200, # 平方像素面積
color='yellow', # 填滿顏色
stroke='navy'
).encode(
x=alt.X('x', title='X 軸'), # 設定 X 軸標籤
y=alt.Y('y', title='Y 軸'), # 設定 Y 軸標籤
shape='label', # 資料點的圖形分類欄位
color='label', # 顏色根據 label 分類
tooltip=['x', 'y'] # 資料點工具提示
).properties(
width=400, # 圖片寬 (px)
height=300, # 圖片高 (px)
title='Altair 散布圖' # 圖片標題
).configure_view(
fill='lightyellow' # 僅繪圖區背景色
)
st.altair_chart(chart, use_container_width=False)
結果如下 :
3. 長條圖 :
Altair 的長條圖繪製方法是 mark_bar(), 例如 :
測試 3-1 : 輸出 Altair 長條圖 (單組垂直) [看原始碼]
# st-altair-bar-test-1.py
import streamlit as st
import altair as alt
import pandas as pd
# 建立資料
df=pd.DataFrame({
'月份': ['一月', '二月', '三月', '四月', '五月'],
'營收': [120000, 135000, 99000, 150000, 170000]
})
# 建立繪製折線圖的 Chart 物件
chart=alt.Chart(df).mark_bar(
color='cyan', # 設定長條顏色
size=30, # 設定長條寬度 px
stroke='navy' # 設定邊框顏色
).encode(
x=alt.X('月份', sort=['一月', '二月', '三月', '四月', '五月']), # 列舉 X 軸順序
y='營收',
).properties(
width=400, # 圖片寬 (px)
height=300, # 圖片高 (px)
title='Altair 長條圖' # 圖片標題
)
st.altair_chart(chart, use_container_width=False)
結果如下 :
在 encode() 中把 X, Y 軸顛倒就會得到水平長條圖, 例如 :
測試 3-2 : 輸出 Altair 長條圖 (單組水平) [看原始碼]
# st-altair-bar-test-2.py
import streamlit as st
import altair as alt
import pandas as pd
# 建立資料
df=pd.DataFrame({
'月份': ['一月', '二月', '三月', '四月', '五月'],
'營收': [120000, 135000, 99000, 150000, 170000]
})
# 建立繪製折線圖的 Chart 物件
chart=alt.Chart(df).mark_bar(
color='cyan', # 設定長條顏色
size=30, # 設定長條寬度 px
stroke='navy' # 設定邊框顏色
).encode(
y=alt.Y('月份', sort=['一月', '二月', '三月', '四月', '五月']), # 列舉 Y 軸順序
x='營收',
).properties(
width=400, # 圖片寬 (px)
height=300, # 圖片高 (px)
title='Altair 長條圖' # 圖片標題
)
st.altair_chart(chart, use_container_width=False)
結果如下 :
下面範例是繪製兩組資料的群組式垂直長條圖 :
測試 3-3 : 輸出 Altair 群組式長條圖 (雙組垂直) [看原始碼]
# st-altair-bar-test-3.py
import streamlit as st
import altair as alt
import pandas as pd
# 原始資料
x=['一月', '二月', '三月', '四月', '五月']
y1=[120000, 135000, 99000, 150000, 170000]
y2=[100000, 125000, 87000, 140000, 160000]
# 將原始資料轉成長格式的 DataFrame
df=pd.DataFrame({
'月份': x * 2,
'營收': y1 + y2,
'類別': ['今年'] * len(x) + ['去年'] * len(x)
})
# 建立群組長條圖
chart=alt.Chart(df).mark_bar().encode(
x=alt.X(
'月份:N',
title='月份',
sort=['一月', '二月', '三月', '四月', '五月'],
axis=alt.Axis(labelAngle=0) # 軸刻度文字旋轉 0 度=水平
),
y=alt.Y('營收:Q', title='營收金額 (元)'),
color=alt.Color('類別:N', title='類別'),
xOffset='類別:N', # 依照指定欄位群組化顯示長條
tooltip=['月份', '類別', '營收']
).properties(
width=400,
height=300,
title='今年與去年每月營收比較'
)
st.altair_chart(chart, use_container_width=False)
注意此例使用 alt.Axis(labelAngle=0) 將 X 軸標籤角度設為 0 (水平), 群組化關鍵是用 xOffset 參數設定分組欄位名稱, 結果如下 :
繪製群組式水平長條圖只要將 encode() 裡的 x, y 軸顛倒, 而且用 yOffset 參數設定 Y 軸分組欄位名稱即可 :
測試 3-4 : 輸出 Altair 群組式長條圖 (雙組水平) [看原始碼]
# st-altair-bar-test-3.py
import streamlit as st
import altair as alt
import pandas as pd
# 原始資料
df=pd.DataFrame({
'月份': ['一月', '二月', '三月', '四月', '五月'],
'今年': [120000, 135000, 99000, 150000, 170000],
'去年': [100000, 125000, 87000, 140000, 160000]
})
# 將原始資料轉成長格式的 DataFrame
df=df.melt(
id_vars=['月份'], # 保持不變的欄位 (其他欄位要被融化)
value_name='營收', # 融化後新的數值欄位名稱
var_name='類別' # 要新增的分類欄位名稱
)
# 建立群組長條圖
chart=alt.Chart(df).mark_bar().encode(
y=alt.Y(
'月份:N',
title='月份',
sort=['一月', '二月', '三月', '四月', '五月'],
axis=alt.Axis(labelAngle=0) # 軸刻度文字旋轉 0 度=水平
),
x=alt.X('營收:Q', title='營收金額 (元)'),
color=alt.Color('類別:N', title='類別'),
yOffset='類別:N', # 依照指定欄位群組化顯示長條
tooltip=['月份', '類別', '營收']
).properties(
width=400,
height=300,
title='今年與去年每月營收比較'
)
st.altair_chart(chart, use_container_width=False)
此例改用 df.melt() 將原始寬格式 DataFrame 改成長格式, 結果如下 :
OK, 歷經一個半月的測試, 終於把 Streamlit 的基本功能學完了, 未來應用時如果有發現遺漏的或新的用法再來補充. 不過接下來會把 Streamlit 用在機器學習/深度學習的再整理與測試上.








沒有留言 :
張貼留言