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

如何在Y轴范围受限的时间线上居中叠加保留原始值的折线子图

时间线叠加销量折线图适配方案

实现逻辑

用Matplotlib双Y轴方案即可实现需求,无需大幅修改原有时间线绘制逻辑:

  • 第一个Y轴专门绘制事件时间线,固定Y轴范围为[-6,6],从根源避免事件标注被挤压变形
  • 新建共享X轴的第二个Y轴用于绘制销量折线,将销量原始值线性缩放到[-5,5]区间内,适配时间线的垂直展示范围
  • 第二个Y轴的刻度直接映射为原始销量数值,用户看到的就是真实销量,无需手动换算

修改后完整代码

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


def GenerateTimeLine2(data, data02, title="Timeline", xaxis_format="%d %b", day_interval=5, figsize=(8, 5)):
    levels = np.array([-5, 5, -3, 3, -1, 1])
    fig, ax1 = plt.subplots(figsize=figsize)
    # 绘制基准时间线
    start = min(data.index)
    stop = max(data.index)
    ax1.plot((start, stop), (0, 0), 'k', alpha=.5)
    # 遍历标注所有事件
    for ii, (idate, iname) in enumerate(data.itertuples()):
        level = levels[ii % 6]
        vert = 'top' if level < 0 else 'bottom'

        ax1.scatter(idate, 0, s=100, facecolor='w', edgecolor='k', zorder=9999)
        ax1.plot((idate, idate), (0, level), c='r', alpha=.7)
        ax1.text(idate, level, iname, ha='right', va=vert, fontsize=14,
                backgroundcolor=(1., 1., 1., .3))
        
    ax1.set(title=title)
    # X轴日期格式设置
    ax1.get_xaxis().set_major_locator(mdates.DayLocator(interval=day_interval))
    ax1.get_xaxis().set_major_formatter(mdates.DateFormatter(xaxis_format))
    fig.autofmt_xdate()
    # 固定左侧Y轴范围,保证时间线布局不会变化
    ax1.set_ylim(-6, 6)
    # 隐藏左侧Y轴刻度和所有边框保持简洁
    plt.setp((ax1.get_yticklabels() + list(ax1.spines.values())), visible=False)

    # 新建右侧Y轴显示销量原始值
    ax2 = ax1.twinx()
    sales_min = data02.iloc[:,0].min()
    sales_max = data02.iloc[:,0].max()
    # 将销量值映射到时间线的Y轴区间[-5,5]内绘制
    norm_sales = 10 * (data02.iloc[:,0] - sales_min) / (sales_max - sales_min) - 5
    ax2.plot(data02.index, norm_sales)
    # 右侧Y轴刻度映射为原始销量值
    ax2.set_ylim(-5,5)
    ax2.set_yticks(np.linspace(-5,5,5))
    ax2.set_yticklabels(np.linspace(sales_min, sales_max,5).astype(int))
    ax2.set_ylabel('销量')
    ax2.yaxis.set_label_position("right")
    # 隐藏右侧Y轴边框
    ax2.spines[['top','bottom','left','right']].set_visible(False)
    
    return ax1, ax2

# 数据读取
data = pd.read_csv(r'testdata01.txt', parse_dates=True, index_col=0)
data02 = pd.read_csv(r'rap_a.txt', parse_dates=True, index_col=0)
ax1, ax2 = GenerateTimeLine2(data,data02,title='事件时间线',
                       day_interval=1,figsize=(8,5))
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:18:04