Python 3D散点图平滑求助:trisurf三角化效果异常
Hey there! Let's work through this trisurf issue you're facing when trying to smooth your 3D scatter plot. I’ve dealt with similar wonky triangulation results before, so here are some practical fixes and alternatives to get that clean, Mathematica-style smooth surface you’re after.
Common Fixes for Trisurf Triangulation Issues
First, let’s troubleshoot why your trisurf output is looking off:
Fix 1: Interpolate to a Regular Grid First
Randomly scattered or sparse data points often cause weird triangulation. The solution here is to convert your irregular data into a regular grid using interpolation, which gives trisurf (or better yet,plot_surface) a cleaner structure to work with. Here’s how to do it withscipy.interpolate.griddata:import numpy as np from scipy.interpolate import griddata import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # Assume your raw data is stored in x, y, z arrays # Create a dense, regular grid xi = np.linspace(x.min(), x.max(), 150) yi = np.linspace(y.min(), y.max(), 150) xi, yi = np.meshgrid(xi, yi) # Interpolate z values onto the grid (use 'cubic' for smoothness) zi = griddata((x, y), z, (xi, yi), method='cubic') # Plot the smooth surface fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(xi, yi, zi, cmap='viridis', edgecolor='none') plt.show()This should give you a much smoother, more uniform surface compared to using raw scattered data with trisurf.
Fix 2: Manually Control Triangulation & Filter Bad Triangles
If you want to stick with trisurf, you can usescipy.spatial.Delaunayto generate the triangulation manually, then filter out tiny or distorted triangles that cause the weird artifacts:from scipy.spatial import Delaunay # Generate triangulation from raw points tri = Delaunay(np.column_stack((x, y))) # Calculate area of each triangle to filter outliers def calc_tri_area(simplex, x, y): pts = np.array([(x[s], y[s]) for s in simplex]) a = np.linalg.norm(pts[0] - pts[1]) b = np.linalg.norm(pts[1] - pts[2]) c = np.linalg.norm(pts[2] - pts[0]) s = (a + b + c) / 2 return np.sqrt(s * (s - a) * (s - b) * (s - c)) areas = [calc_tri_area(s, x, y) for s in tri.simplices] # Filter out the smallest 5% of triangles (adjust threshold as needed) valid_tris = tri.simplices[np.array(areas) > np.percentile(areas, 5)] # Plot with cleaned triangulation fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.trisurf(x, y, z, triangles=valid_tris, cmap='viridis', edgecolor='none') plt.show()
Alternative Methods for Smooth 3D Surfaces
If trisurf still isn’t giving you what you want, try these approaches that are better suited for smooth, Mathematica-like results:
Radial Basis Function (RBF) Interpolation
For non-uniform data, RBF interpolation creates incredibly smooth surfaces. Usescipy.interpolate.RBFInterpolator:from scipy.interpolate import RBFInterpolator points = np.column_stack((x, y)) # Use 'cubic' or 'quintic' kernel for smoothness interp = RBFInterpolator(points, z, kernel='cubic') # Interpolate onto regular grid xi_flat = xi.flatten() yi_flat = yi.flatten() zi_flat = interp(np.column_stack((xi_flat, yi_flat))) zi = zi_flat.reshape(xi.shape) ax.plot_surface(xi, yi, zi, cmap='viridis')Use Mayavi for Professional-Grade Rendering
If Matplotlib’s capabilities feel limited, Mayavi is a powerful tool for 3D visualization that produces ultra-smooth surfaces. Here’s a quick example:from mayavi import mlab # Interpolate to grid first (using griddata as before) mlab.surf(xi, yi, zi, colormap='viridis') mlab.show()
Give these methods a try—start with the regular grid interpolation, since that’s usually the quickest fix for wonky trisurf results. Let me know if you need to tweak any of the code for your specific dataset!
内容的提问来源于stack exchange,提问作者J.Agusti

