如何使用Python内插3D曲面图(2D数组)的缺失值(未定义区域)?

时间:2019-07-03 15:50:35

标签: python numpy scipy interpolation surface

在使用Numpy和matplotlib的Python 3.7中,我想为以下方程式绘制3D曲面:

f(x,y)=sin(x)sin(y)/(x*y)

此功能显然未定义,其中 x = 0 y = 0

要计算和绘制此图形,我有以下代码,当前正在Jupyter Notebook中运行:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib notebook

f = lambda x, y: np.sin(x)*np.sin(y)/(x*y)

xs, ys = np.mgrid[-np.pi:np.pi:31j, -np.pi:np.pi:31j]
zs = f(xs, ys)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(X=xs, Y=ys, Z=zs)

请注意图表,该图表缺少值: enter image description here

如何对缺失值进行插值,以使图形显得平滑?

2 个答案:

答案 0 :(得分:1)

Scipy具有可以执行此操作的插值模块。依靠以上内容(在问题发布中),此代码可以在下一个单元格中运行:

from scipy import interpolate

# integer arrays for indexing
x_indx, y_indx = np.meshgrid(np.arange(0, zs.shape[1]),
                             np.arange(0, zs.shape[0]))

# mask all invalid values
zs_masked = np.ma.masked_invalid(zs)

# retrieve the valid, non-Nan, defined values
valid_xs = x_indx[~zs_masked.mask]
valid_ys = y_indx[~zs_masked.mask]
valid_zs = zs_masked[~zs_masked.mask]

# generate interpolated array of z-values
zs_interp = interpolate.griddata((valid_xs, valid_ys), valid_zs.ravel(),
                                 (x_indx, y_indx), method='cubic')

# finally, plot the data 
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(X=xs, Y=ys, Z=zs_interp)

返回以下图形: enter image description here

请注意,此代码已针对可读性和可理解性(而非内存效率)进行了优化。重新优化此代码以提高内存效率是一项琐碎的任务,留给读者

答案 1 :(得分:1)

在这种情况下,您可以使用scipy.special.sinc。这将插入确切的结果sin(0)/0 = 1

import numpy as np
from scipy.special import sinc
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib notebook

f = lambda x, y: sinc(x)*sinc(y)

xs, ys = np.mgrid[-1:1:31j, -1:1:31j]
zs = f(xs, ys)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(X=xs*np.pi, Y=ys*np.pi, Z=zs)

enter image description here