How to make color plots in 3D?

177 views (last 30 days)
Jamie Al
Jamie Al on 12 Oct 2022
Commented: Walter Roberson on 15 Oct 2022
I am using isosurface to create 3D plots, but the colors aren't what I want. I have two examples with 2D plots with nice colormap and 3D plots using isosurface. I would like to reprduce the colors from 2D plot to my 3D plot if that's possible:
2D plot:
Nx = 256;
Ny = 256;
Lx = 128;
Ly = 128;
%coord mapping
xi = (0:Nx-1)/Nx*2*pi;
xi_x = 2*pi/Lx;
x = xi/xi_x;
yi = (0:Ny-1)/Ny*2*pi;
yi_y = 2*pi/Ly;
y = yi/yi_y;
A = 2*pi / Lx;
B = 2*pi / Ly;
x0 = 64;
y0 = 64;
rx0 = 20;
ry0 = 20;
p = 3;
b = 0.015;
c = 12;
d = 1;
a = 4;
[X2,Y2] = meshgrid(x,y);
theta2 = atan2(Y2 -y0, X2-x0) - (pi/c);
p02 = ((X2-x0) .* (X2-x0)) /(rx0 * rx0) + ((Y2-y0) .* (Y2-y0))/(ry0 * ry0);
n2 =d + a * exp((-1. * p02 .* (1 - b * cos(c * theta2))).^p) ;
%plot
figure
pcolor(X2,Y2,n2); colorbar; colormap('inferno'); shading flat; axis tight;
grid on;
The same example for 3D:
Nx = 256;
Ny = 256;
Nz = 256;
Lx = 128;
Ly = 128;
Lz = 128;
%coord mapping
xi = (0:Nx-1)/Nx*2*pi;
xi_x = 2*pi/Lx;
x = xi/xi_x;
yi = (0:Ny-1)/Ny*2*pi;
yi_y = 2*pi/Ly;
y = yi/yi_y;
zi = (0:Nz-1)/Nz*2*pi;
zi_z = 2*pi/Lz;
z = zi/zi_z;
A = 2*pi / Lx;
B = 2*pi / Ly;
x0 = 64;
y0 = 64;
z0 = 64;
rx0 = 20;
ry0 = 20;
rz0 = 20;
p = 3;
b = 0.015;
c = 12;
d = 1;
a = 4;
[X,Y,Z] = meshgrid(x,y,z);
theta = atan2(Y -y0, X-x0) - (pi/c);
p0 = ((X-x0) .* (X-x0)) /(rx0 * rx0) + ((Y-y0) .* (Y-y0))/(ry0 * ry0) + ((Z-z0) .* (Z-z0))/(rz0 * rz0);
n =d + a * exp((-1. * p0 .* (1 - b * cos(c * theta))).^p) ;
%plotting
figure
isosurface(X,Y,Z,n);
colorbar;
shading flat;
grid on;
xlabel('x'); ylabel('y'); zlabel('z');
  3 Comments
Adam Danz
Adam Danz on 12 Oct 2022
  1. For starters, you'll need to set the same custom colormap - colormap('inferno') (pretty neat, by the way).
  2. See this example in the isosurface documentation that shows how to control surface color by using patch along with the isosurface outputs. https://www.mathworks.com/help/matlab/ref/isosurface.html#mw_0340c7e3-87a1-489e-99ec-454313c25169
  3. Investigate the n variable to make sure it's doing what you want it to do.
See also the clim function which may be helpful to scale the colors.
Jamie Al
Jamie Al on 15 Oct 2022
Thanks! This colormap 'inferno' is from someone else who converted from Python and it's very useful. I can make 2D slices and use this colormap, but I was thinking maybe 3D countor plots are better here.

Sign in to comment.

Answers (1)

Walter Roberson
Walter Roberson on 12 Oct 2022
If you
help isosurface
then currently Example 1 shows taking the output of isosurface() and passing it to patch() and then modifying the patch properties such as setting the face color.
Example 1:
[x y z v] = flow;
p = patch(isosurface(x, y, z, v, -3));
isonormals(x,y,z,v, p)
p.FaceColor = 'red';
p.EdgeColor = 'none';
daspect([1 1 1])
view(3)
camlight; lighting phong
  2 Comments
Jamie Al
Jamie Al on 15 Oct 2022
Thanks, but I was wondering if I can do something like 3D contour plots using MATLAB. I can take 2D slices and use the MATLAB contoru function like:
for i = 140
figure(22)
contour3(X(:,:,i), Y(:,:,i), n(:,:,i));
end
But is there a way to make 3D contour plots in MATLAB similar to these?
Walter Roberson
Walter Roberson on 15 Oct 2022
Loop isosurface() calls, each with a different iso level. For example,
N = 10; %number of surfaces
cmap = parula(N);
[minn, maxn] = bounds(n, 'all');
L = linspace(minn, maxn, N);
for K = 1 : N
p = patch(isosurface(X, Y, n, L(K)));
p.FaceColor = cmap(K,:);
p.EdgeColor = 'none';
p.FaceAlpha = 0.6;
end
view(3)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!