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


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

vocus|新世代的創作平台
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')
)
vocus|新世代的創作平台

按更新圖檔才會更新

vocus|新世代的創作平台

3️⃣ 使用 State 而非 Input

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


📚 總結

vocus|新世代的創作平台



留言
avatar-img
螃蟹_crab的沙龍
167會員
322內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
你可能也想看
Thumbnail
這篇內容,將會講解什麼是表達式(Expression),什麼是陳述式(Statement)。有了這些概念,各位會更容易理解,要如何設計程式碼。
Thumbnail
這篇內容,將會講解什麼是表達式(Expression),什麼是陳述式(Statement)。有了這些概念,各位會更容易理解,要如何設計程式碼。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
這篇內容,將會講解什麼是函式,以及與函式相關的知識。包括函式的簡介、Runtime Function、自訂函式、Script Function 腳本函式、Method 方法。
Thumbnail
這篇內容,將會講解什麼是「switch」,以及與「switch」相關的知識。包括switch的簡介、switch、break。
Thumbnail
這篇內容,將會講解什麼是「switch」,以及與「switch」相關的知識。包括switch的簡介、switch、break。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
在網路速度有限的情況下,依序記錄不斷產生的資訊,能統計使用者在頁面上操作了哪些功能。
Thumbnail
User Input & Tables 的使用
Thumbnail
User Input & Tables 的使用
Thumbnail
Function的使用方式
Thumbnail
Function的使用方式
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
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News