Matplotlib绘制相同x标签多数据聚合分组柱状图方法
你的两版代码无法实现分组效果的核心原因是没有对重复名称的分析结果做聚合:你采集到的三个列表是逐文件生成的扁平结构,同名分析对应多条重复记录,Matplotlib不会自动合并同名x轴标签,必须先完成数据结构化归集,再按组计算柱位绘图。
注意:同一分析文件夹下孤立模型CSV只有1个,所以同一分析名对应的max_disp_iso值是重复的,绘图时每组只需要绘制1次孤立模型柱即可,无需重复绘制。
实现代码
把你原来遍历完所有文件夹、准备绘图的部分,替换为以下代码即可:
from collections import defaultdict import numpy as np import matplotlib.pyplot as plt # ---------------------- 1. 聚合同名分析数据 ---------------------- agg_data = defaultdict(lambda: {"iso_val": None, "asb_vals": []}) for name, iso_v, asb_v in zip(analysis, max_disp_iso, max_disp_asb): # 同个分析的孤立模型值固定,仅存储1次 if agg_data[name]["iso_val"] is None: agg_data[name]["iso_val"] = iso_v agg_data[name]["asb_vals"].append(asb_v) # 提取去重后的分析名称作为x轴主标签 unique_analysis_names = list(agg_data.keys()) n_analysis_groups = len(unique_analysis_names) bar_width = 0.2 # 单根柱宽度,可根据显示效果调整 # ---------------------- 2. 分组绘制柱状图 ---------------------- fig, ax = plt.subplots(figsize=(12, 6)) x_group_centers = np.arange(n_analysis_groups) # 每个分析组的中心x坐标 for group_idx, analysis_name in enumerate(unique_analysis_names): group_res = agg_data[analysis_name] # 组内柱顺序:1个孤立模型柱 + N个装配模型柱 bar_heights = [group_res["iso_val"]] + group_res["asb_vals"] bar_legends = ["Isolated model"] + [f"Assembled model {i+1}" for i in range(len(group_res["asb_vals"]))] n_bars_in_group = len(bar_heights) # 计算组内每根柱的x偏移,保证整组柱居中对齐x轴标签 bar_offsets = np.linspace( -(n_bars_in_group - 1)*bar_width/2, (n_bars_in_group - 1)*bar_width/2, n_bars_in_group ) # 逐根绘制柱形 for bar_idx, (height, offset, legend) in enumerate(zip(bar_heights, bar_offsets, bar_legends)): # 仅在第一个组添加图例,避免重复 legend_label = legend if group_idx == 0 else "" # 固定配色,同类型模型颜色一致 bar_color = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728"][bar_idx] rect = ax.bar( x_group_centers[group_idx] + offset, height, width=bar_width, label=legend_label, color=bar_color ) ax.bar_label(rect, padding=2, fmt="%.4f") # 标注柱顶数值,可调整小数位数 # ---------------------- 3. 图表样式配置 ---------------------- ax.set_xticks(x_group_centers, unique_analysis_names) ax.set_ylabel("Maximum displacement (m)") ax.set_title("Max Displacement: Isolated vs Assembled Model") ax.legend() fig.tight_layout() plt.show()
适配说明
- 自动适配不同分析组的柱数量:仅含1个装配模型的组会显示2根柱,含3个装配模型的组会显示4根柱,不会出现多余空位
- 同类型模型使用统一配色,跨组对比更清晰
- 图例仅生成一次,不会出现重复项
- 柱顶数值标注格式可通过
fmt参数调整,柱宽、画布大小、配色都可以根据需求修改
内容的提问来源于stack exchange,提问作者MathisGauthey
相关产品推荐
相关产品推荐

