2025年6月15日 星期日

Python 學習筆記 : 用 Altair 繪製互動式圖表 (二) 散布圖

本篇旨在測試 Altair 套件的散布圖繪製方法 chart.make_point(). 關於 Altair 的基本用法參考本系列之前一篇文章 :


摘要說明 Altair 繪製圖表的六個步驟 : 
  1. 建立資料 : DataFrame 
  2. 建立圖表物件 : 呼叫建構式 Chart() 並傳入 DataFrame
  3. 指定圖表類型 : 例如折線圖 mark_line()
  4. 指定欄位如何呈現 : 呼叫 encode() 方法
  5. 設定外觀屬性 : 呼叫 properties() 方法
  6. 設定互動性 : 呼叫 interactive() 方法
從第二步建立 Chart 物件後, 每一個方法都會傳回更新 JSON 設定後的 Chart 物件, 故這些方法可使用鏈式呼叫. 

繪製散布圖第三步驟要呼叫 Chart 物件的 mark_point() 方法, 其常用參數如下表所示 :


mark_point() 參數 說明
filled 設定為 True 時,圓點為實心;預設為 False(空心)
size 設定點的大小(預設 30 平方像素),除以 pi 開根號才是半徑 px
color 設定點的顏色 (預設黑色),例如 'red''rgba(255,0,0,0.5)'
opacity 透明度,介於 0(全透明)與 1(不透明,預設)之間
shape 點的形狀,例如 'circle' (預設), 'square', 'triangle'
stroke 點邊框顏色,例如 'black'
strokeWidth 邊框寬度(預設 1 像素)
strokeOpacity 邊框透明度 (預設 1)


注意, 其中 size 參數的單位不是像素, 而是是圖形面積 (平方像素 pixels²), 除以 pi 再開根號才會得到圓點的半徑, 預設是 30, 半徑大約是 3.1px, 設為 100 大約半徑是 5.6px. 

資料點的形狀預設為圓點 ("circle"), 但也可以設定為其它符號, 可用符號如下表 : 


shape 參數值 符號 說明
"circle" 圓形(預設)
"square" 方形
"cross" 十字形
"diamond" 菱形
"triangle-up" 上三角形
"triangle-down" 下三角形
"triangle-left" 左三角形
"triangle-right" 右三角形


如果資料點有分類, 則可在 encode() 用 shape 參數指定圖形之類別欄位, 這時 shape 會依據下表繪製不同的資料點符號 :


encode() 的 shape 參數值 對應圖形(Vega Shape 名稱)
0circle
1square
2cross
3diamond
4triangle-up
5triangle-down
6triangle-right
7triangle-left
8stroke (outline circle)
9–25其他內建幾何圖形(不常用)


例如 : 


測試 1 : 預設的圓點散布圖 [看原始碼] 

# altair-points-test-1.py
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().encode(
    x='x',
    y='y'
    )
chart.save('altair-points-test-1.html')

結果如下 :



可見預設為有邊框的空心圓點, 下面範例則是設定為無邊框之實心紅色圓點 : 


測試 2 : 設定 color, filled, size 與 strokeWidth 參數的圓點散布圖 [看原始碼]  

# altair-points-test-2.py
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=100,    # 平方像素面積
    color='red',   # 填滿顏色
    strokeWidth=0  # 無邊框
    ).encode(
    x='x',
    y='y',
    tooltip=['x', 'y']   # 資料點工具提示
    ).properties(
    width=400,   # 圖片寬 (px)
    height=300,  # 圖片高 (px)
    title='Altair 散布圖'  # 圖片標題
    )
chart.save('altair-points-test-2.html')

結果如下 : 




下面範例測試邊框的顏色, 粗細, 與透明度 : 


測試 3 : 設定 color, filled, size 與 strokeWidth 參數的圓點散布圖 [看原始碼]  

# altair-points-test-3.py
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 散布圖'  # 圖片標題
    )
chart.save('altair-points-test-3.html')

此例將圓點面積放大以利觀察, 邊框顏色改用 "#RRGGBB" 格式, 結果如下 :




可見 0.5 的透明度讓邊框顏色沒那麼藍. 其實也可以不用 strokeOpacity 參數, 改用 "rgba(r, g, b, a)" 格式也可以有相同效果, 例如 : 


測試 4 : 用 stroke='rgba(r, g, b, a)' 設定邊框透明度 [看原始碼]  

# altair-points-test-4.py
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='rgba(0, 0, 255, 0.5)',   # 邊框顏色
    strokeWidth=2  # 邊框
    ).encode(
    x='x',
    y='y',
    tooltip=['x', 'y']   # 資料點工具提示
    ).properties(
    width=400,   # 圖片寬 (px)
    height=300,  # 圖片高 (px)
    title='Altair 散布圖'  # 圖片標題
    )
chart.save('altair-points-test-4.html')

此例移除 strokeOpacity 參數, 邊框透明度改成在 stroke 參數的 "rgba(r, g, b, a)" 中用 a 設定, 結果與上例相同. 

除了圓點外也可以用 shape 參數設定為其它圖形, 例如方點 : 


測試 5 : 用 shape 參數設定資料點的圖形 [看原始碼]  

# altair-points-test-5.py
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='yellow',  # 填滿顏色
    shape='square',  # 方形資料點
    stroke='navy'
    ).encode(
    x='x',
    y='y',
    tooltip=['x', 'y']   # 資料點工具提示
    ).properties(
    width=400,   # 圖片寬 (px)
    height=300,  # 圖片高 (px)
    title='Altair 散布圖'  # 圖片標題
    )
chart.save('altair-points-test-5.html')

此例將資料點設為方形, 結果如下 :




資料點也可以進行分類讓不同類別的資料顯示不同的資料點圖形, 例如 :


測試 6 : 在 encode() 中用 shape 參數設定資料點的分類圖形 [看原始碼]  

# altair-points-test-6.py
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='x',
    y='y',
    shape='label',  # 資料點的圖形分類欄位
    tooltip=['x', 'y']   # 資料點工具提示
    ).properties(
    width=400,   # 圖片寬 (px)
    height=300,  # 圖片高 (px)
    title='Altair 散布圖'  # 圖片標題
    )
chart.save('altair-points-test-6.html')

此例在 DataFrame 中增加一個 label 欄位來標示資料點分類為 A, B 兩類, 然後於 encode() 中傳入 shape 參數指定以此 label 欄位做為圖形分類, Altair 會根據資料中 label 欄位的類別順序為每個類別自動分配一個圖形 (shape) 索引, 此例 A 類被分到索引 0, B 類被分到索引 1, 依據上面的索引與圖形對照表, 索引 0 為圓形資料點, 索引 1 為方形資料點, 結果如下 : 




上例中不論分類是圓點或方點的資料點圖形均為黃色, 可以在 encode() 中傳入 color 參數並指定值為 'label', 這樣 Altair 就會依照欄位不同自動為每個分類配色, 例如 : 


測試 7 : 讓不同分類的資料點顏色不同 [看原始碼]  

# altair-points-test-7.py
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='x',
    y='y',
    shape='label',  # 資料點的圖形分類欄位
    color='label',  # 顏色根據 label 分類
    tooltip=['x', 'y']   # 資料點工具提示
    ).properties(
    width=400,   # 圖片寬 (px)
    height=300,  # 圖片高 (px)
    title='Altair 散布圖'  # 圖片標題
    )
chart.save('altair-points-test-7.html')

此例於 encode() 中指定 color='label', Altair 會依照 'label' 欄位的分類自動為每個分類配色, 結果如下 : 




可見 A, B 兩種分類顏色不同, A 類是藍色系圓點; B 類是橘色系方點. 

沒有留言 :