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

如何用自定义变换让matplotlib的fill_between填充曲线至无穷区域?

在Matplotlib中填充曲线至视图顶部(支持缩放/平移)

方法1:利用事件动态更新填充范围

这种方法简单直观,通过绑定轴的视图变化事件,在缩放或平移时自动更新填充的上限为当前轴的顶部:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)
ax.plot(x, y)

# 初始化填充,上限设为当前y轴最大值
fill = ax.fill_between(x, y, ax.get_ylim()[1], color='blue', alpha=0.3)

def update_fill(event):
    # 更新填充的上限为当前视图的y轴最大值
    current_ylim = ax.get_ylim()
    fill.set_ylim(top=current_ylim[1])
    fig.canvas.draw_idle()

# 绑定视图变化事件
ax.callbacks.connect('xlim_changed', update_fill)
ax.callbacks.connect('ylim_changed', update_fill)

plt.show()

方法2:使用混合坐标变换(无需事件)

如果不想依赖事件触发,可以利用Matplotlib的混合坐标变换,直接将曲线的y值(数据坐标)与轴顶部(轴坐标)绑定,创建始终贴合视图顶部的填充区域:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Polygon
import matplotlib.transforms as transforms

fig, ax = plt.subplots()
x = np.arange(0, 4 * np.pi, 0.01)
y = np.sin(x)
ax.plot(x, y)

# 将数据y转换为轴坐标(0-1范围,1对应轴顶部)
screen_points = ax.transData.transform(np.column_stack((x, y)))
ax_bbox = ax.get_window_extent()
y_ax = (screen_points[:, 1] - ax_bbox.y0) / ax_bbox.height

# 构建填充区域的顶点:曲线点 + 轴顶部两端点 + 闭合点
vertices = np.column_stack((x, y_ax))
vertices = np.vstack([
    vertices,
    [x[-1], 1],  # 曲线右端点对应的轴顶部位置
    [x[0], 1],   # 曲线左端点对应的轴顶部位置
    [x[0], y_ax[0]]  # 回到起点闭合
])

# 创建混合变换:x用数据坐标,y用轴坐标
blended_trans = transforms.blended_transform_factory(
    ax.transData,  # x轴使用数据坐标
    ax.transAxes   # y轴使用轴坐标
)

# 添加多边形到轴上
fill_poly = Polygon(vertices, color='blue', alpha=0.3, transform=blended_trans)
ax.add_patch(fill_poly)

plt.show()

说明

  • 方法1通过事件监听视图变化,实时调整填充范围,代码简洁易维护,适合大多数场景。
  • 方法2利用混合坐标系统直接绑定数据与轴坐标,不需要事件触发,缩放平移时自动适配视图,更优雅但需要坐标转换的步骤。

两种方法都解决了你之前代码中仅y>0时生效、填充范围固定的问题,满足缩放/平移时始终填充曲线上方区域的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:08:20