Matplotlib中X轴日期格式设置异常问题排查与解决
问题描述
我有如下数据集:
ID Date Chemical Group 0 6 06-12-21 21 1 1 12 07-03-22 26 2 2 11 08-03-22 28 1 3 13 08-03-22 29 2 4 15 08-03-22 28 1 5 14 09-03-22 26 2 6 7 16-12-21 23 2 7 8 16-12-21 24 2 8 9 16-12-21 23 2 9 10 16-12-21 25 1 10 1 20-11-21 21 1 11 2 26-11-21 19 2 12 3 26-11-21 31 2 13 5 26-11-21 32 1 14 4 27-11-21 31 2
将Date列转为datetime类型并排序:
maindf['Date'] = pd.to_datetime(maindf['Date'], format='%d-%m-%y') maindf.sort_values('Date', inplace=True) print(maindf)
转换后日期识别正常:
ID Date Chemical Group 10 1 2021-11-20 21 1 11 2 2021-11-26 19 2 12 3 2021-11-26 31 2 13 5 2021-11-26 32 1 14 4 2021-11-27 31 2 0 6 2021-12-06 21 1 6 7 2021-12-16 23 2 7 8 2021-12-16 24 2 8 9 2021-12-16 23 2 9 10 2021-12-16 25 1 1 12 2022-03-07 26 2 2 11 2022-03-08 28 1 3 13 2022-03-08 29 2 4 15 2022-03-08 28 1 5 14 2022-03-09 26 2
用Seaborn绘制箱线图时,X轴日期附带0时分秒:
import seaborn as sns sns.boxplot(data=maindf, x='Date', y='Chemical', hue='Group') plt.xticks(rotation=20) plt.show()
尝试用DateFormatter修改日期格式后,X轴全部显示为1970年起始的错误日期:
sns.boxplot(data=maindf, x='Date', y='Chemical', hue='Group') from matplotlib.dates import DateFormatter dtFmt = DateFormatter('%d-%m-%y') # define the formatting plt.gca().xaxis.set_major_formatter(dtFmt) plt.xticks(rotation=20) plt.show()
请问问题出在哪里,该如何修正?
问题原因
Seaborn的boxplot处理datetime类型的x轴时,会自动将datetime值转换为从0开始的整数索引,而非保留datetime对象。此时用DateFormatter格式化这些整数,matplotlib会把它们当作Unix时间戳(从1970-01-01开始的秒数),因此出现1970年的错误日期。
解决方法
方案1:手动替换X轴刻度标签
提取唯一日期并格式化后,直接替换X轴的刻度标签:
import seaborn as sns from matplotlib import pyplot as plt # 绘制箱线图 ax = sns.boxplot(data=maindf, x='Date', y='Chemical', hue='Group') # 提取唯一日期并格式化为指定样式 unique_dates = maindf['Date'].dt.strftime('%d-%m-%y').unique() # 设置X轴刻度标签 ax.set_xticklabels(unique_dates) plt.xticks(rotation=20) plt.show()
方案2:使用格式化后的日期字符串作为X轴
先将datetime列转为目标格式的字符串,再传入绘图函数:
import seaborn as sns from matplotlib import pyplot as plt # 创建格式化后的日期列 maindf['Date_str'] = maindf['Date'].dt.strftime('%d-%m-%y') # 绘制箱线图 g = sns.catplot(data=maindf, x='Date_str', y='Chemical', hue='Group', kind='box') g.set_xticklabels(rotation=20) plt.show()
内容的提问来源于stack exchange,提问作者rnso
相关产品推荐
相关产品推荐

