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
相关产品推荐
相关产品推荐

