2025年6月8日 星期日

Streamlit 學習筆記 : 內建統計圖表 (四) 區域圖

本篇旨在測試 Streamlit 內建統計圖表函式中的區域圖函式 st.area_chart() :


 函式名稱 說明
 st.line_chart() 繪製折線圖,適合用來呈現時間序列或連續變化的資料。
 st.bar_chart() 繪製長條圖,適合用來比較各分類資料的數值大小。
 st.scatter_chart() 繪製散佈圖,用於顯示兩個變數之間的關係(需 DataFrame 格式資料)。
 st.area_chart() 繪製區域圖,類似折線圖,但底部會填滿陰影,強調總量變化。
 st.map() 在地圖上繪製地理座標點,支援 DataFrame 中包含緯度與經度的資料。


本系列所有測試文章參考 :



4. 區域圖函式 st.area_chart() : 

區域圖與折線圖類似, 用來顯示時間序列資料 (如銷售趨勢, 氣溫變化等) 隨時間或數值變化的趨勢, 但區域圖在折線下方會填滿顏色, 方便觀察數值累積或變動面積 (故又稱為面積圖), 它比折線圖多了 "累積量" 的訊息, 強調 "填滿" 的感覺. 如果資料包含多欄數值, 區域圖會自動顯示多條區域線. 其參數結構如下 : 

st.area_chart(data=None, x=None, y=None, x_label=None, y_label=None, color=None, stack=None, width=None, height=None, use_container_width=True)

參數說明如下表 :


 st.area_chart() 參數  說明
 data  要繪製的資料 (預設 None),支援 DataFrame、numpy 陣列、字典等格式
 x  指定 x 軸的欄位名稱 (預設 None 使用資料的索引作為 x 軸)。
 y  指定 y 軸的欄位名稱 (預設 None 繪製所有剩餘欄位),字串或字串串列。
 x_label  x 軸的標籤文字 (預設 None 使用 x 參數的欄位名稱或無標籤)。 
 y_label  y 軸的標籤文字 (預設 None 使用 y 參數的欄位名稱或無標籤)。 
 color  自定義圖表顏色 (預設 None),可為十六進位字串、RGB 顏色或其串列。
 stack  控制面積圖堆疊方式 (預設 None)。可為 True(堆疊)、False(重疊)、"normalize"(標準化)或 "center"(居中)。
 width  圖表寬度 (像素,預設 None 自動調整寬度)。使用時需同時設定 use_container_width=False。
 height  圖表高度 (像素,預設 None 依據內容自動調整高度)
 use_container_width  是否使用容器寬度 (預設 True 圖表會填滿容器寬度,設為 False 則使用 width 參數值。


注意, color 參數須 v1.13+ 以上才支援. 

例如 : 


測試 4-1 : 一個 Y 軸資料的區域圖 [看原始碼]   

# st-area-chart-test-1.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['一月', '二月', '三月', '四月', '五月'],
    '營收': [120000, 135000, 95000, 150000, 170000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(data=data, x='月份', y='營收')

此例只有一個 Y 軸資料, 所以用 x 與 y 參數直接指定 X 與 Y 軸欄位, 結果如下 :




區域下的面積代表累積的營收. 注意, X 軸並沒有按照一月~五月順序排序, 這是因為 Streamlit 在處理中文字串時會按照 Unicode 字母順序排列而非按照預期的中文月份邏輯順序, 最簡單的解決辦法是把 X 軸的月份改成阿拉伯數字, 例如 : 


測試 4-2 : 修正 X 軸中文排序問題的第種做法 [看原始碼]   

# st-area-chart-test-2.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['1月', '2月', '3月', '4月', '5月'],
    '營收': [120000, 135000, 95000, 150000, 170000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(data, x='月份', y='營收')

此例將月份資料改成用阿拉伯數字,  結果如下 :



這樣 X 軸的排序就正常了. 

但是如果 X 軸非要使用中文不可, 那麼可以利用 Pandas 的 Categorical 類別將 X 軸欄位變成 Categorical 物件後進行排序, 作法如下 :


測試 4-3 : 修正 X 軸中文排序問題的第二種做法 [看原始碼]   

# st-area-chart-test-3.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['一月', '二月', '三月', '四月', '五月'],
    '營收': [120000, 135000, 95000, 150000, 170000]
    })
month=['一月', '二月', '三月', '四月', '五月']
# 轉成 Categorical 物件
data['月份']=pd.Categorical(data['月份'], categories=month, ordered=True)  
data=data.sort_values('月份')  # 依據月份欄排序
st.subheader('今年前五月月營收區域圖')
st.area_chart(data=data, x='月份', y='營收')

結果如下 : 




可見中文月份的 X 軸已經照順序排列了. 從上面的範例可知, st.area_chart() 在只有一個 Y 軸資料時預設會用深藍色填滿資料點折線下的面積, 這顏色可以用 color 參數來設定, 下面範例同時測試 color 與 x_label, y_label 參數 : 


測試 4-4 : 測試 color, x_label, 與 x_label 參數的功能 [看原始碼]   

# st-area-chart-test-4.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['1月', '2月', '3月', '4月', '5月'],
    '營收': [120000, 135000, 95000, 150000, 170000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(
    data,
    x='月份',
    y='營收',
    color='#FF6B6B',
    x_label='2025 年前五月',
    y_label='營收 (單位: 元)'
    )

結果如下 :




接下來測試有兩個 Y 軸資料的情形 : 


測試 4-5 : 兩個 Y 軸資料的區域圖 (1) [看原始碼]   

# st-area-chart-test-5.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['1月', '2月', '3月', '4月', '5月'],
    '師大店營收': [120000, 135000, 95000, 150000, 170000],
    '內湖店營收': [90000, 102000, 99000, 130000, 160000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(
    data,
    x='月份',
    y=['師大店營收', '內湖店營收']
    )

此例因為有兩個 Y 軸資料, y 參數改為傳入兩個 Y 軸欄位名稱之串列 (v1.12+ 起支援), 結果如下 :




可見 st.area_chart() 會把累積面積比較大的用較淡顏色表示, 這樣面積較小的才不會被蓋掉. 也可以不用 x 與 y 參數, 而是用 df.set_index() 設定索引欄位並選取 Y 軸資要欄位, 例如 :


測試 4-6 : 兩個 Y 軸資料的區域圖 (2) [看原始碼]   

# st-area-chart-test-6.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['一月', '二月', '三月', '四月', '五月'],
    '師大店營收': [120000, 135000, 95000, 150000, 170000],
    '內湖店營收': [90000, 102000, 99000, 130000, 160000]
    })
st.subheader('今年前五月月營收區域圖')
chart_data=data.set_index('月份')[['師大店營收', '內湖店營收']]
st.area_chart(
    chart_data,
    color=['#FF6B6B', '#4ECDC4'],
    x_label='月份',
    y_label='營收(單位:元)'    
    )

此例 st.area_chart() 會自動將索引欄位 '月份' 當作 X 軸, 用 [] 選取了兩個欄位做為 Y 軸資料欄位, 結果如下 : 





下面範例測試 stack 參數為 True 的效果 :


測試 4-7 : 參數 stack=True 的效果 [看原始碼]   

# st-area-chart-test-7.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['1月', '2月', '3月', '4月', '5月'],
    '師大店營收': [120000, 135000, 95000, 150000, 170000],
    '內湖店營收': [90000, 102000, 99000, 130000, 160000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(
    data=data,
    x='月份',
    y=['師大店營收', '內湖店營收'],
    stack=True
    )

此例將 stack 參數設為 True, 其作用是會將每個資料點的 Y 軸疊加, 例如一月份的營收兩家店加起來就是 120000+90000=210000, 這樣最上面的值就是總營收, 結果如下 :




預設 stack=None 其實就是 False, 各 Y 軸資料是重疊顯示, 所以面積圖會互相遮住. 

下面範例測試 stack 參數為 'normalize' 的效果 :


測試 4-8 : 參數 stack='normalize' 的效果 [看原始碼]   

# st-area-chart-test-8.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['1月', '2月', '3月', '4月', '5月'],
    '師大店營收': [120000, 135000, 95000, 150000, 170000],
    '內湖店營收': [90000, 102000, 99000, 130000, 160000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(
    data=data,
    x='月份',
    y=['師大店營收', '內湖店營收'],
    stack='normalize'
    )

stack='normalize' 會將每個資料系列的 Y 值轉換為相對比例以確保所有系列在每個 X 軸點的總和為 1 (或 100%), 圖表的總高度被標準化為固定值 (通常為 1), 每個系列的面積表示其在總量中的占比, 結果如下 :




面積圖會以堆疊方式顯示, 但總高度固定為 1, 面積大小反映各系列的相對貢獻比例, 適合用來比較多個系列在總量中的分布情況 (例如不同店鋪營收的相對占比變化). 

下面範例測試 stack 參數為 'center' 的效果 :


測試 4-9 : 參數 stack='center' 的效果 [看原始碼]   

# st-area-chart-test-9.py
import streamlit as st
import pandas as pd

# 模擬每月營收資料
data=pd.DataFrame({
    '月份': ['1月', '2月', '3月', '4月', '5月'],
    '師大店營收': [120000, 135000, 95000, 150000, 170000],
    '內湖店營收': [90000, 102000, 99000, 130000, 160000]
    })
st.subheader('今年前五月月營收區域圖')
st.area_chart(
    data=data,
    x='月份',
    y=['師大店營收', '內湖店營收'],
    stack='center'
    )

stack='center' 從 Streamlit 1.18+ 開始支援, 它會將多個數據系列的 Y 值以中心堆疊的方式呈現, 這意味著各系列的 Y 值會圍繞一個中心點 (通常是 Y 軸的零點或平均值) 做對稱堆疊, 故資料會呈現上下對稱分佈, 而不是像 stack=True 或 stack="normalize" 那樣從 Y=0 開始堆疊, 因此適合用於資料包含正負值或需要突出相對變化的場景 (投資盈虧). 結果如下 :




可見每個資料系列 (Y 軸) 的面積會根據其值在中心點 (平均值) 上下堆疊, 但本例的資料都是正值, 所以其實並不適合採用 stack='center' 之設定. 

沒有留言 :