如何使用 Python 插入 3D 曲面图(2D 数组)的缺失值(未定义区域)?
How can I interpolate missing values (undefined areas) of a 3D surface plot (2D array) using Python?
在 Python 3.7 中使用 Numpy 和 matplotlib,我想为以下方程绘制 3D 表面:
此函数显然未定义,其中 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)
注意图表,它缺少值:
如何插入缺失值以使图形看起来平滑?
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)
返回下图:
请注意,此代码已针对可读性和可理解性而非内存效率进行了优化。 Re-Optimizing 此内存效率代码是留给 reader
的一项微不足道的任务
在这种特定情况下,您可以使用 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)
在 Python 3.7 中使用 Numpy 和 matplotlib,我想为以下方程绘制 3D 表面:
此函数显然未定义,其中 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)
注意图表,它缺少值:
如何插入缺失值以使图形看起来平滑?
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)
返回下图:
请注意,此代码已针对可读性和可理解性而非内存效率进行了优化。 Re-Optimizing 此内存效率代码是留给 reader
的一项微不足道的任务在这种特定情况下,您可以使用 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)