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
原因分析
核心问题是数据与时间序列的索引不匹配:
- 使用
isin()筛选数据时,返回的filtered_dst_values保留了原表格的整数索引,而date_range是时间类型索引,两者长度可能一致但索引无法对齐 - 无匹配数据时手动创建的全0Series是默认整数索引,同样与
date_range的时间索引不对应 - 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
相关产品推荐
相关产品推荐

