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

Matplotlib零高度柱状图显示问题:如何可视化零高度条目?

解决柱状图零高度条目不可见的问题

我有一个包含两组数值的数据集,需要以两组数值的差值作为柱状图的高度,但当两组数值相等时,柱高为0导致无法显示。我需要将这类零高度条目显示为细线、点或其他可见元素,曾尝试给差值添加固定小值,但Y轴刻度动态变化,固定值在不同刻度范围适配性差。想知道使用subplot搭配bar(x, height)是否不合适,或是是否有更优方案比如ax.errorbar()?

原始示例代码

import matplotlib.pyplot as plt
import pandas as pd

df=pd.DataFrame()
df["desc"] = ("A","B","C","D","E")
df["a"] = (0.1,0.5,1,0.6,0.4)
df["b"] = (0.3,0.6,0.6,0.7,0.4)
fig, ax = plt.subplots()

ax.bar(x=df['desc'], 
       bottom=df['a'], 
       height=df['b'] - df['a'])

ax.set_ylim(bottom=0, top=1.2)
new_yticks = list(set(df['a']).union(df['b']))
plt.yticks(new_yticks)
plt.show()

可以看到X轴为"E"的条目因高度为0未显示。此前尝试给差值添加固定小值,但适配性差。


方案1:区分处理零高度与非零高度条目

针对零高度的条目单独绘制极窄柱子或标记点,既不影响正常柱子展示,又能让零值条目清晰可见,且高度会随Y轴范围自动适配:

import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame()
df["desc"] = ("A","B","C","D","E")
df["a"] = (0.1,0.5,1,0.6,0.4)
df["b"] = (0.3,0.6,0.6,0.7,0.4)
df['diff'] = df['b'] - df['a']

fig, ax = plt.subplots()

# 绘制正常高度的柱子
non_zero_mask = df['diff'] != 0
ax.bar(x=df.loc[non_zero_mask, 'desc'], 
       bottom=df.loc[non_zero_mask, 'a'], 
       height=df.loc[non_zero_mask, 'diff'])

# 处理零高度条目:绘制占Y轴范围1%的细柱,居中在a值位置
zero_mask = df['diff'] == 0
y_range = ax.get_ylim()[1] - ax.get_ylim()[0]
tiny_height = y_range * 0.01
ax.bar(x=df.loc[zero_mask, 'desc'], 
       bottom=df.loc[zero_mask, 'a'] - tiny_height/2,
       height=tiny_height,
       color='red',
       width=0.1)

# 也可以替换成散点标记,更直观
# ax.scatter(x=df.loc[zero_mask, 'desc'], 
#            y=df.loc[zero_mask, 'a'],
#            color='red', marker='o', s=50)

ax.set_ylim(bottom=0, top=1.2)
new_yticks = list(set(df['a']).union(df['b']))
plt.yticks(new_yticks)
plt.show()

方案2:改用线段+标记的展示方式

如果核心是展示两组数值的差异而非严格柱状图,用散点+线段的组合会更灵活,零差异条目自然显示为重合的点,无需处理高度适配问题:

import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame()
df["desc"] = ("A","B","C","D","E")
df["a"] = (0.1,0.5,1,0.6,0.4)
df["b"] = (0.3,0.6,0.6,0.7,0.4)
x_indices = range(len(df['desc']))

fig, ax = plt.subplots()

# 绘制两组数值的标记点
ax.scatter(x_indices, df['a'], color='blue', label='a')
ax.scatter(x_indices, df['b'], color='orange', label='b')

# 绘制连接每组a和b的线段
for i in x_indices:
    ax.plot([i, i], [df['a'][i], df['b'][i]], color='gray', linestyle='-')

# 设置X轴刻度
ax.set_xticks(x_indices)
ax.set_xticklabels(df['desc'])

ax.set_ylim(bottom=0, top=1.2)
new_yticks = list(set(df['a']).union(df['b']))
plt.yticks(new_yticks)
plt.legend()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:33:17