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

Plotly子图柱状图宽度不一致问题求助

解决Plotly子图柱状图宽度不一致的问题

我一眼就揪出你代码里的核心问题了——你明明在循环里用p = df.filter(pl.col("group") == group)过滤了对应分组的数据,但添加柱状图时却误用了整个原始DataFrame的x和y数据,而不是过滤后的p!

问题根源

当group是空字符串时,df.filter(pl.col("group") == "")返回的数据行数远少于其他分组,但你仍然用全量的df.select("date").to_series()作为x轴数据。这就导致该子图里的有效数据点被强行分散在整个x轴范围内,柱子自然被挤压得异常纤细;而其他分组的子图因为x和y数据完全匹配,柱子宽度就正常显示了。

修正后的代码

把x和y的数据源改成过滤后的p,就能立刻解决宽度不一致的问题:

import polars as pl
from plotly.subplots import make_subplots
import plotly.graph_objects as go

df = pl.read_csv("https://gist.githubusercontent.com/KeremAslan/c20094b65c4023e8b1d8d6b70fe90f45/raw/bcd44ed1c98ad7021c4b3951e3815d9b22a021a1/stackoverflow_plotly")
values = ["value_a", "value_b", "value_c", "value_d"]
groups = ["A", "B", "C", "D", ""]

fig = make_subplots(
    rows=len(groups), cols=len(values),
    shared_xaxes=True, shared_yaxes=True
)

for group_index, group in enumerate(groups):
    # 过滤当前分组的数据
    p = df.filter(pl.col("group") == group)
    for ix, value in enumerate(values):
        fig.add_trace(
            go.Bar(
                # 改用过滤后的p的date和对应value列
                x=p.select("date").to_series(),
                y=p.select(value).to_series()
            ),
            row=group_index+1, col=ix+1
        )

fig.update_layout(showlegend=False)
fig.show()

额外优化建议

  1. 统一柱子宽度:可以在go.Bar()里添加width参数(比如width=0.8),强制所有柱子使用相同宽度,让视觉效果更规整。
  2. 简化x轴显示:因为开启了shared_xaxes=True,可以隐藏重复的x轴标签,只保留最底部子图的标签,提升可读性:
    fig.update_xaxes(showticklabels=False)
    fig.update_xaxes(showticklabels=True, row=len(groups), col="all")
    
  3. 处理空分组:空字符串分组的数据量太少,你可以考虑要么移除这个分组,要么单独调整该子图的布局,避免视觉上的不协调。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:42:40