我有一个x,y,z坐标数据集,应该代表一个表面。数据源自3D有限元网格。我现在想使用matplotlib绘制该表面。使用下面的代码,我能够成功绘制多个表面。但是,与添加的数据集相对应的曲面无法产生令人满意的结果,如您在此图像上所见:
使用单独的数据集绘制Y轴上的曲面和未正确绘制的曲面。
@staticmethod
def plot_vector(*args, surfaces=[], **kwargs):
'''
*args = vectors that have to be plotted
**surfaces = tuple of all surfaces that have to be plotted
**vector_surface = surface on which the vectors have to be plotted,
the vector_surface should also be included in the surfaces tuple
**intersect = np.ndarray containing intersection points between the weld and plate
The vectors will not be plotted on the centerpoint but along the edge of the weld
Either vector_surface or intersect have to be entered,
kwarg intersect has priority over kwarg vector_surface
**colors = tuple containting colors for the quivers. len(colors) should be equal to
the number of vector arguments given
**vector_length = array_like of shape (3,) or a scalar value which allowing scaling
of vector lengths
**trisurf if trisurf kwarg = true then a trisurf plot instead of a scatter plot is made
'''
# Create figure and axes objects
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Check if atleast one of the manadatory kwargs is entered
b = ['vector_surface', 'intersect']
a = kwargs.keys()
check = lambda a, b: any(i in b for i in a)
if check is False:
raise ValueError(''Expected either a vector_surface or intersect arg'')
# Get the max and min number along each axis for each surface
# Used to determine vector length and axis limits
max_x = max([np.amax(surf[:, 0]) for surf in surfaces])
max_y = max([np.amax(surf[:, 1]) for surf in surfaces])
max_z = max([np.amax(surf[:, 2]) for surf in surfaces])
min_x = min([np.amin(surf[:, 0]) for surf in surfaces])
min_y = min([np.amin(surf[:, 1]) for surf in surfaces])
min_z = min([np.amin(surf[:, 2]) for surf in surfaces])
#Iterate over all surfaces entered through surfaces kwarg
for i, surf in enumerate(surfaces):
x_val = surf[:, 0]
y_val = surf[:, 1]
z_val = surf[:, 2]
if 'plot_trisurf' in kwargs and True == kwargs['plot_trisurf']:
triang = mtri.Triangulation(x_val, y_val)
ax.plot_trisurf(triang, z_val, cmap='jet', alpha=0.5)
else: ax.scatter(x_val, y_val, z_val, c='b', alpha=0.2)
# Plot the vectors (quivers)
for i, arg in enumerate(args): # args = vectors that have to be plotted
for j, vectors in enumerate(arg):
if 'intersect' in kwargs:
X, Y, Z = intersect[j]
elif 'vector_surface' in kwargs:
if np.array_equal(surf, kwargs['vector_surface']):
# Calculate the center point of the surface
center_point = (x_val.sum(axis=0)/x_val.shape[0],
y_val.sum(axis=0)/y_val.shape[0],
z_val.sum(axis=0) /z_val.shape[0])
# Vector start point
X, Y, Z = center_point
# Vector length is standard = 5
if 'vector_length' in kwargs:
vector_length = kwargs['vector_length']
if isinstance(vector_length, (int, float)):
U, V, W = vectors * vector_length
elif isinstance(vector_length, (list, tuple, np.ndarray)) and i <= len(vector_length):
U, V, W = vectors * vector_length[i]
else:
U, V, W = vectors*5
#If the kwarg colors if given, apply the right color
if 'colors'in kwargs:
c = kwargs['colors'][i]
else: c = 'r'
# Add the vector to the axes objec
ax.quiver(X, Y, Z, U, V, W, color=c)
# Labels, limits, show plot
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
ax.set_xlim(max_x, min_x)
ax.set_ylim(max_y, min_y)
ax.set_zlim(max_z, min_z)
plt.show()
使用散点图绘制时,图看起来像这样:
因此,基本上我的问题是,为什么三角剖分对一个表面有效,而对另一个看似不太复杂的表面却不起作用,又怎么解决呢?
谢谢。