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

Matplotlib垂直网格线与数据点不匹配问题求助

Matplotlib垂直网格线与数据点不对齐问题

问题详情

请问为何Matplotlib绘制的垂直网格线无法与数据点对齐?

垂直网格线与数据点错位示例

绘图数据

{
    datetime.datetime(2025, 4, 15, 19, 23, 50, 658000, tzinfo=datetime.timezone.utc): 68.0,
    datetime.datetime(2025, 4, 16, 19, 31, 1, 367000, tzinfo=datetime.timezone.utc): 72.0,
    datetime.datetime(2025, 4, 17, 19, 34, 21, 507000, tzinfo=datetime.timezone.utc): 75.0,
    datetime.datetime(2025, 4, 18, 19, 50, 28, 446000, tzinfo=datetime.timezone.utc): 80.0,
    datetime.datetime(2025, 4, 19, 19, 57, 15, 393000, tzinfo=datetime.timezone.utc): 78.0,
    datetime.datetime(2025, 4, 20, 19, 57, 49, 60000, tzinfo=datetime.timezone.utc): 77.0,
    datetime.datetime(2025, 4, 21, 20, 28, 51, 127710, tzinfo=datetime.timezone.utc): 73.0
}

绘图代码

fig, ax = plt.subplots(figsize=(12, 6))

ax.plot(df['Дата'], df['Вес'], marker='o', linestyle='-', color='royalblue', label='Вес')

ax.scatter(df['Дата'], df['Вес'], color='red', zorder=5)

ax.set_title('График изменения веса по дням', fontsize=16)
ax.set_xlabel('Дата', fontsize=12)
ax.set_ylabel('Вес (кг)', fontsize=12)
ax.xaxis.set_major_locator(mdates.AutoDateLocator())  # Раз в день

ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%Y'))

plt.setp(ax.xaxis.get_majorticklabels(), rotation=45, ha="right")

ax.grid(True, linestyle='--', alpha=0.6)

plt.tight_layout()

原因分析

数据点的datetime包含具体时分秒,但AutoDateLocator默认将x轴主刻度定位到当日0点,而非数据点的实际时间位置,导致垂直网格线(与刻度绑定)和数据点错位。

解决办法

方案1:让网格线完全对齐数据点

替换自动日期定位器,直接将x轴刻度设置为数据中的datetime值:

fig, ax = plt.subplots(figsize=(12, 6))

ax.plot(df['Дата'], df['Вес'], marker='o', linestyle='-', color='royalblue', label='Вес')
ax.scatter(df['Дата'], df['Вес'], color='red', zorder=5)

ax.set_title('График изменения веса по дням', fontsize=16)
ax.set_xlabel('Дата', fontsize=12)
ax.set_ylabel('Вес (кг)', fontsize=12)

# 替换AutoDateLocator,使用数据中的日期作为刻度
ax.set_xticks(df['Дата'])
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%Y'))

plt.setp(ax.xaxis.get_majorticklabels(), rotation=45, ha="right")
ax.grid(True, linestyle='--', alpha=0.6)

plt.tight_layout()

方案2:对齐到日期(忽略时分秒)

如果希望刻度显示为完整日期,可先提取数据中的日期部分,再设置刻度:

# 先提取日期(忽略时分秒)
df['Дата_день'] = df['Дата'].dt.date

fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(df['Дата'], df['Вес'], marker='o', linestyle='-', color='royalblue', label='Вес')
ax.scatter(df['Дата'], df['Вес'], color='red', zorder=5)

ax.set_title('График изменения веса по дням', fontsize=16)
ax.set_xlabel('Дата', fontsize=12)
ax.set_ylabel('Вес (кг)', fontsize=12)

# 设置刻度为日期对象
ax.set_xticks(df['Дата_день'])
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d.%m.%Y'))

plt.setp(ax.xaxis.get_majorticklabels(), rotation=45, ha="right")
ax.grid(True, linestyle='--', alpha=0.6)

plt.tight_layout()

内容的提问来源于stack exchange,提问作者andrey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:02:07