本篇旨在測試 Streamlit 內建統計圖表函式中的地圖函式 st.map(), 此函式可在網頁應用程式中快速繪製基於地理資料的互動式地圖, 並於地圖上顯示資料點地理位置之散點分佈, 不需要複雜的設定即可輕鬆地將經緯度相關的資料 (例如城市中的店鋪位置, 地震發生點或交通流量等) 呈現於地圖上.
st.map() 底層基於 PyDeck 和 Mapbox 函式庫, 它所繪製的地圖支援基本的互動功能, 例如縮放與平移, 但不支援工具提示 (tooltips) 或複雜標記等進階功能. 僅支援散點圖, 不支援多層地圖, 熱圖或複雜標記 (這些功能要使用底層的 PyDeck).
| 函式名稱 | 說明 |
|---|---|
| st.line_chart() | 繪製折線圖,適合用來呈現時間序列或連續變化的資料。 |
| st.bar_chart() | 繪製長條圖,適合用來比較各分類資料的數值大小。 |
| st.scatter_chart() | 繪製散佈圖,用於顯示兩個變數之間的關係(需 DataFrame 格式資料)。 |
| st.area_chart() | 繪製區域圖,類似折線圖,但底部會填滿陰影,強調總量變化。 |
| st.map() | 在地圖上繪製地理座標點,支援 DataFrame 中包含緯度與經度的資料。 |
5. 地圖函式 st.map() :
此函式的參數結構如下 :
st.map(data=None, latitude='lat', longitude='lon', color=None, size=None, zoom=None, use_container_width=True)
雖然每個參數都有預設值, 但 參數說明如下表 :
| st.map() 參數 | 說明 |
|---|---|
| data | 資料來源,可為 DataFrame 或類似格式,需包含經緯度欄位 |
| latitude | 指定緯度欄位名稱,若為 None,將自動從常見欄位名稱中推測(如 'lat') |
| longitude | 指定經度欄位名稱,若為 None,將自動從常見欄位名稱中推測(如 'lon') |
| color | 設定地圖上點的顏色,可為顏色欄位名稱、色碼(如 '#FF0000')或 RGB 色彩值 |
| size | 設定點的大小(單位公尺, 預設10),可為數值欄位名稱或單一固定數值 |
| zoom | 初始縮放等級,數值愈大愈接近(建議範圍約 1~18,預設 10) |
| width | 地圖寬度(以像素為單位),若未指定則依 container 決定 |
| height | 地圖高度(以像素為單位) |
| use_container_width | 是否讓地圖寬度自動撐滿 container,預設為 True |
其中 size 與 color 參數是 v1.25 之後才新增的, size 預設值為 10, 可以指定 DataFrame 中的欄位名稱, color 預設值為紅色, 可以用 16 進位色碼字串例如 "#0000FF" 或 RGB 串列例如 [0, 0, 255], 也可以指定 DataFrame 中的一個欄位名稱. 參數 zoom 數值愈大地圖愈接近 (例如 zoom=14~16 可清楚看見街區或地標), 一般設 10~12 即可.
例如 :
測試 5-1 : 預設的地圖 [看原始碼]
# st-map-test-1.py
import streamlit as st
import pandas as pd
data=pd.DataFrame({
'lat': [25.033968, 25.102398],
'lon': [121.564468, 121.548492]
})
st.map(data)
此例僅傳入包含兩組經緯度資料點的 DataFrame, 在沒有傳入 latitude (緯度) 與 longitude (經度) 情況下, st.map() 會自動去搜尋欄位名稱, 自動判斷哪一個是經緯度欄位, 此處第一組經緯度是台北 101, 第二組是故宮博物院, 結果如下 :
可見預設使用小紅點標示資料點在地圖上的位置, 滑鼠移到資料點上時並無 tooltip 提示.
可以用 size 與 color 參數去設定資料點大小與顏色, 如果指定單一值表示套用到所有資料點, 例如下面範例 :
測試 5-2 : 用 size 與 color 參數設定資料點大小與顏色 (1) [看原始碼]
# st-map-test-2.py
import streamlit as st
import pandas as pd
data=pd.DataFrame({
'lat': [25.033968, 25.102398],
'lon': [121.564468, 121.548492]
})
st.map(data, latitude='lat', longitude='lon', size=100, color='#0000FF')
此例用參數 size 與 color 將資料點大小設為 100 公尺與藍色, 這會套用到所有資料點. 其次也用 latitude 與 longitude 參數明確指定緯度與精度在 DataFrame 中的欄位名稱, 結果如下 :
參數 size 與 color 也可以指定 DataFrame 中的一個欄位, 這樣就可以為每個資料點指定不同的大小與顏色, 例如 :
測試 5-3 : 用 size 與 color 參數設定資料點大小與顏色 (2) [看原始碼]
# st-map-test-3.py
import streamlit as st
import pandas as pd
data=pd.DataFrame({
'lat': [25.033968, 25.102398],
'lon': [121.564468, 121.548492],
'顏色' : ['#0000ff', [0, 255, 0]],
'大小' : [100, 150]
})
st.map(data, latitude='lat', longitude='lon', size='大小', color='顏色')
此例在 DataFrame 中新增顏色與大小兩個欄位分別指定各資料點的顏色與大小, 然後將 size 與 color 參數指向這兩個欄位即可, 結果如下 :
可見故宮已經變成較大的綠色點點了.
下面是添加更多資料點來測試 zoom, height, width 與 use_container_width 參數的範例 :
# st-map-test-4.py
import streamlit as st
import pandas as pd
data=pd.DataFrame({
'地點': ['台北 101', '故宮博物院', '中正紀念堂', '士林夜市', '陽明山國家公園', '松山文創園區'],
'lat': [25.033968, 25.102398, 25.034194, 25.088200, 25.166748, 25.044150],
'lon': [121.564468, 121.548492, 121.521880, 121.525000, 121.559845, 121.557510],
'類別': ['商業地標', '文化地標', '歷史紀念', '夜市美食', '自然景觀', '文創藝術'],
'人氣': [95, 80, 85, 90, 75, 70],
'色彩': ['#0000FF', '#00FF00', '#FF0000', [55, 123, 77], [210, 50, 78], [116, 23, 109]]
})
st.map(
data,
latitude='lat',
longitude='lon',
size='人氣',
color='色彩',
width=600,
height=400,
zoom=10,
use_container_width=False
)
此例添加 '地點' 欄位來註解經緯度所在之景點 (可惜沒有 tooltip 參數可用), 以 '人氣' 欄來設定 size 參數; 以 '色彩' 欄來設定 color 參數, 結果如下 :
可見這六個景點依據其人氣來決定資料點大小, 顏色也各自不同.
下面範例利用 Numpy 來產生高雄市登革熱病例分布的模擬地圖 :
測試 5-5 : 高雄市登革熱病例分布的模擬地圖 [看原始碼]
# st-map-test-5.py
import streamlit as st
import pandas as pd
import numpy as np
st.subheader('高雄登革熱疫情模擬地圖')
# 輸入病例數
case_count=st.slider('模擬病例數量', min_value=10, max_value=500, value=100, step=10)
center_lat=22.6300 # 高雄市中心緯度
center_lon=120.3000 # 高雄市中心經度
theta=np.random.uniform(0, 2 * np.pi, case_count) # 隨機角度 (0~2π)
r=np.random.uniform(0, 0.02, case_count) # 隨機半徑 (0 ~ r),r=0.02
lat=center_lat + r * np.sin(theta) # 生成隨機病例位置緯度 (Numpy 陣列)
lon=center_lon + r * np.cos(theta) # 生成隨機病例位置經度 (Numpy 陣列)
data=pd.DataFrame({'lat': lat,'lon': lon}) # 建立 DataFrame
st.map(
data,
latitude='lat',
longitude='lon',
color='#FF0000',
size=80,
zoom=12
)
此例以隨機角度與半徑生成以市中心為分布中心的不定形狀病例分布區域經緯度陣列, 將其轉成 DataFrame 後傳給 st.map() 繪製疫情地圖, 結果如下 :





沒有留言 :
張貼留言