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

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.575362
65儿童披萨白开水9.456981
57儿童煎饼啤酒11.14450
84成人点心苏打水8.806990
45成人披萨果汁17.72584
问题演示

创建包含两个子图的图表:

  • 第一个子图展示最大跑步速度的分布(数值类型)
  • 第二个子图展示拥有自行车数量的分布(数值类型)

使用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”字段为空:

悬停时value字段为空

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

data中存在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:44:58