Matplotlib bar绘图为何未对相同X轴标签的Y值求和?
问题原因与解决办法
为什么只显示最后一个Y值?
matplotlib的ax.bar()函数不会自动对重复的X轴标签做数值聚合,它的逻辑是:传入多少组(x,y)对,就绘制多少个柱状条。当多个柱状条的X轴标签相同时,它们会被绘制在同一个位置,后绘制的柱状条会完全覆盖前面的,所以你看到的是每个标签对应的最后一个Y值(比如F对应的9,是列表中最后一个F的Y值)。
你的代码里x有10个元素、y对应10个值,实际生成了10个柱状条,但其中D对应4个、F对应2个,这些重叠的柱状条被后绘制的覆盖,最终视觉上只显示每个标签的最后一个Y值。
解决办法:先聚合数据再绘图
要实现相同标签的Y值累加,需要先手动对数据按X标签分组求和,再传入bar()函数。
方法1:用Python字典手动聚合
import matplotlib.pyplot as plt x = ['A', 'B', 'C', 'D', 'D', 'D', 'D', 'E', 'F', 'F'] y = [5, 8, 7, 9, 9, 2, 7, 8, 8, 9] # 按标签累加Y值 sum_data = {} for label, value in zip(x, y): sum_data[label] = sum_data.get(label, 0) + value # 提取聚合后的标签和数值 agg_labels = list(sum_data.keys()) agg_values = list(sum_data.values()) fig, ax = plt.subplots() ax.bar(agg_labels, agg_values) # 添加数值标签让结果更清晰 for i, v in enumerate(agg_values): ax.text(i, v + 0.2, str(v), ha='center') plt.show()
方法2:用Pandas分组聚合(更简洁)
如果数据量较大,用Pandas的分组功能会更高效:
import matplotlib.pyplot as plt import pandas as pd x = ['A', 'B', 'C', 'D', 'D', 'D', 'D', 'E', 'F', 'F'] y = [5, 8, 7, 9, 9, 2, 7, 8, 8, 9] # 转为DataFrame并分组求和 df = pd.DataFrame({'category': x, 'value': y}) agg_df = df.groupby('category')['value'].sum().reset_index() fig, ax = plt.subplots() ax.bar(agg_df['category'], agg_df['value']) # 添加数值标签 for idx, row in agg_df.iterrows(): ax.text(idx, row['value'] + 0.2, str(row['value']), ha='center') plt.show()
补充:如果需要堆叠柱状图
如果你想展示每个重复标签下的细分Y值(而非总和),可以用bottom参数实现堆叠效果:
import matplotlib.pyplot as plt from collections import defaultdict x = ['A', 'B', 'C', 'D', 'D', 'D', 'D', 'E', 'F', 'F'] y = [5, 8, 7, 9, 9, 2, 7, 8, 8, 9] # 按标签收集所有Y值 grouped = defaultdict(list) for label, val in zip(x, y): grouped[label].append(val) fig, ax = plt.subplots() labels = list(grouped.keys()) bottom = [0] * len(labels) # 逐个绘制堆叠的柱状条 for label_idx, label in enumerate(labels): values = grouped[label] for val in values: ax.bar(label_idx, val, bottom=bottom[label_idx]) bottom[label_idx] += val # 设置X轴标签 ax.set_xticks(range(len(labels))) ax.set_xticklabels(labels) plt.show()
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

