How can I create a 3D intensity map, or 3D scatter plot where colour represents intensity?

조회 수: 13 (최근 30일)
I am hoping to create a 3D plot for a data set (a 3D matrix) where each voxel has four pieces of data: an x position, y position, z position, and intensity. I would like to create a scatter plot (or other type of intensity map) where each point is appropriately located, and its colour relates its value. The result might look something like the example of 'Visualize function of 3 variables' on this page: https://www.mathworks.com/help/matlab/visualize/visualizing-four-dimensional-data.html. However, I have thus far been unable to replicate that result with my own data, which is organized in a 3D matrix.
For example, if I have this matrix M:
A = [1 2 3; 4 5 6; 7 8 9];
A(:,:,2) = [10 11 12; 13 14 15; 16 17 18];
B = cat(3,A,[3 2 1; 0 9 8; 5 3 7]);
M = B./max(B);
how do I create a 3D plot where the voxel with value 0.3333 is located at point 3, 2, 3 on the 3D plot and is blue to show that it has a relatively low value, while the points representing voxels with value 1.000 (the maximum) are red. I would also like to include a sidebar which shows the colour scale.
In case it is helpful, here is the code from the above-mentioned example (i.e., not my code):
cla
load accidents hwydata % load data
long = -hwydata(:,2); % longitude data
lat = hwydata(:,3); % latitude data
rural = 100 - hwydata(:,17); % percent rural data
fatalities = hwydata(:,11); % fatalities data
scatter3(long,lat,rural,40,fatalities,'filled') % draw the scatter plot
ax = gca;
ax.XDir = 'reverse';
view(-31,14)
xlabel('W. Longitude')
ylabel('N. Latitude')
zlabel('% Rural Population')
cb = colorbar; % create and label the colorbar
cb.Label.String = 'Fatalities per 100M vehicle-miles';
Thank you in advance for any help you can provide!

채택된 답변

Kevin Holly
Kevin Holly 2022년 3월 28일
편집: Kevin Holly 2022년 3월 28일
The dimensions of the matrix, M, is 3x3x3. I am going to assume the third dimension is your x, y, and z coordinates, where 1 is x, 2 is y, and 3 is z. With that established, what values do you want expressed in the 4th dimension (the colors).
Define variables
A = [1 2 3; 4 5 6; 7 8 9];
A(:,:,2) = [10 11 12; 13 14 15; 16 17 18];
B = cat(3,A,[3 2 1; 0 9 8; 5 3 7]);
M = B./max(B);
Create scatter plot and color bar
scatter3(M(:,:,1),M(:,:,2),M(:,:,3),40,'filled')
xlabel('x')
ylabel('y')
zlabel('z')
colorbar
  댓글 수: 5
Kevin Holly
Kevin Holly 2022년 3월 31일
% Equivalence of square and circular fields: R = 0.558 a
% where R is the radius of the circle
% and the side of the square has length a
R = 5; % radius of beam at surface of tank (cm)
a = R./0.558; % equivalent square side length (cm)
%%%%%%%%%%%%%%%%%%%%%%%%%
% get surface PDD
PDD_surface_mia_et_al = [0.3821, 0.4100, 0.4320, 0.4010]; % measured surface PDDs
field_size= [4, 6, 8, 10]; % square field side length
PDD_surface = interp1(field_size,PDD_surface_mia_et_al,a); % interpolate PDD at surface for field side length a
% This is the depth and PDD from surface up to 30 cm depth
% use steps of 0.5 cm since this is the voxel size
xmid = [0, 1.5:0.5:30]; % distance from surface of tank (cm)
fmid = [PDD_surface, 1, 0.988, 0.9692, 0.9505, 0.9295, 0.9084, 0.8874, 0.8664, 0.8454, 0.8244, 0.8041, 0.7838, 0.7641, 0.7443, 0.7251, 0.7058, 0.6875, 0.6693, 0.6515, 0.6338, 0.6170, 0.6002, 0.5847, 0.5692, 0.5537, 0.5382, 0.5240 ,0.5097, 0.4957, 0.4817, 0.4690, 0.4562, 0.4437, 0.4312, 0.4197, 0.4082, 0.3972, 0.3862, 0.3757, 0.3652, 0.3552, 0.3452, 0.3360, 0.3268, 0.3183, 0.3098, 0.3013, 0.2928, 0.2850, 0.2773, 0.2698, 0.2623, 0.2553, 0.2483, 0.2418, 0.2353, 0.2288, 0.2223];
% get PDD between 0 cm and 1.5 cm
pshallow = polyfit(xmid(1,1:2),fmid(1,1:2),1); % get fit equation
xshallow = 0:0.5:1.5; % depths in cm up to 1.5 cm
fshallow = polyval(pshallow,xshallow); % results of fit
% get extrapolated PDD for 30 to 50 cm depth
pdeep = polyfit(xmid(1,30:length(xmid)),fmid(1,30:length(fmid)),3); % get fit equation
xdeep = 30:0.5:50; % depth up to 50 cm
fdeep = polyval(pdeep,xdeep); % results of fit
% combine all of the PDDs
depth = 0:0.5:50; % depth in cm
PDD = [fshallow, fmid(1,3:length(fmid)), fdeep(1,2:length(fdeep))]; % PDD from 0 cm to 50 cm depth
%%%%%%%%%%%%%%%%%%%%%%%%%
% Create Gaussian distributions for lateral dose profiles
x = [-15:0.5:15]; % distances along x or y direction (cm), centred at 0 cm, 0.5cm voxel side length
lat_profile = normpdf(x,0,1); % Gaussian dist with mean = 0, sigma = 1 cm
% make the centre of the distribution match the dose on the CAX
% create profiles for 1.5 cm, 5 cm, 10 cm, 20 cm
x_lat_p_015 = lat_profile./max(lat_profile).*PDD(find(depth == 2)); % profile at 1.5 cm deep
x_lat_p_05 = lat_profile./max(lat_profile).*PDD(find(depth == 5)); % 5 cm deep
x_lat_p_10 = lat_profile./max(lat_profile).*PDD(find(depth == 10)); % 10 cm deep
x_lat_p_20 = lat_profile./max(lat_profile).*PDD(find(depth == 20)); % 20 cm deep
y_lat_p_015 = lat_profile./max(lat_profile).*PDD(find(depth == 2)); % profile at 1.5 cm deep
y_lat_p_05 = lat_profile./max(lat_profile).*PDD(find(depth == 5)); % 5 cm deep
y_lat_p_10 = lat_profile./max(lat_profile).*PDD(find(depth == 10)); % 10 cm deep
y_lat_p_20 = lat_profile./max(lat_profile).*PDD(find(depth == 20)); % 20 cm deep
%%%%%%%%%%%%%%%%%%%%%%%%%
% Put the lateral and CAX PDDs into one matrix
% first do the CAX
tank = zeros((30*2 + 1), (30*2 + 1), (50*2 + 1)); %pre-allocate 30cm x 30cm x 50cm matrix with 0.5 cm voxels
for k = 1:length(PDD)
tank(k,31,51) = PDD(k);
end
% then do lateral
% 1.5 cm deep
tank = zeros((30*2 + 1), (30*2 + 1), (50*2 + 1));
for k = 1:length(x_lat_p_015)
tank(31,k,find(depth == 1.5)) = x_lat_p_015(k);
end
for k = 1:length(x_lat_p_015)
tank(k,31,find(depth == 1.5)) = x_lat_p_015(k);
end
% 5 cm deep
tank = zeros((30*2 + 1), (30*2 + 1), (50*2 + 1));
for k = 1:length(x_lat_p_015)
tank(31,k,find(depth == 5)) = x_lat_p_05(k);
end
for k = 1:length(x_lat_p_015)
tank(k,31,find(depth == 5)) = x_lat_p_05(k);
end
% 10 cm deep
tank = zeros((30*2 + 1), (30*2 + 1), (50*2 + 1));
for k = 1:length(x_lat_p_015)
tank(31,k,find(depth == 10)) = x_lat_p_10(k);
end
for k = 1:length(x_lat_p_015)
tank(k,31,find(depth == 10)) = x_lat_p_10(k);
end
% 20 cm deep
tank = zeros((30*2 + 1), (30*2 + 1), (50*2 + 1));
for k = 1:length(x_lat_p_015)
tank(31,k,find(depth == 20)) = x_lat_p_20(k);
end
for k = 1:length(x_lat_p_015)
tank(k,31,find(depth == 20)) = x_lat_p_20(k);
end
Create vector coordinates for 30 cm x 30 cm x 50 cm tank
x_coord = 1:0.5:30+1;
y_coord = 1:0.5:30+1;
z_coord = 1:0.5:50+1;
Create vectors (x, y, and z) that represent all points within 3D grid
[X,Y,Z] = meshgrid(x_coord,y_coord,z_coord);
x=reshape(X,1,[]);
y=reshape(Y,1,[]);
z=reshape(Z,1,[]);
Reshape 3D tank matrix into a single array
tank_vector = reshape(tank,1,[]);
Create scatterplot
figure; scatter3(x,y,z,[],tank_vector,'filled')
% Remove Scatter points with value of zero
M = [x;y;z;tank_vector];
M(:,M(4,:)==0)=[];
figure; scatter3(M(1,:),M(2,:),M(3,:),[],M(4,:),'filled')
colorbar

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Interpolation of 2-D Selections in 3-D Grids에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by