Figure 結構
Plotly 的每一張圖都是一個 Figure 物件(plotly.graph_objects.Figure),由 data 與 layout 兩大部分組成:data 是一串 trace(實際畫出來的點、線、長條),layout 是標題、座標軸、圖例、邊界等版面設定。Plotly Express 的每個函式都只是「幫您建好一個 Figure」,所以理解 Figure 結構,就知道畫完之後要去哪裡改。
Plotly 套件的三個層次
| 層次 | 模組 | 用途 |
|---|---|---|
| 高階 | plotly.express(px) |
一個函式建立整張圖;從 DataFrame 欄位對應到視覺屬性 |
| 低階 | plotly.graph_objects(go) |
手動組合 trace 與 layout,可做任何 Plotly 支援的圖 |
| 工具 | plotly.io(pio)、plotly.subplots |
顯示、輸出、模板設定;建立子圖格線 |
Plotly Express 在 2019 年加入 Plotly 4.0,目標是讓 80% 的常見圖表都能一行完成;剩下 20% 的特殊需求,再用 Graph Objects 補。
Figure 裡面有什麼?
print(fig) 或 fig.to_dict() 可以看到 Figure 的完整內容:
輸出大致如下(已簡化):
Figure({
'data': [{'type': 'bar', 'x': array(['A', 'B', 'C']), 'y': array([3, 1, 2]), ...}],
'layout': {'title': {'text': '簡單長條圖'}, 'xaxis': {...}, 'yaxis': {...}, 'template': '...'}
})
fig.data:trace 的 tuple。用color分組時,每一組就是一條獨立的 trace,所以點擊圖例可以單獨隱藏某一組。fig.layout:版面設定,例如title、xaxis、yaxis、legend、template、margin。
怎麼找到屬性名稱?
在 Jupyter 中輸入 fig.layout. 再按 Tab 可以看到所有可設定的屬性。完整屬性清單見官方的 Figure Reference。
同一張圖:Express 與 Graph Objects 寫法比較
下面兩段程式產生的圖幾乎相同:
import plotly.graph_objects as go
import plotly.express as px
df = px.data.iris()
fig = go.Figure()
for species, group in df.groupby("species"):
fig.add_trace(go.Scatter(
x=group["sepal_width"], y=group["sepal_length"],
mode="markers", name=species,
))
fig.update_layout(xaxis_title="sepal_width", yaxis_title="sepal_length",
legend_title="species")
fig.show()
Graph Objects 需要自己分組、迴圈、加圖例標題;Plotly Express 用 color="species" 一個參數就完成。這就是本站以 Plotly Express 為主軸的原因。
畫完之後再修改:混用兩者
Plotly Express 回傳的就是 go.Figure,所以所有 Graph Objects 的方法都能直接使用:
import plotly.express as px
import plotly.graph_objects as go
df = px.data.stocks()
fig = px.line(df, x="date", y="GOOG", title="Google 相對股價")
fig.add_hline(y=1, line_dash="dot", annotation_text="基準值") # 加一條水平參考線
fig.add_trace(go.Scatter(x=df["date"], y=df["AAPL"], name="AAPL")) # 再加一條 trace
fig.update_layout(yaxis_title="相對價格")
fig.show()
常用的修改方法:
| 方法 | 作用 |
|---|---|
fig.update_layout(...) |
修改版面:標題、圖例、邊界、字型、模板 |
fig.update_traces(...) |
修改所有(或篩選後的)trace:顏色、線寬、標記、文字 |
fig.update_xaxes(...)/fig.update_yaxes(...) |
修改座標軸:範圍、刻度、格線、對數刻度 |
fig.add_trace(...) |
加入新的 trace |
fig.add_hline()/add_vline()/add_hrect()/add_vrect() |
加入參考線或底色區間 |
fig.add_annotation(...) |
加入文字標註 |
這些方法在 樣式與客製化 有更完整的範例。
什麼時候需要 Graph Objects?
Plotly Express 無法直接做到、需要改用 Graph Objects 的情況:
- 同一張圖要混合不同類型的 trace,且無法用
add_trace補上(例如雙 Y 軸要用make_subplots(specs=[[{"secondary_y": True}]]))。 - 子圖格線中每一格放完全不同的圖(
plotly.subplots.make_subplots)。 - Plotly Express 沒有對應函式的圖,例如 K 線圖
go.Candlestick、瀑布圖go.Waterfall、桑基圖go.Sankey、表格go.Table、指標go.Indicator。
推薦影音
Introduction to Plotly Data Visualization(Charming Data)
簡述:說明 Plotly Express 與 Graph Objects 的差異、為什麼要用 Plotly,以及如何閱讀官方文件找到需要的參數。對應本頁「三個層次」與「Express 與 Graph Objects 比較」兩段。