Generate 3D plots using 3D variables (Lat,lon,depth,Salinity)

Hey!
I've converted 4D-double variables from netCDF files and have these variables (i.e., temperature/salinity) in a three-dimensional double format (lon x lat x depth), I used [x y z ] = meshgrid(lon,lat,depth) in order to make each variable the same size. Each variable is a double, and looking at the forums and mathworks, I should be able to generate 3D plots (i.e., surfc/contour3). However, when I attempt to use these plot formats, I get errors such as X,Y,Z vectors must be the same length (which they are after using meshgrid?), or 'values must be scalar, vector or an array of numeric type' but again, after using TF = isnumeric(variable), each parameter used gets ans (1).
I've tried using the lon, lat and depth variables as they come (not meshgridded), but then I get errors with matrix dimensions must agree.
Does anyone know how to resolve these issues?

 Accepted Answer

surfc and contour3 do not accept 3D variables as inputs. See here:
and here
Lat and Lon can be a vector or 2D matrix, and depth must be a 2D matrix.

7 Comments

Here's an example using an example in a different Answer.
Note that Lat and Lon are already vectors, and depth is a 2D matrix.
So I can use them as is - no meshgrid needed. Just note that rows of a matrix correspond to Y, and columns to X.
load bathymatryGOF.mat
contour3(lat_range,lon_range,depth_range);
xlabel('Longitude')
ylabel('Latitude')
zlabel('Depth')
Thank you! This is similar to what I'm trying to achieve. Only issue I have is the depth values I have are in a 31x1 single format as the values range from 2m to 2000m (not in a scaled order either), what would you suggest for arranging the lat/lon values for depth with this? I'm currently writing a for loop to extract variable data (i.e., salinity), based on depth so that I can overlay it onto surf/contour figures.
Could I not just set zlims for the depth range given but combine the latitude/longitude values to generate this figure?
You many need to use reshape to organize your data into a 2D matrix, though with 31 values, I'm not sure that works. You may need to share your variables to be able to say for certain. Consider saving your lat, lon, depth, and salinity variables to a mat file and attach them to your post using the papercip icon. Consider sharing the code you are using to plot as well.
I've attached the files and script. For now I've % out the for loop as it was overriding the salinity values and re-inputting the values as 1x1 cells, the (i) is something I'm working on as an alternative.
I have removed the timestamp from the salinity value also.
Plot wise, I'm trying to get the values to extract first then will write a full script, but with values I currently have I get issues of matrix dimensions must agree, values must be scalar, vectors or array of numeric types, etc.
Apologies, I've made more work with the plot after using z = meshgrid(Lon,Lat) for depth (& applying zlim([ min max]), I have this so far, using the script below.
Edit so that we can see the code
% load, loop, plot variables %
% aim is to use for loop to extract each layer of data relative to depth to
% be used in pcolors, surf and contour3 plots %
% load data %
Salt2122 = 'bs-cmcc-sal-int-m_1661254972103.nc';
ncdisp(Salt2122)
% variables %
lon = ncread(Salt2122,'lon');
lat = ncread(Salt2122,'lat');
depth = ncread(Salt2122,'depth');
time = ncread(Salt2122,'time');
Lon = double(lon); % convert variables to a double matrix
Lat = double(lat);
Depth = double(depth);
z = meshgrid(Lon,Lat); % z = depth
% for loop to load in depth, and remove timestamp to create 3D double
% (size(lon x lat x depth)
for i = 1:length(depth) % for loop aimed to extract salinity data relative to depth
Salinity = ncread(Salt2122,'so');
Salinity = Salinity(:,:,:,13); % remove timestamp
Salinity = squeeze(Salinity);
%Salt(i) = cell2mat(Salinity) % convert 1x1 cell to mat (cell loads 31 times but size remains 1x1)
end
% save Longitude.mat Latitude.mat Depth_z.mat %Salt.mat
save Lon.mat Lat.mat Depth.mat Salt.mat
%% plots / % need to overlay salinity
contour3(Lon,Lat,z)
hold on
% contour3(Salinity)
% Error using contour3 (line 42)
%Input arguments must have at most 2 dimensions.
% Error in Extract_Salinity (line 27)
% contour3(Salinity)
colormap turbo
colorbar;
xlabel('Longitude');
ylabel('Latitude');
zlabel('Depth (m)');
title('Salinity (PSU) variability against Depth (m)')
set(gca,'Zdir','reverse');
zlim([2.5 2140]);
Here's what I see for sizes
This means each page of Salinity corresponds to all lat/lon combos at a single depth. A contour plot is a good way to perhaps visualize the salinity at a single depth, but is not an appropriate visualization for all the data at all depths. For that, you may want to consider a scatter3 plot where the markers' size or color are based on salinity. Here are some examples.
load Depth.mat
load Lat.mat
load Lon.mat
load Salinity.mat
% contour plot for Salinity at a specific depth
contour3(Lat,Lon,Salinity(:,:,5))
title(["Salinity at Depth = " + Depth(5)])
colorbar
% scatter3: color set by salinity
[X,Y,Z] = meshgrid(Lat,Lon,Depth);
figure
scatter3(X(:),Y(:),Z(:),[],Salinity(:),'filled')
colorbar
I'm not convided the 3D visualization is adding anything, so I'd be more inclined to use a 2D contour plot here.
figure
contourf(Lat,Lon,Salinity(:,:,5))
title("Salinity at Depth = " + Depth(5))
colorbar
Hey Cris!
Thank you so much for all this assistance and guidance, the contourf plots look a lot better at what I'm trying to show, and I can always use subplots to show the change in salinity with different depths.
Cheers for this!!
Francesca :)

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2021a

Community Treasure Hunt

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

Start Hunting!