Applying Colormaps to Scatter3 Plots

I'm trying to plot using scatter3, along with colormaps to understand correlations in my data. Currently, this is what I've developed
At first glance, this might look ok, but if you take a closer look (especially as time increases,) you can see that the control action data points don't follow the colorbar colors as you would expect it to. To help, here's the code I wrote to make the plot.
% Here, variable{xAxisChoice} and its similiar calls are 500 x 3001
% matrices.
c = parula(height(variable{zAxisChoice}));
figure()
hold on; grid on; grid minor; box on;
scatter3(variable{xAxisChoice}, variable{yAxisChoice}, variable{zAxisChoice}, 0.75, c)
xlabel(name{xAxisChoice});
ylabel(name{yAxisChoice});
zlabel(name{zAxisChoice})
title(['Scenario ' num2str(scenarioChoice)])
cb = colorbar('colormap', c);
clim([min(variable{4}, [], 'all'), max(variable{4}, [], 'all')])
ylabel(cb, 'Control Action, u [1/m]','FontSize', 12);
I'd be willing to switch to surf or scatteredInterpolant if that makes it easier to represent. The essential points are that each point can be seen, and that the colormap can be applied.

4 Comments

When I try to reproduce your plot using random data, with variable{xAxisChoice} et al of size 500x3001
variable = {rand(500,3001),rand(500,3001),rand(500,3001)};
xAxisChoice = 1;
yAxisChoice = 2;
zAxisChoice = 3;
then I get an error:
c = parula(height(variable{zAxisChoice}));
figure()
hold on; grid on; grid minor; box on;
scatter3(variable{xAxisChoice}, variable{yAxisChoice}, variable{zAxisChoice}, 0.75, c)
Error using scatter3
Color must be one RGB triplet, an m-by-3 matrix of RGB triplets with one color per scatter point, or an m-by-1 vector with one value per scatter point.
Maybe it'd be helpful if you upload your data in a mat file.
variable = {rand(500,3001),rand(500,3001),rand(500,3001)};
xAxisChoice = 1;
yAxisChoice = 2;
zAxisChoice = 3;
c = parula(numel(variable{zAxisChoice}));
whos c
Name Size Bytes Class Attributes c 1500500x3 36012000 double
figure()
hold on; grid on; grid minor; box on;
scatter3(variable{xAxisChoice}(:), variable{yAxisChoice}(:), variable{zAxisChoice}(:), 0.75, c)
Thanks for this contribution @Walter Roberson! Do you have any idea how I could correlate the color of the point to the z-axis?
variable = {rand(500,3001),rand(500,3001),rand(500,3001)};
xAxisChoice = 1;
yAxisChoice = 2;
zAxisChoice = 3;
c = variable{zAxisChoice}(:);
figure()
hold on; grid on; grid minor; box on;
scatter3(variable{xAxisChoice}(:), variable{yAxisChoice}(:), variable{zAxisChoice}(:), 0.75, c)
view(3)
colormap(parula)

Sign in to comment.

 Accepted Answer

"Do you have any idea how I could correlate the color of the point to the z-axis?"
If that's what you want to do, the easy way is to set the figure or axes colormap, and use the Z-variable as the color input to scatter3:
variable = {25+15*rand(500,3001),300*rand(500,3001),-2.5e-4*rand(500,3001)};
xAxisChoice = 1;
yAxisChoice = 2;
zAxisChoice = 3;
name = {'Density \rho [cars/km]','Time t[s]','Control Action, u [1/m]'};
c = parula(height(variable{zAxisChoice}));
figure('Colormap',c)
hold on; grid on; grid minor; box on;
scatter3(variable{xAxisChoice}(:), variable{yAxisChoice}(:), variable{zAxisChoice}(:), 0.75, variable{zAxisChoice}(:))
xlabel(name{xAxisChoice});
ylabel(name{yAxisChoice});
zlabel(name{zAxisChoice});
cb = colorbar();
clim([min(variable{zAxisChoice}, [], 'all'), max(variable{zAxisChoice}, [], 'all')])
ylabel(cb, name{zAxisChoice},'FontSize', 12);
view(3)

3 Comments

To use scaled mapping of colors (which my answer uses), you have to set the current colormap, as indicated in the scatter3 documentation:
"Assign different colors to each point using a colormap.
Specify a row or column vector of numbers. The numbers map into the current colormap array. The smallest value maps to the first row in the colormap, and the largest value maps to the last row. The intermediate values map linearly to the intermediate rows."
Note that colorbar('colormap',_) doesn't set the figure's colormap:
f = figure();
% the figure's colormap is parula(256) by default
isequal(f.Colormap, parula(256))
ans = logical
1
% create a colorbar showing a different colormap
colorbar('colormap', jet(32))
% check the figure's colormap now:
% it's still parula(256)
isequal(f.Colormap, parula(256))
ans = logical
1
% not jet(32)
isequal(f.Colormap, jet(32))
ans = logical
0
Great! I got this to work with my data. I've accepted the answer because it answers exactly what I asked, but I have one more question - if length(variable{yAxisChoice}(:)) ~= length(variable{xAxisChoice}(:)) or length(variable{zAxisChoice}(:)), how could I change the code to help it handle that case?
You're welcome!
In case variable{xAxisChoice} et al are not all the same size, I would go by the smallest one and truncate the others for plotting. Something like this:
[mx,nx] = size(variable{xAxisChoice});
[my,ny] = size(variable{yAxisChoice});
[mz,nz] = size(variable{zAxisChoice});
m = min([mx,my,mz]);
n = min([nx,ny,nz]);
X = variable{xAxisChoice}(1:m,1:n);
Y = variable{yAxisChoice}(1:m,1:n);
Z = variable{zAxisChoice}(1:m,1:n);
scatter3(X(:), Y(:), Z(:), 0.75, Z(:))

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2023b

Asked:

on 6 Mar 2024

Commented:

on 7 Mar 2024

Community Treasure Hunt

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

Start Hunting!