You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何制作可交互切换着色参数的Plotly图表?支持分类与数值着色

纯Plotly实现交互式散点图:下拉切换着色参数且保留缩放

需求概述

  • 基于Plotly Express从DataFrame创建散点图
  • 添加下拉菜单,支持分类/数值型字段切换作为着色参数
  • 切换参数时保留当前图表的缩放、平移状态
  • 解决Dash实现中存在的两个问题:无法跨类型切换着色、hover信息不更新

纯Plotly解决方案(无需Dash)

利用Plotly原生的updatemenus配置下拉菜单,结合restyle方法更新图表属性,同时通过uirevision锁定交互状态。

完整代码

import plotly.express as px
import numpy as np

# 准备数据
df = px.data.gapminder()
df["moreData1"] = np.random.normal(size=len(df))
# 整理可选择的着色字段:包含分类(continent)和数值型字段
color_options = ["continent", "lifeExp", "gdpPercap", "pop", "moreData1"]

# 初始化图表(默认以continent着色)
fig = px.scatter(df, 
                 x="gdpPercap", 
                 y="lifeExp", 
                 log_x=True, 
                 color="continent",
                 hover_data=["country", "year"]
                )

# 设置uirevision,确保交互状态(缩放、平移)不重置
fig.update_layout(uirevision="constant")

# 配置下拉菜单
fig.update_layout(
    updatemenus=[
        dict(
            buttons=list([
                dict(
                    label=col,
                    method="restyle",
                    args=[
                        {"marker.color": df[col]},
                        {"hovertemplate": f"GDP per Cap: %{{x}}<br>Life Expectancy: %{{y}}<br>{col}: %{{marker.color}}<br>Country: %{{customdata[0]}}<br>Year: %{{customdata[1]}}<extra></extra>"}
                    ]
                ) for col in color_options
            ]),
            direction="down",
            showactive=True,
            x=0.1,
            xanchor="left",
            y=1.1,
            yanchor="top"
        )
    ]
)

# 调整布局,避免菜单遮挡图表
fig.update_layout(margin=dict(t=100))

fig.show()

关键说明

  1. 跨类型着色切换:通过restyle直接传递对应字段的数值/分类值,Plotly会自动识别字段类型并应用对应的颜色映射(离散/连续)
  2. hover信息同步更新:在args中自定义hovertemplate,确保hover显示当前选中的着色字段值
  3. 保留交互状态:uirevision="constant"告诉Plotly,只要这个值不变,就保留用户的缩放、平移等交互状态

Dash方案修复(可选)

如果仍需使用Dash,需修改回调逻辑:重新创建图表而非直接更新trace,同时保留uirevision设置。

修复后代码

import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
import numpy as np

df = px.data.gapminder()
df["moreData1"] = np.random.normal(size=len(df))
# 包含分类和数值字段
color_options = ["continent", "lifeExp", "gdpPercap", "pop", "moreData1"]
options = [{'label': v, 'value': v} for v in color_options]

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Dropdown(
        id='color-dropdown',
        options=options,
        value="continent"
    ),
    dcc.Graph(
        id='scatter-plot'
    )
])

@app.callback(
    Output('scatter-plot', 'figure'),
    [Input('color-dropdown', 'value')]
)
def update_scatter_plot(selected_color):
    # 重新创建图表,确保分类/数值着色逻辑正确
    fig = px.scatter(df, 
                     x="gdpPercap",
                     y="lifeExp", 
                     log_x=True, 
                     color=selected_color,
                     hover_data=["country", "year"],
                     render_mode='webgl'
                    )
    # 锁定交互状态
    fig.update_layout(uirevision='constant')
    return fig

if __name__ == '__main__':
    app.run(debug=True, port=8052)

修复要点

  • 回调中重新创建完整图表,而非仅更新marker颜色,确保Plotly正确处理分类字段的离散颜色映射
  • 保留uirevision设置,避免切换时重置缩放
  • hover信息由Plotly Express自动生成,会同步跟随着色字段更新

内容的提问来源于stack exchange,提问作者Noskario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:01:10