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

含NaN值的网格插值绘图出现断裂,寻求数据平滑方法

问题:等值线图纬度78-80区间数据断裂,寻求数据平滑方案

从大型数据集中生成透视表,提取y(压力)、x(纬度)、z(AOU值)构建网格后执行插值,但绘制的等值线图在纬度78-80附近出现数据断裂点,推测行方向插值未正确执行,需要有效的数据平滑方法。

原始代码

import numpy as np
import matplotlib.pyplot as plt

aou_df = df_1994.pivot_table(index='CTDPRS', columns = 'LATITUDE', values='AOU')
aou_df = aou_df.interpolate(method='linear', limit_area='inside', axis =0 )

##Plotting AOU 1994
y = [4.2, 4.7, 4.8, 4.9, 5.4, 9.1, 9.6, 9.7, 10.0, 10.1,
     ...
     3568.2, 3608.6, 3818.6, 3824.9, 3866.7, 3979.1, 4013.4, 4133.1,
     4159.3, 4287.3]

x = [72.13, 73.0, 73.49, 73.98, 74.5, 75.0, 75.45, 75.75, 75.94,
     76.62, 77.33, 77.78, 78.14, 78.15, 78.98, 79.98, 80.15, 80.16,
     80.33, 80.71, 81.24, 81.58, 82.47, 83.17, 84.06, 84.85, 85.89,
     87.16, 88.06, 88.79, 88.86, 88.95, 89.02, 90.0]

z = [[-12.29372749, np.nan, np.nan, ..., np.nan, np.nan, np.nan],
     [np.nan, np.nan, -43.41465869, ..., np.nan, np.nan, np.nan],
     [np.nan, -54.49999783, np.nan, ..., np.nan, np.nan, np.nan],
     ...,
     [np.nan, np.nan, np.nan, ..., np.nan, np.nan, np.nan],
     [np.nan, np.nan, np.nan, ..., np.nan, 55.87256821, np.nan],
     [np.nan, np.nan, np.nan, ..., 55.39665852, np.nan, 55.05005376]]

xi, yi = np.meshgrid(x,y,indexing='ij')

plt.figure(figsize=(25,10))
levels = np.linspace(-135,135)

plt.contourf(xi,yi,z, cmap = 'jet', levels=levels,vmin=-135, vmax=135)
plt.gca().invert_yaxis()
plt.gca().invert_xaxis()
cbar = plt.colorbar(ticks=(-135,-110,-85,-60,-35,0,35,60,85,110,135), extend= 'both')
cbar.set_label('AOU', fontsize=18)
cbar.ax.tick_params(labelsize=18)
plt.xlabel('LAT',fontsize=18)
plt.ylabel('Pressure (dbar)' ,fontsize=18)
plt.ylim(bottom = 1000)
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
plt.plot(x,range(len(x)),'gD', clip_on=False, markersize=10)

问题可视化

等值线图

解决方案

1. 修正插值顺序:先纬度方向再压力方向

当前仅对压力轴(axis=0)插值,但纬度轴(axis=1)的稀疏缺失值是断裂核心。调整插值顺序,先填充纬度方向的缺失:

aou_df = df_1994.pivot_table(index='CTDPRS', columns='LATITUDE', values='AOU')
# 先对纬度列方向插值,限制在数据有效范围内
aou_df = aou_df.interpolate(method='linear', limit_area='inside', axis=1)
# 再对压力行方向插值
aou_df = aou_df.interpolate(method='linear', limit_area='inside', axis=0)
# 提取z值
z = aou_df.values

2. 用径向基函数(RBF)做全局插值

线性插值对稀疏数据效果有限,RBF适合海洋这类不规则采样数据,能更好地拟合空间分布:

from scipy.interpolate import Rbf

# 提取所有非NaN的原始采样点
mask = ~np.isnan(z)
x_points = np.tile(x, len(y))[mask.flatten()]
y_points = np.repeat(y, len(x))[mask.flatten()]
z_points = z[mask]

# 创建RBF插值模型,multiquadric适合平滑曲面
rbf = Rbf(x_points, y_points, z_points, function='multiquadric')
# 在现有网格上生成插值结果
z_interp = rbf(xi, yi)

# 替换原z值绘图即可
plt.contourf(xi, yi, z_interp, cmap='jet', levels=levels, vmin=-135, vmax=135)

3. 生成密集网格+三次插值

78-80纬度区间采样点稀疏,生成更密集的纬度网格后用三次插值填充:

from scipy.interpolate import griddata

# 生成密集纬度网格(72到90,步长0.1)
xi_dense = np.linspace(72, 90, 181)
yi_dense = y
xi_grid, yi_grid = np.meshgrid(xi_dense, yi_dense, indexing='ij')

# 整理原始采样点
points = []
values = []
for i in range(len(x)):
    for j in range(len(y)):
        if not np.isnan(z[j][i]):
            points.append((x[i], y[j]))
            values.append(z[j][i])

# 三次插值填充密集网格
z_dense = griddata(points, values, (xi_grid, yi_grid), method='cubic')

# 用密集网格绘图
plt.contourf(xi_grid, yi_grid, z_dense, cmap='jet', levels=levels, vmin=-135, vmax=135)

4. 后处理高斯平滑

如果插值后仍有局部断裂,用高斯滤波做后处理平滑:

from scipy.ndimage import gaussian_filter

# sigma控制平滑强度,1.5左右兼顾平滑和细节
z_smoothed = gaussian_filter(z_interp, sigma=1.5)

plt.contourf(xi, yi, z_smoothed, cmap='jet', levels=levels, vmin=-135, vmax=135)

内容的提问来源于stack exchange,提问作者Maria Cristina Alvarez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:12:03