reduce mesh quantity in isosurface plot

28 visualizaciones (últimos 30 días)
Saurav
Saurav el 21 de Sept. de 2025 a las 0:14
Comentada: Umar el 23 de Sept. de 2025 a las 0:11
Hello everybody,
I have used MATLAB's isosurface and patch to plot a function. Everything looks good. The only problem we have is high amount of mesh on using 'EdgeColor'. How can I reduce the amount of mesh so that the graphics becomes similar to the one shown in the attached png file? The PNG file is obtained with Mathematica using ConourPlot3D module.
The main matlab code is also attached. I need you suggestion and help.
-Saurav

Respuestas (2)

Star Strider
Star Strider el 21 de Sept. de 2025 a las 1:00
We have a problem ...
I used a script I wrote earlier to extract the text from your .m file to run here. I post all of it here.
Whatever 'pi3DB_psi' is needs to be supplied (or calculated), and it needs to be passed as an argument to the function. (The function contains one assignment that could probably be put in the calling code, avoiding the function.)
There appear to be a few other arguments missing as well.
imshow(imread('Screenshot 202...20 200051.png'))
% ----- isosurface_t2 -----
% © Saurav Parmar
% last modified: 20-09-2025
% Numeric calculation
clear
clc
syms x y z
% format short
Lx = 5; % length of box with side x
Ly = 5; % length of box with side y
Lz = 5; % length of box with side z
psi_sqr = pi3DB_psi_squared(x,y,z,Lx,Ly,Lz,2,2,2); % nx = 1 & ny = 2 & nz = 2
Unrecognized function or variable 'pi3DB_psi'.

Error in solution>pi3DB_psi_squared (line 40)
psi_sqr = conj(pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz)).*pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
fprintf('psi_sqr = %s.\n',psi_sqr)
% plot
[x,y,z] = meshgrid(0:0.10:5);
ht = matlabFunction(psi_sqr);
[faces_p, verts_p, colors_p] = isosurface(x,y,z,ht(x,y,z),0.01,x);
p = patch('Vertices',verts_p,'Faces',faces_p,'FaceVertexCData',colors_p,'FaceColor',[0.9290 0.6940 0.1250],'EdgeColor','k');
view(3)
% it is better without effect of lightning
xlabel('x-axis','FontSize',12)
ylabel('y-axis','FontSize',12)
zlabel('z-axis','FontSize',12)
disp('the solution is represented as a plot')
function psi_sqr = pi3DB_psi_squared(x,y,z,Lx,Ly,Lz,nx,ny,nz)
psi_sqr = conj(pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz)).*pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz);
end
% ---------------------- END ----------------------
.
  3 comentarios
Saurav
Saurav el 21 de Sept. de 2025 a las 1:41
the full code is attached.
Star Strider
Star Strider el 21 de Sept. de 2025 a las 2:13
The mesh density is controlled by the increment argument in your meshgrid call. I increased that from 0.10 to 0.25 here. Change it appropriately. The isosurface function produces triangulated meshes by default, not square meshes. I am not aware of a way to convert it to square meshes.
I added an axis('equal') call as well.
Your Slightly Tweaked Code --
% © Saurav Parmar
% last modified: 20-09-2025
% Numeric calculation
clear
clc
syms x y z
% format short
Lx = 5; % length of box with side x
Ly = 5; % length of box with side y
Lz = 5; % length of box with side z
psi_sqr = pi3DB_psi_squared(x,y,z,Lx,Ly,Lz,2,2,2); % nx = 1 & ny = 2 & nz = 2
fprintf('psi_sqr = %s.\n',psi_sqr)
psi_sqr = (8*sin((2*pi*conj(z))/5)*sin((2*x*pi)/5)*sin((2*y*pi)/5)*sin((2*z*pi)/5)*sin((2*pi*conj(x))/5)*sin((2*pi*conj(y))/5))/125.
% plot
[x,y,z] = meshgrid(0:0.25:5); ` % <- TWEAKED
ht = matlabFunction(psi_sqr);
[faces_p, verts_p, colors_p] = isosurface(x,y,z,ht(x,y,z),0.01,x);
p = patch('Vertices',verts_p,'Faces',faces_p,'FaceVertexCData',colors_p,'FaceColor',[0.9290 0.6940 0.1250],'EdgeColor','k');
view(3)
% it is better without effect of lightning
xlabel('x-axis','FontSize',12)
ylabel('y-axis','FontSize',12)
zlabel('z-axis','FontSize',12)
axis('equal') % <- ADDED
disp('the solution is represented as a plot')
the solution is represented as a plot
% function1
function psi = pi1DB_psi(x,a,n)
psi = (2/a)^0.5*(sin(pi.*n.*x./a));
end
% function2
function psi = pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz)
psi = pi1DB_psi(x,Lx,nx).*pi1DB_psi(y,Ly,ny).*pi1DB_psi(z,Lz,nz);
end
% function3
function psi_sqr = pi3DB_psi_squared(x,y,z,Lx,Ly,Lz,nx,ny,nz)
psi_sqr = conj(pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz)).*pi3DB_psi(x,y,z,Lx,Ly,Lz,nx,ny,nz);
end
.

Iniciar sesión para comentar.


Umar
Umar el 22 de Sept. de 2025 a las 5:47

Hi @Saurav and @Star Strider,

I've read through the thread and appreciate both the original question and the thoughtful response.

Saurav — thanks for following up with the full code. It’s great to see that the function definitions are now included and the visualization works as expected.

Star Strider — your insights on mesh density and `axis equal` were spot on. I’ve taken the liberty to incorporate those suggestions directly into Saurav’s corrected script, and included a few optional tweaks (e.g., lighting and transparency) that might help match the clean aesthetic seen in Mathematica’s `ContourPlot3D`.

Here’s a refined version:

% © Saurav Parmar
% Cleaned-up and enhanced version based on community feedback
clear; clc;
syms x y z
% Box dimensions
Lx = 5; Ly = 5; Lz = 5;
% Define the symbolic squared wavefunction
psi_sqr = pi3DB_psi_squared(x, y, z, Lx, Ly, Lz, 2, 2, 2);
% Create coarser mesh grid (reduces clutter)
[x, y, z] = meshgrid(0:0.25:5);
ht = matlabFunction(psi_sqr);
% Generate isosurface
[faces_p, verts_p, colors_p] = isosurface(x, y, z, ht(x, y, z), 0.01, x);
p = patch('Vertices', verts_p, 'Faces', faces_p, ...
        'FaceVertexCData', colors_p, ...
        'FaceColor', [0.9290 0.6940 0.1250], ...
        'EdgeColor', 'none');   % Optional: hide mesh lines for cleaner plot
% View settings
view(3)
axis equal
xlabel('x-axis'); ylabel('y-axis'); zlabel('z-axis');
% Optional aesthetic enhancements
camlight; lighting gouraud
material shiny
alpha(0.8)   % Optional: transparency
% Display
disp('The 3D isosurface plot is generated.')
% Function definitions
function psi = pi1DB_psi(x, a, n)
  psi = sqrt(2/a) * sin(pi * n * x / a);
end
function psi = pi3DB_psi(x, y, z, Lx, Ly, Lz, nx, ny, nz)
  psi = pi1DB_psi(x, Lx, nx) .* ...
        pi1DB_psi(y, Ly, ny) .* ...
        pi1DB_psi(z, Lz, nz);
end
function psi_sqr = pi3DB_psi_squared(x, y, z, Lx, Ly, Lz, nx, ny, nz)
  psi_val = pi3DB_psi(x, y, z, Lx, Ly, Lz, nx, ny, nz);
  psi_sqr = conj(psi_val) .* psi_val;
end

Please see attached.

This version builds directly on both of your contributions. If the goal is to match Mathematica’s clean rendering, setting `'EdgeColor','none'` and playing with lighting helps significantly. Alternatively, for educational purposes, keeping edges visible but sparse (via a coarser grid) works well too.

Hope this helps.

  3 comentarios
Umar
Umar el 22 de Sept. de 2025 a las 23:44

Hi @Saurav,

I took a look at your thread and the specific challenge you're facing with volume data visualization. Your instinct to stick with isosurface rather than fimplicit3 is absolutely correct – you can't feed volume arrays into fimplicit3, so you're on the right track.

The issue you're running into is actually quite common in our field. Most people think the grid lines are some special feature, but they're just the triangle edges from the isosurface mesh. Once you realize that, controlling them becomes straightforward.

So what is really happening that when you call isosurface(X, Y, Z, V, isovalue, X), MATLAB creates a triangulated surface. Those "contour lines" you want are simply the edges of those triangles. The density of lines depends entirely on how fine your X, Y, Z grids are. I've put together a comprehensive script that demonstrates this principle with your exact use case. The key insight is in the meshgrid resolution:

% Fewer grid lines (coarser mesh)
[X, Y, Z] = meshgrid(0:0.25:5, 0:0.25:5, 0:0.25:5);
% More grid lines (finer mesh)  
[X, Y, Z] = meshgrid(0:0.15:5, 0:0.15:5, 0:0.15:5);

Results from Testing I ran the script with both analytical functions (like your wavefunction) and synthetic volume data. The output shows exactly what you're after:

For your wavefunction case: The analytical function produces those nice spherical lobes with clean grid lines that look very similar to your Mathematica reference. The mesh resolution of 0.20 gives a good balance - not too cluttered, not too sparse.

For volume data: This is where it gets interesting. The script generates synthetic 3D Gaussian data (you'd replace this with your actual volume data V) and produces a clean spherical isosurface with visible grid lines. The approach works identically to your analytical case.

Grid density comparison: I included a side-by-side comparison showing coarse (0.35), medium (0.20), and fine (0.12) mesh spacing. You can see how dramatically this affects the grid line density.

For your specific volume data, you'd simply replace the synthetic data generation with:

% Your actual volume data
V = your_density_data;  % however you load/generate this
[X, Y, Z] = your_coordinate_grids;  % matching your data dimensions
% Then the same isosurface call you mentioned
[faces_vol, verts_vol, colors_vol] = isosurface(X, Y, Z, V,   isovalue_vol, X);
% The key is making the edges visible
patch('Vertices', verts_vol, 'Faces', faces_vol, ...
    'FaceVertexCData', colors_vol, ...
    'EdgeColor', 'black', ...        % This makes grid lines visible
    'LineWidth', 0.5);               % Adjust thickness to taste

Here are few practical notes that I would like to share with you: The script includes automatic isovalue selection because that's usually where people get tripped up. It examines your data range and picks reasonable values (typically 10-30% of the maximum). This prevents the common "no isosurface found" errors.

For publication work, I'd suggest: * Use mesh spacing around 0.15-0.20 for good grid visibility without overcrowding * Set LineWidth between 0.4-0.6 depending on your journal's figure requirements * Consider EdgeColor as dark gray [0.2 0.2 0.2] rather than pure black for a softer look

The lighting setup (camlight, material properties) makes a significant difference in the final appearance. I've included professional lighting that should work well for most scientific publications.

Now, you would ask why this beats other approaches, unlike fimplicit3 or other plotting functions, isosurface gives you direct control over the triangulation. This matters for volume data because you're dealing with discrete measurements rather than smooth analytical functions. The triangulation respects your data structure while still producing clean, publication-ready visualizations.

The grid lines aren't just decorative – they actually show you the surface topology, which can be scientifically meaningful depending on what your volume data represents.

Your original approach was sound. The script I've provided should handle both your analytical wavefunctions and your volume data with the same grid line control. The key parameters are mesh resolution (for grid density) and the EdgeColor/LineWidth properties (for appearance). Let me know how this works with your actual data. Sometimes real-world datasets have quirks that require minor adjustments to the isovalue selection or mesh resolution.

P.S. - The approach scales well to large datasets, which is often a concern with experimental volume data. The automatic parameter selection should handle most cases, but you can always override the isovalue calculation if you need specific values for your analysis.

Umar
Umar el 23 de Sept. de 2025 a las 0:11

Iniciar sesión para comentar.

Categorías

Más información sobre Surface and Mesh Plots en Help Center y File Exchange.

Productos


Versión

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by