You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib时间序列箱线图中设置X轴主刻度的问题

Matplotlib时间序列箱线图中设置X轴主刻度的问题

嘿,我知道你遇到的这个X轴突然显示1970年的问题了,这其实是seaborn箱线图处理日期轴的小坑导致的,我来帮你捋清楚并解决它~

问题根源

你原来的代码里,直接用df['Date']作为x轴绘制箱线图时,seaborn会把每个不同的日期都当作独立的类别,而不是把x轴当作连续的时间轴。这时候x轴的底层数值其实是类别的索引(0、1、2……),而非日期对应的时间戳。当你用mdates.MonthLocator这类日期定位器时,它会把这些索引值当成时间戳来解析——0对应的就是Unix纪元起始点1970-01-01,所以就出现了奇怪的1970年标签。

解决方案

我们有两种实用的思路来解决这个问题,根据你的数据跨度和需求选择就行:

思路1:按年月分组生成箱线图(适合短时间跨度)

直接给数据新增一个“年月”列,用这个列作为x轴绘制箱线图,手动控制标签显示:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import random

# 生成原始数据
Dates = pd.date_range(start="2020-01-01", end="2020-02-15", freq='D').date
data = {'Date': [], 'Values': []}
for d in Dates:
    data['Date'].extend([d] * 10)
    data['Values'].extend(random.sample(range(1, 101), 10))
df = pd.DataFrame(data)

df['Date'] = pd.to_datetime(df['Date'])
# 新增年月列,格式为"月 年"(比如Jan 2020)
df['Month_Year'] = df['Date'].dt.strftime('%b %Y')

# 基于年月列绘制箱线图
sns.boxplot(x='Month_Year', y='Values', data=df)
plt.xticks(rotation=45)  
plt.title('Time Series Box Plot')
plt.ylabel('Values')
plt.xlabel('Date')
plt.tight_layout()
plt.show()

思路2:将x轴设为连续日期轴(适合长时间跨度,支持间隔刻度)

如果你的数据跨度多年,想要灵活设置每N个月显示一次刻度,可以把每个日期转换为当月第一天,让x轴成为连续的时间轴,再用matplotlib的日期工具控制刻度:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import matplotlib.dates as mdates
import random

# 生成跨多年的测试数据
Dates = pd.date_range(start="2020-01-01", end="2022-02-15", freq='D').date
data = {'Date': [], 'Values': []}
for d in Dates:
    data['Date'].extend([d] * 10)
    data['Values'].extend(random.sample(range(1, 101), 10))
df = pd.DataFrame(data)

df['Date'] = pd.to_datetime(df['Date'])
# 将每个日期转换为当月第一天,作为箱线图的分组依据
df['Month_Start'] = df['Date'].dt.to_period('M').dt.start_time

# 基于当月第一天绘制箱线图,此时x轴是连续时间轴
ax = sns.boxplot(x='Month_Start', y='Values', data=df)
plt.xticks(rotation=45)  
plt.title('Time Series Box Plot')
plt.ylabel('Values')
plt.xlabel('Date')

# 设置每2个月显示一个刻度,格式为"月 年"
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=2))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
plt.tight_layout()
plt.show()

这两种方法都能完美解决你遇到的1970年刻度问题,同时满足你只显示月份和年份、控制刻度间隔的需求~

备注:内容来源于stack exchange,提问作者yippie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:28:07