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

Pandas/Matplotlib绘图如何排除空值消除柱状图空白

问题根因

空白占位是最后一步透视表逻辑导致的:三个年份的Top5数据拼接后做pivot_table,会把所有出现过的7个国家全部转为列,未进入当年Top5的国家对应值为NaN,pandas内置的分组柱状图默认会给所有列预留柱位,NaN值就会显示为空白。不需要拆分成多个子图就能解决。
另外原代码中# create pivot table注释下对全量df做透视的代码没有被后续逻辑调用,可以直接删除。

修复方案

放弃pandas自动生成分组柱的逻辑,手动控制每个年份组的柱位置,按年份分别绘制对应Top5的柱即可,每个年份组固定显示5个有效柱,不会预留空白位。同时给国家分配固定颜色,保证跨年份对比时同一个国家颜色一致,对图例做去重避免重复显示。
完整可运行代码如下:

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

# 读取数据、过滤区域聚合实体
df = pd.read_csv('~/Python/Projects/Jupyter Notebooks/Jupyter Notes and Exercises/Exercises/Energy Exercises/archive/wind-generation.csv')
df = df.drop('Code', axis=1)
df = df[~df['Entity'].isin(['OECD', 'Non-OECD', 'North America', 'South & Central America', 'Europe',
                         'Asia Pacific', 'European Union', 'World', 'Africa', 'Upper-middle-income countries','G20','G7',
                            'European Union (27)','High-income countries','Asia', 
                            'Lower-middle-income countries','Latin America and Caribbean','South America'])]

# 批量提取三个年份的Top5数据
target_years = [2000, 2010, 2020]
year_data = {}
all_countries = set()
for y in target_years:
    top5_df = df[df['Year'] == y].sort_values('Electricity from wind (TWh)', ascending=False).head(5)
    year_data[y] = (top5_df['Entity'].tolist(), top5_df['Electricity from wind (TWh)'].tolist())
    all_countries.update(top5_df['Entity'].tolist())

# 为每个国家分配固定配色
color_map = plt.cm.tab10
country_color = {c: color_map(i) for i, c in enumerate(all_countries)}

bar_w = 0.15
group_gap = 0.3  # 不同年份组之间的间距
fig, ax = plt.subplots(figsize=(8,4))

# 逐年份绘制柱
for idx, y in enumerate(target_years):
    country_list, val_list = year_data[y]
    # 计算当前年份组5个柱的x坐标
    x = np.arange(5) + idx*(5*bar_w + group_gap)
    bars = ax.bar(x, val_list, width=bar_w)
    # 按国家设置颜色、绑定标签
    for bar, c in zip(bars, country_list):
        bar.set_color(country_color[c])
        bar.set_label(c)

# 配置坐标轴和标题
ax.set_xticks([np.arange(5).mean() + i*(5*bar_w + group_gap) for i in range(len(target_years))])
ax.set_xticklabels(target_years, rotation=0)
ax.set_xlabel('Year')
ax.set_ylabel('Wind Generation (TWh)')
ax.set_title('Generation of Wind Energy by \nTop 5 Wind Energy-Producing Countries')
ax.grid(True, axis='y')

# 去重图例,放在图外侧避免遮挡
handles, labels = ax.get_legend_handles_labels()
ax.legend(dict(zip(labels, handles)).values(), dict(zip(labels, handles)).keys(), bbox_to_anchor=(1.02, 1), loc='upper left')

plt.tight_layout()
plt.savefig('Wind Energy Top 5.png', facecolor='white')
plt.show()
效果说明
  • 每个年份分组固定显示5个柱,不存在空白占位
  • 同一国家在不同年份的柱颜色统一,方便跨期对比
  • 年份组之间保留了足够间距,不会出现柱重叠
  • 图例自动去重,不会重复展示相同国家条目

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:09:26