地圖
Plotly Express 的地圖分成兩類:geo 地圖(choropleth、scatter_geo、line_geo)畫在簡化的世界或國家輪廓上,不需要網路底圖,適合國家、州層級的統計;map 地圖(scatter_map、line_map、density_map、choropleth_map)使用 MapLibre 的街道圖磚當底圖,可以放大到街道層級,適合經緯度座標資料。兩類都不需要申請 token。
Plotly 7 已移除 *_mapbox 函式
舊教學常見的 px.scatter_mapbox、px.choropleth_mapbox、px.density_mapbox 與 mapbox_style 參數,在 Plotly 7.0 已移除。請改用 px.scatter_map、px.choropleth_map、px.density_map 與 map_style 參數,用法幾乎一樣,而且不需要 Mapbox token。
面量圖 px.choropleth
面量圖(choropleth map)依數值把地區塗上深淺不同的顏色。最簡單的情況是國家層級資料,搭配 ISO-3 國家代碼:
import plotly.express as px
df = px.data.gapminder().query("year == 2007")
fig = px.choropleth(df, locations="iso_alpha", color="lifeExp",
hover_name="country",
color_continuous_scale=px.colors.sequential.Plasma)
fig.show()
| 參數 | 說明 |
|---|---|
locations |
地區識別欄位 |
locationmode |
locations 的格式:"ISO-3"(預設)、"USA-states"(美國州縮寫)、"country names"(英文國名) |
geojson、featureidkey |
自訂邊界(縣市、鄉鎮)時使用,見下方 |
scope |
顯示範圍:"world"、"asia"、"europe"、"usa" 等 |
projection |
地圖投影:"natural earth"、"orthographic"(地球儀)、"equirectangular" 等 |
fitbounds="locations" |
自動縮放到有資料的區域 |
使用自己的 GeoJSON(例如台灣縣市)
要畫國家以下的行政區,需要一份 GeoJSON 邊界檔,並用 featureidkey 指出 GeoJSON 裡哪個屬性對應到 DataFrame 的 locations 欄位:
import json
import plotly.express as px
with open("taiwan_counties.geojson", encoding="utf-8") as f: # 自備的縣市邊界檔
counties = json.load(f)
fig = px.choropleth(df, geojson=counties,
locations="縣市名稱",
featureidkey="properties.COUNTYNAME", # GeoJSON 中對應的屬性
color="人口數", fitbounds="locations")
fig.update_geos(visible=False) # 隱藏世界底圖,只留 GeoJSON 區域
fig.show()
台灣縣市與鄉鎮邊界可從政府資料開放平臺下載(多為 SHP 格式,可用 GeoPandas 或線上工具轉成 GeoJSON)。
地理散佈圖 px.scatter_geo
在 geo 地圖上用點標示位置,點的大小與顏色對應數值:
df = px.data.gapminder().query("year == 2007")
px.scatter_geo(df, locations="iso_alpha", color="continent",
hover_name="country", size="pop", projection="natural earth")
有經緯度時改用 lat=、lon=。px.line_geo 則是把點連成線,適合畫航線或遷徙路徑。
街道底圖 px.scatter_map
有精確經緯度(店家、站點、事件位置)時,用 map 系列函式,可以縮放到街道層級:
import plotly.express as px
df = px.data.carshare()
fig = px.scatter_map(df, lat="centroid_lat", lon="centroid_lon",
color="peak_hour", size="car_hours", size_max=15, zoom=10)
fig.show()
| 參數 | 說明 |
|---|---|
lat、lon |
緯度、經度欄位 |
zoom、center |
初始縮放與中心點,例如 center={"lat": 25.04, "lon": 121.56};Plotly 7 未指定時會自動縮放到資料範圍 |
map_style |
底圖樣式,例如 "open-street-map"、"carto-positron"、"carto-darkmatter"、"carto-voyager"、"white-bg" |
密度地圖 px.density_map
點很多時,改畫熱度:
df = px.data.carshare()
px.density_map(df, lat="centroid_lat", lon="centroid_lon", z="car_hours",
radius=12, map_style="carto-darkmatter")
radius 控制每個點影響的半徑(像素)。
街道底圖上的面量圖 px.choropleth_map
需要在街道底圖上疊行政區時使用,參數與 px.choropleth 的 GeoJSON 用法相同:
df = px.data.election()
geojson = px.data.election_geojson()
px.choropleth_map(df, geojson=geojson, locations="district",
featureidkey="properties.district", color="Bergeron",
map_style="carto-positron", opacity=0.6)
該選哪一種?
| 情境 | 建議 |
|---|---|
| 國家或州層級的統計值 | choropleth |
| 國家層級的總量(人口、GDP) | scatter_geo(用點大小) |
| 精確經緯度、需要街道細節 | scatter_map |
| 大量經緯度點的熱點分布 | density_map |
| 縣市、鄉鎮、選區疊在街道圖上 | choropleth_map |
推薦影音
Plotting Choropleth Maps using Python (Plotly)(Indian Pythonista)
簡述:從維基百科表格抓資料,逐步做出世界與印度各邦的面量圖,說明 locations、GeoJSON 與 featureidkey 的對應方式。影片使用的是較早的 API,但 GeoJSON 對應觀念與本頁「使用自己的 GeoJSON」一節完全相同。