如何用Matplotlib在Python中绘制数量可变的分组柱状图?
自适应分组柱状图实现方案
核心思路
从嵌套字典中提取所有方法、场景信息,用matplotlib动态计算柱子位置与宽度,实现对任意数量方法、场景的自适应绘图。
完整代码示例
import matplotlib.pyplot as plt import numpy as np # 示例嵌套字典(可替换为你的实际数据) my_dict = { "MethodA": {"Scenario1": 12, "Scenario2": 18, "Scenario3": 15}, "MethodB": {"Scenario1": 15, "Scenario2": 14, "Scenario3": 19}, "MethodC": {"Scenario1": 9, "Scenario2": 22, "Scenario3": 17} } # 1. 提取方法和场景列表 methods = list(my_dict.keys()) # 假设所有方法的场景一致,取第一个方法的场景集合 scenarios = list(next(iter(my_dict.values())).keys()) num_methods = len(methods) num_scenarios = len(scenarios) # 2. 计算柱子宽度与位置 bar_width = 0.8 / num_methods # 分组总宽度控制在0.8,避免重叠 x = np.arange(num_scenarios) # 场景对应的x轴基准位置 # 3. 绘制分组柱状图 plt.figure(figsize=(10, 6)) for i, method in enumerate(methods): # 每个方法的柱子位置:基准x + 偏移量 bar_positions = x + i * bar_width # 提取当前方法在各场景下的数值 values = [my_dict[method][scenario] for scenario in scenarios] plt.bar(bar_positions, values, width=bar_width, label=method) # 4. 设置图表属性 plt.xlabel("场景") plt.ylabel("数值") plt.title("不同场景下各方法的数值对比") # 设置x轴刻度为场景名称,位置调整为分组中心 plt.xticks(x + bar_width * (num_methods - 1) / 2, scenarios) plt.legend(title="方法") plt.tight_layout() # 自动调整布局,避免标签被截断 plt.show()
关键自适应逻辑说明
- 方法数量自适应:通过
num_methods = len(methods)动态计算柱子宽度,循环遍历所有方法绘制对应柱子,无需硬编码方法名称。 - 场景数量自适应:从字典中自动提取场景列表,x轴刻度与柱子数量随场景数量变化,无需手动修改。
- 柱子位置计算:利用
numpy生成基准x轴位置,每个方法的柱子在基准位置上叠加偏移量,保证分组紧凑且不重叠。
额外处理提示
如果不同方法包含的场景不一致,可以先提取所有场景的并集,对缺失场景的数值填充为0或NaN:
# 获取所有场景的并集 all_scenarios = set() for method_data in my_dict.values(): all_scenarios.update(method_data.keys()) scenarios = sorted(all_scenarios) # 填充缺失值为0 values = [my_dict[method].get(scenario, 0) for scenario in scenarios]
内容的提问来源于stack exchange,提问作者LaithovariuS
相关产品推荐
相关产品推荐

