如何用Matplotlib按正确类别顺序绘制分组条形图?
解决Matplotlib条形图数据绘制顺序错误的问题
问题说明
我使用Matplotlib编写了条形图代码,当前存在数据绘制顺序错误的问题。希望设置['25 kWh', '50 kWh', '80 kWh']三个类别,每个类别下对应展示['Optimal Control', 'PSC', 'PSC-ANN']三种方法的数据,且输入数据(如improvement_25_kWh)始终按方法顺序排列,请问该如何调整代码?
原代码
import matplotlib.pyplot as plt import numpy as np # Categories and methods categories = ['25 kWh', '50 kWh', '80 kWh'] methods = ['Optimal Control', 'PSC', 'PSC-ANN'] #Input data improvement_25_kWh = [13.3, 4.1, 5.4] improvement_50_kWh = [13.8, 6.3, 4.4] improvement_80_kWh = [14.3, 8.5, 3.8] bar_width = 0.2 bar_positions_25_kWh = np.arange(len(categories)) bar_positions_50_kWh = bar_positions_25_kWh + bar_width bar_positions_80_kWh = bar_positions_50_kWh + bar_width plt.figure(figsize=(12, 7)) bars_25_kWh = plt.bar(bar_positions_25_kWh, improvement_25_kWh, color='blue', width=bar_width, label='Optimal Control') bars_50_kWh = plt.bar(bar_positions_50_kWh, improvement_50_kWh, color='orange', width=bar_width, label='PSC') bars_80_kWh = plt.bar(bar_positions_80_kWh, improvement_80_kWh, color='green', width=bar_width, label='PSC-ANN') plt.xlabel('Building types', fontsize=17) plt.ylabel('Improvement (%)', fontsize=17) plt.xticks(bar_positions_50_kWh, categories, fontsize=15) plt.yticks(fontsize=15) plt.legend(fontsize=17) plt.savefig(r'C:\Users\User1\Desktop\Result_Percentage_Improvements.png', bbox_inches='tight', dpi=200) plt.show()
问题分析
原代码逻辑错误:将每个类别的所有方法数据作为一组,对应到x轴的三个类别位置上,导致每个x位置的条形是不同类别的同方法数据,和需求的“每个类别下展示三个方法的条形”完全相反。
修正后的代码
import matplotlib.pyplot as plt import numpy as np # Categories and methods categories = ['25 kWh', '50 kWh', '80 kWh'] methods = ['Optimal Control', 'PSC', 'PSC-ANN'] colors = ['blue', 'orange', 'green'] # Input data (每个列表按方法顺序排列:Optimal Control, PSC, PSC-ANN) improvement_25_kWh = [13.3, 4.1, 5.4] improvement_50_kWh = [13.8, 6.3, 4.4] improvement_80_kWh = [14.3, 8.5, 3.8] # 将数据按方法重新组织:每个方法对应三个类别的数据 method_data = [ [improvement_25_kWh[0], improvement_50_kWh[0], improvement_80_kWh[0]], # Optimal Control [improvement_25_kWh[1], improvement_50_kWh[1], improvement_80_kWh[1]], # PSC [improvement_25_kWh[2], improvement_50_kWh[2], improvement_80_kWh[2]] # PSC-ANN ] bar_width = 0.2 # 每个类别的基准位置 category_positions = np.arange(len(categories)) plt.figure(figsize=(12, 7)) # 循环绘制每个方法的条形:每个类别下对应方法的条形 for i, (method, data, color) in enumerate(zip(methods, method_data, colors)): # 每个方法的条形位置 = 类别基准位置 + bar_width * 方法索引 bar_positions = category_positions + bar_width * i plt.bar(bar_positions, data, width=bar_width, color=color, label=method) plt.xlabel('Building types', fontsize=17) plt.ylabel('Improvement (%)', fontsize=17) # 设置x轴刻度:位置为每个类别组的中间位置,标签为类别名 plt.xticks(category_positions + bar_width, categories, fontsize=15) plt.yticks(fontsize=15) plt.legend(fontsize=17) plt.savefig(r'C:\Users\User1\Desktop\Result_Percentage_Improvements.png', bbox_inches='tight', dpi=200) plt.show()
关键调整点
- 数据重组:将输入数据按方法维度重新整理,每个方法对应三个类别的数据,确保和绘图逻辑匹配
- 条形位置修正:以每个类别为基准,每个方法的条形位置偏移
bar_width * 方法索引,保证同一类别下的三个方法条形相邻 - x轴刻度调整:将刻度位置设置为每个类别组的中间位置(
category_positions + bar_width),让标签和类别组对齐
内容的提问来源于stack exchange,提问作者PeterBe
相关产品推荐
相关产品推荐

