如何用循环绘制多分组条形图?30+Sector的DataFrame绘图问题
解决分组条形图绘制问题
错误原因分析
你遇到的 TypeError: can't multiply sequence by non-int of type 'float' 是因为代码中 for i in df 会遍历DataFrame的列名(Month、Sector、CWD),而非你需要的各个Sector分组。当尝试执行 df['Month']+width*i 时,i 是字符串类型,无法与浮点数width相乘,导致报错。
修正后的代码实现
以下是满足需求的完整代码,包含分组条形图绘制、随机颜色生成等功能:
import matplotlib.pyplot as plt import pandas as pd import numpy as np # 确保数据按Month排序 df = df.sort_values(['Month', 'Sector']) # 获取唯一的月份和扇区列表 months = sorted(df['Month'].unique()) sectors = df['Sector'].unique() num_sectors = len(sectors) # 设置每个条形的宽度,确保同一月份的所有条形总宽度小于1(预留间隙) bar_width = 0.8 / num_sectors # 创建月份对应的x轴位置(用数字索引,方便偏移) x = np.arange(len(months)) # 创建画布和轴 fig = plt.figure('Graphic', figsize=(20,15), dpi=300) ax1 = fig.add_axes([0.2, 0.25, 0.80, 0.60]) # 遍历每个扇区绘制条形 for idx, sector in enumerate(sectors): # 获取当前扇区的CWD数据,按月份排序 sector_cwd = df[df['Sector'] == sector].sort_values('Month')['CWD'].values # 计算当前扇区条形的x轴偏移位置 bar_x = x + idx * bar_width # 生成随机RGB颜色 random_color = np.random.rand(3,) # 绘制条形 ax1.bar(bar_x, sector_cwd, width=bar_width, label=sector, color=random_color) # 设置x轴刻度为月份,位置在每个月份组的中间 ax1.set_xticks(x + bar_width * (num_sectors - 1) / 2) ax1.set_xticklabels(months) # 添加标签和图例 ax1.set_xlabel('Month') ax1.set_ylabel('CWD') ax1.set_title('CWD by Month and Sector') # 若扇区数量多,调整图例位置避免遮挡 ax1.legend(bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
关键改进点
- 正确遍历分组:通过
df['Sector'].unique()获取所有扇区,逐个处理每个扇区的数据。 - 合理的条形位置偏移:使用
np.arange(len(months))作为月份的基准位置,每个扇区的条形按索引偏移idx * bar_width,确保同一月份的条形紧密排列。 - 随机颜色生成:用
np.random.rand(3,)生成随机RGB颜色值,每个扇区对应唯一颜色。 - 清晰的轴刻度:将x轴刻度设置在每个月份组的中间,保证标签与条形组对齐。
内容的提问来源于stack exchange,提问作者Javier
相关产品推荐
相关产品推荐

