Is there any function similar to 'clabel' to use in 3D graphics (contourslice)?
2 views (last 30 days)
Show older comments
I generated a graph in the spatial domain.
The domain was created by bounding the x,y,z vectors and then using the 'meshgrid' function to create a mesh (X Y Z).
So, I applied a function that generated a temperature data for this mesh in space.
I can observe the isotherms with the 'contourslice' function but I cannot generate labels with the temperature values.
The 'clabel' function only works for a surface graph where the temperature is shown in a mesh (X Y).
How to do the same task performed by 'clabel' on the surface but using the 3D graph?
0 Comments
Answers (1)
Sven
on 5 Apr 2023
A 3D spatial domain generates a 3D isosurface (rather than a 2D isocontour).
Here is some code to generate/display such a surface in synthetic data.
[x,y,z] = meshgrid(-3:0.25:3);
% V is your temperature matrix
V = x.*exp(-x.^2 -y.^2 -z.^2);
% Define contour values, I'm choosing these arbitrarily
contVals = linspace(0.5,9,5) * 1E-4;
nConts = numel(contVals);
contCols = parula(nConts);
% Loop over each contour value and make an isosurface of a chosen color
% with some transparency so you can see them all
figure, hold on
for i = 1:numel(contVals)
contVal = contVals(i);
fv = isosurface(x,y,z,V,contVal);
patch(fv,'FaceColor',contCols(i,:),'FaceAlpha',0.2,'EdgeColor','none')
end
% Make the picture a bit nicer to look at
view(3), camlight, axis image, lighting gouraud
% Show the colorbar
colormap(contCols), colorbar, clim(contVals([1 end]))
3 Comments
Sven
on 7 Apr 2023
Edited: Sven
on 7 Apr 2023
There's no inbuilt function to do all of the things you wanted. The basic issue is that you have 3d data. There is no concept of a 2d "isocontour" for 3d data unless you, say, take just a single slice of your data. So how about this: if you just picked a single slice (say, the 10th slice of the matrix V):
V_slice = V(:,:,10);
Can you then do everything that you want using isocontour etc? Assuming you can pick the "best" slice based on some criteria, is that 2d solution satisfactory to you?
If not, and you really do want to use all of your 3d data, then perhaps you can measure the nearest distances between vertices on each of the isosurfaces? It's not guaranteed to be "minimal" but it will be quite close as long as the resolution of your image is sufficient.
[x,y,z] = meshgrid(-3:0.25:3);
% V is your temperature matrix
V = x.*exp(-x.^2 -y.^2 -z.^2);
% Define contour values, I'm choosing these arbitrarily
contVals = [0.5 9]*10e-4;
nConts = numel(contVals);
contCols = parula(nConts);
% Loop over each contour value and make an isosurface of a chosen color
% with some transparency so you can see them all
fvSet = cell(nConts,1);
figure, hold on
for i = 1:numel(contVals)
contVal = contVals(i);
fv = isosurface(x,y,z,V,contVal);
patch(fv,'FaceColor',contCols(i,:),'FaceAlpha',0.2,'EdgeColor','none')
fvSet{i} = fv;
end
axis image
% Make the picture a bit nicer to look at
view(3), camlight, axis image, lighting gouraud
% Show the colorbar
colormap(contCols), colorbar, clim(contVals([1 end]))
% Calculate the nearest vertices
v1 = fvSet{1}.vertices;
v2 = fvSet{2}.vertices;
[minDists,minInds] = pdist2(v1,v2,'euclidean','Smallest',1);
[minDist,minInd] = min(minDists);
% Show the nearest pair of vertices
ptPair = [v2(minInd,:); v1(minInds(minInd),:)];
plot3(ptPair(:,1),ptPair(:,2),ptPair(:,3),'-o')
title(sprintf("Nearest vertices are %0.4f units apart",minDist))
Otherwise, you'll need to familiarize yourself with some more detailed geometry interrogation tools like geom3d
See Also
Categories
Find more on Contour Plots in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!