Plotly Express子图字符串轴标签不显示问题求助
问题概述
使用Plotly Express 5.18.0创建包含子图且轴标签为非数值类型的图表时,仅首个子图会显示轴标签,后续子图的轴标签为空。如何确保所有子图都能显示各自的轴标签(即使标签为字符串类型)?
示例数据
import numpy as np import pandas as pd import plotly.express as px N = 100 food = ["点心", "面条", "汉堡", "披萨", "煎饼"] drink = ["啤酒", "葡萄酒", "苏打水", "白开水", "果汁", "咖啡", "茶"] df = pd.DataFrame( { "年龄": np.random.randint(8, 99, N), "最爱食物": np.random.choice(food, N, replace=True), "最爱饮品": np.random.choice(drink, N, replace=True), "最大跑步速度": np.random.random(N)*20, "拥有自行车数量": np.random.randint(0, 5, N) } ) df.年龄.replace({range(0, 19): "儿童", range(19, 100): "成人"}, inplace=True)
随机5行数据:
| 年龄 | 最爱食物 | 最爱饮品 | 最大跑步速度 | 拥有自行车数量 | |
|---|---|---|---|---|---|
| 0 | 成人 | 点心 | 葡萄酒 | 8.57536 | 2 |
| 65 | 儿童 | 披萨 | 白开水 | 9.45698 | 1 |
| 57 | 儿童 | 煎饼 | 啤酒 | 11.1445 | 0 |
| 84 | 成人 | 点心 | 苏打水 | 8.80699 | 0 |
| 45 | 成人 | 披萨 | 果汁 | 17.7258 | 4 |
问题演示
创建包含两个子图的图表:
- 第一个子图展示最大跑步速度的分布(数值类型)
- 第二个子图展示拥有自行车数量的分布(数值类型)
使用facet_col参数、Plotly Express的宽格式支持及相关格式更新方法:
px.histogram( df, x=["最大跑步速度", "拥有自行车数量"], facet_col="variable", color="年龄", barmode="group", histnorm="percent", text_auto=".2r", ).update_xaxes(matches=None, showticklabels=True).update_yaxes(matches=None, showticklabels=True)

一切正常 ✅:X轴和Y轴拥有独立范围,且所有X轴都显示标签。
现在对文本类型的列执行相同操作:
px.histogram( df, x=["最爱食物", "最爱饮品"], facet_col="variable", color="年龄", barmode="group", histnorm="percent", text_auto=".2r", ).update_xaxes(matches=None, showticklabels=True).update_yaxes(matches=None, showticklabels=True)

问题出现 ❌:右侧子图的X轴未显示最爱饮品的名称。
已尝试操作
检查底层数据JSON对象,发现鼠标悬停在右侧子图的柱状图上时,“value”字段为空:

但检查图表的.data键对应的JSON对象时,两个直方图的X值均存在:

解决方案
这个问题是Plotly Express在宽格式下处理字符串类型列分面时的默认行为问题,核心是分面后非首个子图的轴未正确映射分类标签,可通过以下两种方法解决:
方法1:手动设置子图轴的分类标签
获取每个子图对应的原始数据类别,逐个更新轴的分类映射:
fig = px.histogram( df, x=["最爱食物", "最爱饮品"], facet_col="variable", color="年龄", barmode="group", histnorm="percent", text_auto=".2r", ).update_xaxes(matches=None, showticklabels=True).update_yaxes(matches=None, showticklabels=True) # 为第一个子图设置"最爱食物"的类别 fig.layout.xaxis.categoryarray = food fig.layout.xaxis.categoryorder = 'array' # 为第二个子图设置"最爱饮品"的类别 fig.layout.xaxis2.categoryarray = drink fig.layout.xaxis2.categoryorder = 'array' fig.show()
方法2:将数据转换为长格式(推荐)
避免使用宽格式多列输入,将数据重塑为长格式,让Plotly自动识别每个分面的分类标签:
# 重塑数据为长格式 long_df = df.melt(id_vars=["年龄"], value_vars=["最爱食物", "最爱饮品"], var_name="类别", value_name="选项") fig = px.histogram( long_df, x="选项", facet_col="类别", color="年龄", barmode="group", histnorm="percent", text_auto=".2r", ).update_xaxes(matches=None, showticklabels=True).update_yaxes(matches=None, showticklabels=True) fig.show()
这种方法更贴合Plotly Express的设计逻辑,无需手动配置轴属性,即可自动完成分类标签映射。
内容的提问来源于stack exchange,提问作者Saaru Lindestøkke
相关产品推荐
相关产品推荐

