如何构建支持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()
方案说明
- 核心逻辑:使用Plotly的
restyle方法直接更新现有散点图的X/Y轴数据,不需要预先创建所有变量组合的trace,代码更简洁高效。 - 双下拉独立控制:两个下拉按钮分别管理X轴和Y轴的变量切换,用户可以自由组合任意X-Y配对。
- 动态标题更新:切换变量时,图表标题和轴标题会自动同步更新,提升交互体验。
关于你原代码的报错修复
如果一定要保留“固定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
相关产品推荐
相关产品推荐

