numpy 使用matplotlib plot_surface绘制包含NaN值的矩阵

ogq8wdun  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(155)

我想绘制一个包含浮点数和NaN值组合的矩阵。这是一个3D图,其中X和Y是矩阵坐标,Z是矩阵中的值。
NaN值应该被忽略。如果matplot可以填充浮点值之间的曲面,那就太好了,但是如果它不这样做也没关系。
这是我迄今为止尝试的代码的改编。它应该绘制手动分配的3个数据点,但相反,它产生了一个空的3D图。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

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

X0=0
Xmax=10
Y0=0
Ymax=10

Xfill,Yfill=numpy.meshgrid(range(X0,Xmax),range(Y0,Ymax))

data_matrix=numpy.full(shape=[Xmax,Ymax],fill_value=numpy.nan)

data_matrix[5,5]=3
data_matrix[1,8]=6
data_matrix[7,2]=0.5

ax.plot_surface(Xfill,Yfill, data_matrix[X0:Xmax,Y0:Ymax],color='blue',rstride=1,cstride=1)

plt.show()

字符串

luaexgnf

luaexgnf1#

下面我展示了我所知道的两个选项;一个使用散点图,另一个绘制一个给定任意点集的表面。
x1c 0d1x的数据

import matplotlib.pyplot as plt
import numpy as np

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

X0 = 0
Xmax = 10
Y0 = 0
Ymax = 10

Xfill, Yfill = np.meshgrid(range(X0, Xmax), range(Y0, Ymax))

data_matrix = np.full(shape=[Xmax, Ymax], fill_value=np.nan)

data_matrix[5, 5] = 3
data_matrix[1, 8] = 6
data_matrix[7, 2] = 0.5

#Pull out the non-nan datapoints
x_valid = np.argwhere(~np.isnan(data_matrix))[:, 0]
y_valid = np.argwhere(~np.isnan(data_matrix))[:, 1]
data_valid = data_matrix[x_valid, y_valid]

#Scatter plot of individual points
ax.scatter(x_valid, y_valid, data_valid, c='tab:red',
           s=60, label='scatter', depthshade=False)

#Also works somewhat:
# ax.scatter(Xfill, Yfill, data_matrix)

#Overlay a surface plot that doesn't require a regular grid
ax.plot_trisurf(x_valid, y_valid, data_valid,
                cmap='jet', label='trisurf plot', alpha=0.7)

字符串
可选的进一步格式化:

# Some additional flourishes
ax.view_init(azim=20, elev=45, roll=0)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('data')

#Vertical lines from each point
from mpl_toolkits.mplot3d.art3d import Line3DCollection
lines_start = [(x, y, 0) for x, y in zip(x_valid, y_valid)]
lines_end = [(x, y, z) for x, y, z in zip(x_valid, y_valid, data_valid)]
lines = list(zip(lines_start, lines_end))

ax.add_collection(Line3DCollection(lines, linewidth=3,
                  color='tab:orange', label='vertical projection'))
plt.gcf().legend()

nwwlzxa7

nwwlzxa72#

溶液

Matplotlib不允许在输入数组中使用任何NaN值。为了解决这个问题,您必须隔离有效值(非NaN)并仅将这些数字作为参数传递。您可以使用np.argwhere(~np.isnan(data_matrix))查找所有非NaN值的索引。将索引应用于data_matrix数组,您将仅获得有效值。将有效值传递给绘图函数,您将解决了这个问题!
注意事项:矩阵必须包含至少3个有效值,否则将不绘制任何内容。此外,ax.plot_trisurf(...)最适合此示例,因为它填补了缺失值的空白。

代码

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

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

X0=0
Xmax=10
Y0=0
Ymax=10

Xfill,Yfill=np.meshgrid(range(X0,Xmax),range(Y0,Ymax))

data_matrix=np.full(shape=[Xmax,Ymax],fill_value=1,dtype=np.float32)

data_matrix[5,5]=4
data_matrix[2,6]=6
data_matrix[7,2]=4
data_matrix[4,8]=2
data_matrix[7,4]=np.nan
data_matrix[8,8]=np.nan
data_matrix[2,2]=np.nan
data_matrix[4,3]=np.nan

# This is the important part!
indices = np.argwhere(~np.isnan(data_matrix))

# Use plot_trisurf to create the surface
ax.plot_trisurf(indices[:,0],indices[:,1], data_matrix[indices[:,0],indices[:,1]],color='blue')
ax.set_xlim(X0-1,Xmax+1)
ax.set_ylim(Y0-1,Ymax+1)
ax.set_zlim(Y0-1,Ymax/2)

plt.show()

字符串

相关问题