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

基于DateTimeIndex轴,编写函数获取ax.axhline的xmin与xmax值

问题

现有一个索引为DateTimeIndex的DataFrame,已定位到当日14:00-15:00区间内局部最大值对应的时间idx与数值max_val。当前通过硬编码xmin、xmax调用ax.axhline绘制水平线段,无法灵活适配时间间隔调整(比如从15分钟改成20分钟)或最大值位置变化的场景。

需要编写一个函数,接收参数idx(最大值对应的DateTimeIndex)和dt(时间间隔,单位为分钟),返回适配DateTimeIndex型x轴的xmin与xmax值,让水平线段以idx为中心,覆盖前后dt/2分钟的范围。

附现有代码示例:

fig, ax = plt.subplots(figsize=(20, 4))
index = pd.date_range('7-20-2022', '7-21-2022', freq='min')
np.random.seed(0)
df = pd.DataFrame(np.cumsum(np.random.randn(len(index))), index=index)
df_limited = df.loc['7-20-2022'].between_time('14:00', '15:00')
idx  = df_limited.idxmax()
max_val = df_limited.loc[idx]
df.plot(ax=ax)
ax.axhline(max_val.values, color='r', xmin=0.57, xmax=0.6)
plt.show()

当前局部最大值时间为2022-07-20 14:06:00,对应数值-46.80,期望绘制13:51-14:21的水平线段。

解决方案

核心思路是将时间转换为matplotlib坐标轴的相对位置:先获取当前轴的x轴时间范围,再计算目标时间点在该范围内的占比,得到对应的xmin和xmax。

实现函数

import matplotlib.dates as mdates

def get_xmin_xmax(idx, dt):
    # 计算中心时间前后dt/2分钟的边界时间
    half_dt = pd.Timedelta(minutes=dt/2)
    start_time = idx - half_dt
    end_time = idx + half_dt
    
    # 获取当前绘图轴的x轴时间范围(转换为matplotlib数值格式)
    ax = plt.gca()
    xlim = ax.get_xlim()
    x_start = mdates.num2date(xlim[0])
    x_end_num = mdates.date2num(xlim[1])
    
    # 计算目标时间在x轴上的相对比例
    xmin = (mdates.date2num(start_time) - mdates.date2num(x_start)) / (x_end_num - mdates.date2num(x_start))
    xmax = (mdates.date2num(end_time) - mdates.date2num(x_start)) / (x_end_num - mdates.date2num(x_start))
    
    return xmin, xmax

完整使用示例

将原有代码中的硬编码xmin、xmax替换为函数返回值即可:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def get_xmin_xmax(idx, dt):
    half_dt = pd.Timedelta(minutes=dt/2)
    start_time = idx - half_dt
    end_time = idx + half_dt
    
    ax = plt.gca()
    xlim = ax.get_xlim()
    x_start = mdates.num2date(xlim[0])
    x_end_num = mdates.date2num(xlim[1])
    
    xmin = (mdates.date2num(start_time) - mdates.date2num(x_start)) / (x_end_num - mdates.date2num(x_start))
    xmax = (mdates.date2num(end_time) - mdates.date2num(x_start)) / (x_end_num - mdates.date2num(x_start))
    
    return xmin, xmax

# 生成示例数据
fig, ax = plt.subplots(figsize=(20, 4))
index = pd.date_range('7-20-2022', '7-21-2022', freq='min')
np.random.seed(0)
df = pd.DataFrame(np.cumsum(np.random.randn(len(index))), index=index)
df_limited = df.loc['7-20-2022'].between_time('14:00', '15:00')
idx  = df_limited.idxmax()
max_val = df_limited.loc[idx]

# 绘制曲线
df.plot(ax=ax)

# 调用函数获取xmin和xmax,绘制水平线段(dt=30对应前后15分钟,覆盖13:51-14:21)
xmin, xmax = get_xmin_xmax(idx, dt=30)
ax.axhline(max_val.values, color='r', xmin=xmin, xmax=xmax)

plt.show()

说明

  • 用pd.Timedelta计算时间边界,支持任意分钟数的时间间隔调整
  • 借助matplotlib.dates实现时间与坐标轴数值的转换,确保相对位置计算准确
  • 自动获取当前轴的x范围,无需手动配置,适配不同绘图场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:39:14