如何修正Matplotlib+pandas图表X轴日期乱序问题?
问题:Matplotlib图表X轴日期未按时间顺序排列
我想要为Exercises列表中的每个训练项目绘制图表,展示Participants列表中每位参与者的成绩随日期的变化情况。我使用了两层循环实现,但生成的图表X轴日期未按时间顺序排列。
代码如下:
Participants = ['Yannick','Levin','Luca','Lars','Livio','Tim','Ryan','Schumi','Marc'] Exercises = ['100 Burpees for Time','Max. 1 Rep Benchpress','Max. Reps Muscle Ups','100 Turkish Get Ups','30 min. stationary bike','100 Pullups','500 Double Unders','Murph','1 hour row','5km run','Grace','Linda','Max Bar Hang','Amrap 14','1km Swim','5 Reps Deadlift','5 Reps Clean','Hero Workout \"Miro\"','The Schumi','2km row'] for exercise in Exercises: # define plot plt.figure(figsize=(12, 8)) plt.title(exercise, fontsize = 18) for participant in Participants: # get Score and Date columns from pandas and plot them Score = data_csv.loc[(data_csv.Participant == participant)].loc[data_csv.Exercise == exercise]['Score'] Date = data_csv.loc[(data_csv.Participant == participant)].loc[data_csv.Exercise == exercise]['Date'] plt.plot(Date, Score, label = participant) plt.scatter(Date, Score, marker='o') plt.grid(axis = 'y') plt.xticks(rotation = 30) plt.legend(fontsize=14,bbox_to_anchor=(1.2, 1.05)) #plt.savefig('name1_{}.pdf'.format(name)) plt.show()
生成的图表中X轴日期顺序混乱,请问该如何解决这个问题?
解决方法
核心原因
你的Date列大概率是字符串类型,而非pandas的datetime类型。Matplotlib对字符串类型的日期会按字典序排列,而非时间先后顺序,导致X轴混乱。
具体修复步骤
- 将Date列转为datetime类型
在读取data_csv之后,先执行类型转换:
import pandas as pd # 转换日期列,若你的日期格式特殊,可指定format参数(比如'%Y-%m-%d') data_csv['Date'] = pd.to_datetime(data_csv['Date'])
- 筛选数据后按日期排序
即使日期列转为datetime,筛选后的子集可能仍存在乱序,需先排序再绘图。修改内层循环的数据获取逻辑:
for participant in Participants: # 筛选对应参与者和训练项目的数据,并按日期排序 filtered_data = data_csv.loc[ (data_csv['Participant'] == participant) & (data_csv['Exercise'] == exercise) ].sort_values('Date') # 跳过无数据的情况,避免报错 if filtered_data.empty: continue Score = filtered_data['Score'] Date = filtered_data['Date'] plt.plot(Date, Score, label=participant) plt.scatter(Date, Score, marker='o')
- 优化图表属性设置
把重复的图表配置(网格、刻度旋转、图例)移到内层循环外,避免重复执行:
for exercise in Exercises: plt.figure(figsize=(12, 8)) plt.title(exercise, fontsize=18) for participant in Participants: filtered_data = data_csv.loc[ (data_csv['Participant'] == participant) & (data_csv['Exercise'] == exercise) ].sort_values('Date') if filtered_data.empty: continue plt.plot(filtered_data['Date'], filtered_data['Score'], label=participant) plt.scatter(filtered_data['Date'], filtered_data['Score'], marker='o') # 统一设置图表样式 plt.grid(axis='y') plt.xticks(rotation=30) plt.legend(fontsize=14, bbox_to_anchor=(1.2, 1.05)) plt.tight_layout() # 防止图例被画布截断 plt.show()
内容的提问来源于stack exchange,提问作者lbaltensp
相关产品推荐
相关产品推荐

