如何将DataFrame列名设为柱状图X轴,实现非堆叠叠加分组柱状图?
绘制叠加式分组柱状图(非堆叠)
给定的Pandas DataFrame
import pandas as pd data = {'name': ['Bob', 'Chuck', 'Daren', 'Elisa'], '100m': [19, 14, 12, 11], '200m': [36, 25, 24, 24], '400m': [67, 64, 58, 57], '800m': [117, 120, 123, 121]} df = pd.DataFrame(data)
对应的表格展示:
| name | 100m | 200m | 400m | 800m | |
|---|---|---|---|---|---|
| 0 | Bob | 19 | 36 | 67 | 117 |
| 1 | Chuck | 14 | 25 | 64 | 120 |
| 2 | Daren | 12 | 24 | 58 | 123 |
| 3 | Elisa | 11 | 24 | 57 | 121 |
需求
- 绘制柱状图:Y轴为时间(各赛事的数值),X轴为赛事名称(100m、200m、400m、800m),用
name列的不同个体作为颜色区分 - 要求柱子是叠加并排显示(同一赛事下的柱子挨在一起,不是堆叠在同一位置),但Seaborn和Matplotlib没有直接实现该样式的功能,需要手动处理
解决方案
要实现这种并排分组的柱状图,关键是给每个个体的柱子设置不同的X轴偏移量,让它们在同一赛事位置上错开排列。具体代码如下:
步骤1:转换数据格式(宽表转长表)
先把原数据转成适合分组处理的长格式:
df_melted = df.melt(id_vars='name', var_name='event', value_name='time')
步骤2:手动绘制并排柱状图
import matplotlib.pyplot as plt import numpy as np # 获取赛事和人员列表 events = df['100m':'800m'].columns.tolist() names = df['name'].tolist() event_count = len(events) name_count = len(names) # 设置柱子宽度和偏移量 bar_width = 0.2 base_x = np.arange(event_count) # 每个赛事的基础X坐标 plt.figure(figsize=(10, 6)) # 循环绘制每个人的柱子 for idx, name in enumerate(names): # 获取当前人员的所有赛事时间 person_times = df[df['name'] == name].iloc[0, 1:].tolist() # 计算当前柱子的X位置(基础坐标 + 偏移) plt.bar(base_x + idx * bar_width, person_times, width=bar_width, label=name) # 设置轴标签和刻度 plt.xlabel('赛事') # 让X轴刻度居中在每组柱子中间 plt.xticks(base_x + bar_width * (name_count - 1)/2, events) plt.ylabel('时间') plt.title('不同人员各赛事用时对比') plt.legend(title='姓名') plt.tight_layout() plt.show()
效果说明
这段代码会在每个赛事对应的X轴位置,并排显示4个不同颜色的柱子(对应4个人),完全实现你要的叠加而非堆叠的样式,同时颜色区分个体,符合需求。
内容的提问来源于stack exchange,提问作者You_Donut
相关产品推荐
相关产品推荐

