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

pandas v1.3.0中DataFrame.plot()绘制柱状图忽略0值的实现方法

问题根源说明

pandas v1.3.0 版本的柱状图绘制接口不会自动跳过0值或NaN值,你将0替换为NaN的方案失效,是因为该版本会默认将NaN处理为0高度进行渲染,所以还是会显示无效的空白占位。


可行解决方案

方案1:最小改动适配原有逻辑

直接在原有代码绘制后,移除高度为0的柱子即可,无需调整数据结构:

X_AXIS = x_axis_labels_list
index = pd.Index(X_AXIS, name= 'my_name')
cmap = 'tab20'
df = pd.DataFrame(dic, index=index)
ax = df.plot(kind='bar', figsize=(50, 6), colormap=cmap)

# 新增代码:删除高度为0的柱子,加极小阈值避免浮点精度导致的判断误差
for bar_container in ax.containers:
    for bar in bar_container:
        if bar.get_height() < 1e-9:
            bar.remove()

ax.set_ylabel('tk score')
plt.legend(title='labels', bbox_to_anchor=(1.0, 1), loc='upper left')
plt.show()

方案2:调整数据格式过滤0值后绘图

如果需要从数据层面提前过滤无效值,可以将宽表转换为长表,过滤0值后再绘制:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

X_AXIS = x_axis_labels_list
cmap = 'tab20'
df = pd.DataFrame(dic, index=X_AXIS)

# 宽表转长表,过滤0值
df_long = df.stack().reset_index()
df_long.columns = ['x_label', 'protein', 'score']
df_long = df_long[df_long['score'] > 1e-9]

# 配置颜色映射,和原pandas绘图逻辑保持一致
protein_all = df.columns.tolist()
color_list = plt.get_cmap(cmap)(np.linspace(0, 1, len(protein_all)))
color_mapper = dict(zip(protein_all, color_list))

# 计算分组柱子的偏移量
bar_width = 0.8 / len(protein_all)
x_tick_pos = np.arange(len(X_AXIS))

plt.figure(figsize=(50,6))
for protein in protein_all:
    sub_data = df_long[df_long['protein'] == protein]
    x_pos = [x_tick_pos[X_AXIS.index(label)] + bar_width * protein_all.index(protein) for label in sub_data['x_label']]
    plt.bar(x_pos, sub_data['score'], width=bar_width, color=color_mapper[protein], label=protein)

plt.xticks(x_tick_pos + 0.4, X_AXIS)
plt.ylabel('tk score')
plt.legend(title='labels', bbox_to_anchor=(1.0, 1), loc='upper left')
plt.tight_layout()
plt.show()

两个方案都可以在pandas v1.3.0下实现仅渲染非0柱子的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:09:03