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

如何构建支持X/Y轴独立切换的Plotly散点图?解决'dict_keys'对象不可下标访问报错

实现双下拉切换X/Y轴的Plotly散点图

首先,你遇到的'dict_keys' object is not subscriptable报错,本质是Python的dict_keys对象不支持下标访问(比如直接写cols_dd.keys()[0]),必须先转成列表(list(cols_dd.keys())[0])才能用下标。不过更重要的是,你的当前代码是用一个下拉切换固定的X-Y组合,而你想要的是两个独立下拉分别控制X轴和Y轴变量——下面是完全符合需求的实现方案:

完整代码实现

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

# 获取OWID数据并预处理
df = pd.read_csv(
    "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/latest/owid-covid-latest.csv"
)

df = df.rename(
    columns={
        "location": "Location",
        "iso_code": "Iso code",
        "total_tests": "Total tests",
        "people_vaccinated_per_hundred": "Vaccines",
        "new_cases": "Recent cases",
        "total_cases": "Total cases",
        "total_deaths": "Total deaths",
        "total_vaccinations": "Total vaccinations",
        "people_vaccinated": "People vaccinated",
        "population": "Population",
        "total_boosters": "Vaccination policy",
    }
).fillna(0)

# 定义可选的X轴和Y轴变量
x_options = ["Total tests", "Total deaths", "Population"]
y_options = ["Total cases", "Recent cases", "Total vaccinations"]

# 初始化图表:使用第一个X和第一个Y变量
fig = px.scatter(
    df,
    x=x_options[0],
    y=y_options[0],
    color="Location",
    hover_data={
        "Iso code": False,
        "Vaccines": True,
        "Total tests": ": ,0.f",
        "Recent cases": ": ,0.f",
        "Total cases": ": ,0.f",
        "Total deaths": ": ,0.f",
        "Total vaccinations": ": ,0.f",
        "People vaccinated": ": ,0.f",
        "Population": ": ,0.f",
        "Vaccination policy": ": 0.f",
    },
    color_continuous_scale="spectral_r",
    hover_name="Location"
)

# 创建X轴切换下拉按钮
x_dropdown = dict(
    buttons=[
        dict(
            label=var,
            method="restyle",
            args=[
                {"x": [df[var]]},  # 更新trace的X轴数据
                {"xaxis.title.text": var, "title.text": f"<b>{var}</b> vs <b>{fig.layout.yaxis.title.text}</b>"}
            ]
        ) for var in x_options
    ],
    direction="down",
    showactive=True,
    x=0.15,
    y=1.18,
    xanchor="left"
)

# 创建Y轴切换下拉按钮
y_dropdown = dict(
    buttons=[
        dict(
            label=var,
            method="restyle",
            args=[
                {"y": [df[var]]},  # 更新trace的Y轴数据
                {"yaxis.title.text": var, "title.text": f"<b>{fig.layout.xaxis.title.text}</b> vs <b>{var}</b>"}
            ]
        ) for var in y_options
    ],
    direction="down",
    showactive=True,
    x=0.85,
    y=1.18,
    xanchor="right"
)

# 更新布局,添加下拉按钮并调整样式
fig.update_layout(
    updatemenus=[x_dropdown, y_dropdown],
    title=f"<b>{x_options[0]}</b> vs <b>{y_options[0]}</b>",
    xaxis_title=x_options[0],
    yaxis_title=y_options[0],
    margin=dict(t=120)  # 留出顶部空间放置下拉按钮
)

fig.show()

方案说明

  1. 核心逻辑:使用Plotly的restyle方法直接更新现有散点图的X/Y轴数据,不需要预先创建所有变量组合的trace,代码更简洁高效。
  2. 双下拉独立控制:两个下拉按钮分别管理X轴和Y轴的变量切换,用户可以自由组合任意X-Y配对。
  3. 动态标题更新:切换变量时,图表标题和轴标题会自动同步更新,提升交互体验。

关于你原代码的报错修复

如果一定要保留“固定X-Y组合”的切换逻辑,只需确保所有dict_keys对象都转成列表即可,比如把:

{"visible": [key == k for key in cols_dd.keys()]}

改成:

{"visible": [key == k for key in list(cols_dd.keys())]}

但这种方式只能切换预设的组合,灵活性远不如双独立下拉的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:44:08