Dash 教學第 2 篇:進階互動與動態更新

更新於 發佈於 閱讀時間約 14 分鐘

📌 你將學會:

  1. Input, Output, State 差異與用途
  2. 多個輸入的 callback 使用方法
  3. 使用者動作判斷(例如:只在按下按鈕時觸發)
  4. 利用 dash.callback_context 控制觸發條件
  5. 實作:多條國家生命線圖 + 自訂年份區間 + 按鈕觸發圖表更新

✳️ Input / Output / State 是什麼?

類別說明常見用途Input使用者觸發更新的輸入元件(會即時觸發 callback)Dropdown、SliderOutputcallback 的輸出(通常是畫面上的元件)Graph、HTML 元件State非觸發性參數(按下按鈕時才一起讀取)TextInput、Date


🛠️ 範例:選擇多國、年份區間、按下按鈕才更新圖表

raw-image
import dash
from dash import dcc, html, Input, Output, State
import plotly.express as px
import pandas as pd

# 讀取資料
df = px.data.gapminder()

# 初始化 App
app = dash.Dash(__name__)

# Layout 設計
app.layout = html.Div([
html.H2("🌍 多國家壽命趨勢比較"),

dcc.Dropdown(
id='country-dropdown',
options=[{'label': c, 'value': c} for c in sorted(df['country'].unique())],
multi=True,
value=['Taiwan', 'Japan'],
placeholder="選擇一個或多個國家"
),

dcc.RangeSlider(
id='year-slider',
min=int(df['year'].min()),
max=int(df['year'].max()),
marks={int(year): str(year) for year in df['year'].unique()},
value=[1980, 2007],
step=None,
allowCross=False
),

html.Button("📈 更新圖表", id='update-button', n_clicks=0, style={'marginTop': '20px'}),

dcc.Graph(id='line-graph'),

html.Div(id='debug-output', style={'marginTop': '10px', 'color': 'gray'})
])

# Callback:當按鈕被按下時才觸發
@app.callback(
Output('line-graph', 'figure'),
Output('debug-output', 'children'),
Input('update-button', 'n_clicks'),
State('country-dropdown', 'value'),
State('year-slider', 'value')
)
def update_graph(n_clicks, selected_countries, year_range):
if not selected_countries:
return dash.no_update, "⚠️ 請選擇至少一個國家"
filtered_df = df[(df['country'].isin(selected_countries)) &
(df['year'] >= year_range[0]) &
(df['year'] <= year_range[1])]
fig = px.line(filtered_df, x='year', y='lifeExp', color='country',
title="選定國家生命期望值趨勢", markers=True)
return fig, f"✅ 已載入:{', '.join(selected_countries)}{year_range[0]} ~ {year_range[1]})"

# 啟動應用
if __name__ == '__main__':
app.run_server(debug=True)
# app.run(debug=True) # 看版本

📦📦 套件與資料準備

import dash
from dash import dcc, html, Input, Output, State
import plotly.express as px
import pandas as pd
  • dash:用來建立 Web 應用的主套件。
  • dcc:Dash Core Components,如下拉選單、圖表等互動元件。
  • html:Dash 的 HTML 標籤元件,用於組合 UI。
  • Input, Output, State:用來定義 Callback 函式的輸入與輸出。
  • plotly.express: 簡化的 Plotly 繪圖工具。
  • pandas:處理資料用。
df = px.data.gapminder()
  • 使用 Plotly 內建的 gapminder 資料集,包含世界各國在不同年份的人均 GDP、壽命與人口數。

🌐 App 初始化與 Layout 設計

app = dash.Dash(__name__)
  • 建立一個 Dash 應用實例。
app.layout = html.Div([
...
])
  • 使用 html.Div 組成整個畫面的外觀。

📌 Layout 元件細節:

標題

html.H2("🌍 多國家壽命趨勢比較"),

顯示應用的標題。

國家下拉選單(多選)

dcc.Dropdown(
id='country-dropdown',
options=[{'label': c, 'value': c} for c in sorted(df['country'].unique())],
multi=True,
value=['Taiwan', 'Japan'],
placeholder="選擇一個或多個國家"
),
  • 可選多個國家。
  • 選項來自 df['country'].unique()
  • 預設選取台灣與日本。

年份範圍滑桿

dcc.RangeSlider(
id='year-slider',
min=int(df['year'].min()),
max=int(df['year'].max()),
marks={int(year): str(year) for year in df['year'].unique()},
value=[1980, 2007],
step=None,
allowCross=False
),
  • 允許使用者選擇特定年份區間。
  • marks 會顯示在滑桿上對應的年份。
  • step=None 表示只能選擇資料中實際存在的年份。
  • allowCross=False 防止兩端交錯。

更新按鈕

html.Button("📈 更新圖表", id='update-button', n_clicks=0, style={'marginTop': '20px'}),
  • 手動觸發圖表更新。
  • 避免每次調整滑桿或下拉就重新繪圖,提升效能。

圖表顯示區域

dcc.Graph(id='line-graph'),
  • 顯示以 Plotly 繪製的生命期望圖。

偵錯訊息區(顯示載入的參數)

html.Div(id='debug-output', style={'marginTop': '10px', 'color': 'gray'})
  • 顯示目前選取的國家與年份範圍。

⚙️ Callback 控制邏輯

@app.callback(
Output('line-graph', 'figure'),
Output('debug-output', 'children'),
Input('update-button', 'n_clicks'),
State('country-dropdown', 'value'),
State('year-slider', 'value')
)

這段註冊一個 callback 函式 update_graph

  • 只有當使用者點擊「更新圖表」按鈕時(Input)才觸發。
  • 使用目前 DropdownSlider 的選取值(State)來產生新的圖。

📉 update_graph 函式邏輯:

def update_graph(n_clicks, selected_countries, year_range):
if not selected_countries:
return dash.no_update, "⚠️ 請選擇至少一個國家"
  • 若沒選國家,則不更新圖表,並提示錯誤。
filtered_df = df[(df['country'].isin(selected_countries)) &
(df['year'] >= year_range[0]) &
(df['year'] <= year_range[1])]
  • 根據選擇的國家與年份篩選資料。
fig = px.line(filtered_df, x='year', y='lifeExp', color='country',
title="選定國家生命期望值趨勢", markers=True)
  • 使用 Plotly Express 繪製折線圖。
  • 每個國家一條線,x 軸為年份,y 軸為壽命(life expectancy)。
return fig, f"✅ 已載入:{', '.join(selected_countries)}{year_range[0]} ~ {year_range[1]})"
  • 回傳圖表與 debug 訊息。

🧠 關鍵解說

1️⃣ dcc.RangeSlider 的用法

可以讓你用滑桿選取一段時間範圍,value=[start, end]

    dcc.RangeSlider(
        id='year-slider',
        min=int(df['year'].min()),
        max=int(df['year'].max()),
        marks={int(year): str(year) for year in df['year'].unique()},
        value=[1980, 2007],
        step=None,
        allowCross=False
    ),

2️⃣ html.Button + Input(n_clicks)

透過 n_clicks 控制只有按下按鈕才觸發 callback,避免使用者每改一個欄位就自動重繪圖表。

# Callback:當按鈕被按下時才觸發
@app.callback(
    Output('line-graph', 'figure'),
    Output('debug-output', 'children'),
    Input('update-button', 'n_clicks'),
    State('country-dropdown', 'value'),
    State('year-slider', 'value')
)
raw-image

按更新圖檔才會更新

raw-image

3️⃣ 使用 State 而非 Input

因為我們不想讓 DropdownSlider 的變動立即觸發 callback,所以要改用 State 來「讀值但不觸發」。


📚 總結

raw-image



留言
avatar-img
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
141會員
253內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
你可能也想看
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
這篇內容,將會講解什麼是「switch」,以及與「switch」相關的知識。包括switch的簡介、switch、break。
Thumbnail
這篇內容,將會講解什麼是「switch」,以及與「switch」相關的知識。包括switch的簡介、switch、break。
Thumbnail
這篇內容,將會講解什麼是表達式(Expression),什麼是陳述式(Statement)。有了這些概念,各位會更容易理解,要如何設計程式碼。
Thumbnail
這篇內容,將會講解什麼是表達式(Expression),什麼是陳述式(Statement)。有了這些概念,各位會更容易理解,要如何設計程式碼。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
本章節提供了關於Typescript中流程控制元素的詳細介紹,包括if, else if, else語句,三元運算子,switch語句,各種for迴圈,while迴圈,循環嵌套和控制迴圈語句(break,continue和標籤)的使用。
Thumbnail
本章節提供了關於Typescript中流程控制元素的詳細介紹,包括if, else if, else語句,三元運算子,switch語句,各種for迴圈,while迴圈,循環嵌套和控制迴圈語句(break,continue和標籤)的使用。
Thumbnail
Function的使用方式
Thumbnail
Function的使用方式
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News