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

Matplotlib Y轴刻度定位器失效问题排查求助

Y轴刻度混乱及颠倒问题排查与解决

问题背景

我有两个表格:

  • 表格1:包含起始日期(Date_Start)和结束日期(Date_Stop)列,需据此生成起始日00:00至结束日23:00的小时级datetime序列
  • 表格2:小时级DST数据及对应时间戳

编写代码遍历表格1的每一行,将时间序列与表格2的对应数据匹配,逐行绘制子图(无匹配数据则填充0)。但设置Y轴范围为-150至150、刻度间隔为50后,实际输出的Y轴刻度值混乱,甚至出现刻度值颠倒(如-37刻度在-12上方)的情况。

原代码

fig, axs = plt.subplots(len(themis_data), figsize=(10, 2*len(themis_data)))
for ax, (index, row) in zip(axs, themis_data.iterrows()):
    # Create a series of timestamps at a 1-hour cadence between the start and stop times
    date_range = pd.date_range(start=row['Date_Start'], end=row['Date_Stop']+pd.Timedelta(days=1)-pd.Timedelta(seconds=1), freq='1h')
    # Return all the values that correspond to these timestamps
    filtered_dst_values = DST_filtered.loc[DST_filtered['Date'].isin(date_range), 'DST']

    #For some reason, if there is no data then fill all 0
    if len(filtered_dst_values) == 0:
        filtered_dst_values = pd.Series([0] * len(date_range))

    # Plot the returned values
    ax.plot(date_range, filtered_dst_values)

    #Format the axis: set the limits, tick locators, and format for the labels on the x-axis
    ax.set_ylim((-150, 150))
    ax.yaxis.set_major_locator(MultipleLocator(50))
    ax.xaxis.set_major_locator(mdates.DayLocator(interval=2))
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))

plt.tight_layout()
plt.show()

样本数据

# 表格1数据
Date_Start,Date_Stop,Y_Start,Y_Stop,X_Max,DST
2011-11-26,2011-12-13,,,,
2012-12-23,2013-01-24,,,,
2014-02-26,2014-03-27,,,,
2015-05-01,2015-05-31,,,,
2016-06-25,2016-07-14,,,,
2017-08-20,2017-09-22,,,,
2018-09-26,2018-11-07,,,,
2019-11-05,2019-12-11,,,,
2020-12-10,2021-01-20,,,,
2022-01-11,2022-03-01,,,,
2023-03-01,2023-04-15,,,,

# 表格2数据
,DOY,DST,Date
8765,357,12.00,2012-12-22 23:00:00
8766,358,15.00,2012-12-23 00:00:00
8767,358,18.00,2012-12-23 01:00:00
8768,358,15.00,2012-12-23 02:00:00
8769,358,14.00,2012-12-23 03:00:00
8770,358,12.00,2012-12-23 04:00:00
8771,358,11.00,2012-12-23 05:00:00
8772,358,13.00,2012-12-23 06:00:00
8773,358,16.00,2012-12-23 07:00:00
8774,358,17.00,2012-12-23 08:00:00
8775,358,16.00,2012-12-23 09:00:00
8776,358,14.00,2012-12-23 10:00:00
8777,358,14.00,2012-12-23 11:00:00
8778,358,15.00,2012-12-23 12:00:00
8779,358,12.00,2012-12-23 13:00:00
8780,358,7.00,2012-12-23 14:00:00
8781,358,5.00,2012-12-23 15:00:00
8782,358,4.00,2012-12-23 16:00:00
8783,358,4.00,2012-12-23 17:00:00
8784,358,6.00,2012-12-23 18:00:00
8785,358,9.00,2012-12-23 19:00:00
8786,358,12.00,2012-12-23 20:00:00
8787,358,13.00,2012-12-23 21:00:00
8788,358,14.00,2012-12-23 22:00:00
8789,358,16.00,2012-12-23 23:00:00
8790,359,20.00,2012-12-24 00:00:00
8791,359,21.00,2012-12-24 01:00:00
8792,359,16.00,2012-12-24 02:00:00
8793,359,13.00,2012-12-24 03:00:00
8794,359,12.00,2012-12-24 04:00:00
8795,359,14.00,2012-12-24 05:00:00
8796,359,16.00,2012-12-24 06:00:00
8797,359,16.00,2012-12-24 07:00:00
8798,359,16.00,2012-12-24 08:00:00
8799,359,13.00,2012-12-24 09:00:00
8800,359,12.00,2012-12-24 10:00:00
8801,359,13.00,2012-12-24 11:00:00
8802,359,17.00,2012-12-24 12:00:00
8803,359,17.00,2012-12-24 13:00:00
8804,359,17.00,2012-12-24 14:00:00
8805,359,12.00,2012-12-24 15:00:00
8806,359,6.00,2012-12-24 16:00:00
8807,359,2.00,2012-12-24 17:00:00
8808,359,2.00,2012-12-24 18:00:00
8809,359,5.00,2012-12-24 19:00:00
8810,359,8.00,2012-12-24 20:00:00
8811,359,9.00,2012-12-24 21:00:00
8812,359,10.00,2012-12-24 22:00:00
8813,359,12.00,2012-12-24 23:00:00

原因分析

核心问题是数据与时间序列的索引不匹配:

  1. 使用isin()筛选数据时,返回的filtered_dst_values保留了原表格的整数索引,而date_range是时间类型索引,两者长度可能一致但索引无法对齐
  2. 无匹配数据时手动创建的全0Series是默认整数索引,同样与date_range的时间索引不对应
  3. Matplotlib绘图时,无法正确映射数据到坐标轴,导致Y轴刻度计算逻辑混乱,出现刻度值颠倒或异常

解决方案

通过将表格2的Date设为索引,再用reindex实现精准匹配,确保数据与时间序列的索引完全一致,同时自动填充缺失值为0:

修改后完整代码

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DayLocator, DateFormatter
from matplotlib.ticker import MultipleLocator

# 预先处理DST数据:将Date列转为datetime并设置为索引
DST_filtered['Date'] = pd.to_datetime(DST_filtered['Date'])
DST_filtered = DST_filtered.set_index('Date')['DST']

fig, axs = plt.subplots(len(themis_data), figsize=(10, 2*len(themis_data)))
for ax, (index, row) in zip(axs, themis_data.iterrows()):
    # 生成目标时间序列:起始日00:00到结束日23:00的小时级数据
    date_range = pd.date_range(start=row['Date_Start'], end=row['Date_Stop'], freq='1h')
    
    # 重新索引:自动匹配对应时间的数据,缺失值填充为0
    filtered_dst_values = DST_filtered.reindex(date_range, fill_value=0)

    # 绘图
    ax.plot(date_range, filtered_dst_values)

    # 设置坐标轴格式
    ax.set_ylim(-150, 150)
    ax.yaxis.set_major_locator(MultipleLocator(50))
    ax.xaxis.set_major_locator(DayLocator(interval=2))
    ax.xaxis.set_major_formatter(DateFormatter('%m-%d'))

plt.tight_layout()
plt.show()

验证说明

修改后测试2012-12-23,2012-12-24的日期范围,Y轴会正确显示-150、-100、-50、0、50、100、150的刻度,数据与坐标轴对应正常,无混乱或颠倒问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:45:55