Clear Filters
Clear Filters

Color map using gscatter

52 views (last 30 days)
nicole
nicole on 3 Mar 2023
Edited: Voss on 5 Mar 2023
Hello,
I am using gscatter to make a scatter plot of temperature vs kd color coded by temperature.
I would like to color code the temperature using a color map (either hot or autumn) to show the temperature gradients movement from hot to cold, but can not figure out how to do this using gscatter.
I have posted my code below:
figure(6); hold on; box on;
gscatter(alldataoxides.pHs, log(alldataoxides.kds), alldataoxides.Temperature)
colormap autumn
xlabel('pH');
ylabel('log kd');
title('oxides - synthetic corundum, geothite, gibbsite')
hold off;
Any advice would be much apprecitated!
Thanks.

Accepted Answer

Voss
Voss on 3 Mar 2023
% some made-up data
alldataoxides = struct( ...
'pHs',14*rand(1,100), ...
'kds',1000*rand(1,100), ...
'Temperature',linspace(45,255,100));
% group the temperature values into bins
bin_width = 30; % each bin is 30 degrees (you can change this)
% the edges of the bins will all be multiples of bin_width
limits = [ ...
floor(min(alldataoxides.Temperature)/bin_width) ...
ceil(max(alldataoxides.Temperature)/bin_width) ...
];
bin_edges = (limits(1):limits(2))*bin_width;
% number of temperature bins
n_bins = numel(bin_edges)-1;
% bin_idx is which bin each temperature value is in
bin_idx = discretize(alldataoxides.Temperature,bin_edges);
% construct bin labels to describe the temperature range for each bin, e.g., "30 <= T < 60"
bin_labels = cell(n_bins,1);
for ii = 1:n_bins-1
bin_labels{ii} = sprintf('%g <= T < %g',bin_edges(ii),bin_edges(ii+1));
end
% the last bin is different because it includes its upper edge
bin_labels{end} = sprintf('%g <= T <= %g',bin_edges(end-1),bin_edges(end));
% index bin_labels with bin_idx to get a label for each temperature value.
% this will be used as the groups in gscatter.
labels = bin_labels(bin_idx);
% create a matrix of colors from 'autumn' colormap, one color for each temperature bin
colors = autumn(n_bins);
figure(6); hold on; box on;
gscatter(alldataoxides.pHs, log(alldataoxides.kds), labels, colors)
xlabel('pH');
ylabel('log kd');
title('oxides - synthetic corundum, geothite, gibbsite')
legend('Location','eastoutside')
hold off;
  2 Comments
nicole
nicole on 5 Mar 2023
thank you so so much! This was really, really helpful!!
Voss
Voss on 5 Mar 2023
Edited: Voss on 5 Mar 2023
You're welcome!
For posterity, I'm going to also reply to your original comment, reproduced here:
"Thank you so much Voss! This was really helpful:) Thank you for taking the time to code everything up and leave detailed comments on each line.
This was so helpful that I am actually trying to turn it into a function - however I am getting errors when I do so, I have attached my function along with an example call.
Every time I call the function it gives me back a 1 in the colors matrix.
When I run the function I created and then run your code using the same input values for each (i.e. 30 bin width, temperature as the variable, and colormap autumn), I get the same exact values for each vairable (i.e. bin width, bin edges, etc.) until I get to colors. I am returning the colors matrix as an output in my function, and when I return it in the function it says that the colors matrix = 1 regardless of what I do. In your function I get back a double matrix that lists what colors I am indexing from the color map, which is correct and what want - yet this is not working.
Any ideas where I went wrong?
Thank you so much,
N"
You may have already figured it out, but here's my explanation anyway:
I didn't find the example call to colorcoding you mentioned, but I suspect the problem is with the second input argument, map.
autumn (like hot, jet, hsv, etc. - all the built-in colormaps) is a function that takes a single number as input and returns a matrix of colors. Inside colorcoding, whatever colormap function you give it will be evaluated with the number of colors (n_bins) once the number of colors is known. So to pass the colormap you want as an input to colorcoding, you have to pass a handle to that colormap function. For example, use @autumn instead of autumn. If you use autumn without the @ in front, that evaluates the autumn function with no arguments (which uses the default value of 64 colors) before passing it to colorcoding, so what's passed to colorcoding in that case is a 64-by-3 matrix. Then inside colorcoding, map is a variable and map(n_bins) indexes that variable with index n_bins, instead of evaluating the function map with input argument n_bins. (Since the red channel of the autumn colormap is all 1's, you get 1 returned no matter how many bins there were.)
A separate issue worth mentioning is: For the method in my answer to be used with gscatter and have the legend labels be in the correct order, the three variables should be sorted according to the thirdvariable value. (The Temperature values in the random data I made up were already sorted, so I didn't notice this until now.)
I also added an optional fourth argument to colorcoding, which is thirdvariablename, signifying the name of the color variable to be used in the labels. If it's unspecified, then the name 'variable' is used, like you had it. (Updated function is attached.)
See example usage below:
% some made up data, now with unsorted Temperature:
alldataoxides = struct( ...
'pHs',14*rand(1,100), ...
'kds',1000*rand(1,100), ...
'Temperature',200*rand(1,100));
% sort the data according to Temperature:
[Temperature,idx] = sort(alldataoxides.Temperature);
pHs = alldataoxides.pHs(idx);
kds = alldataoxides.kds(idx);
% get the colors and labels using our colorcoding function
[colors, labels] = colorcoding(30, @autumn, Temperature, 'T')
colors = 7×3
1.0000 0 0 1.0000 0.1667 0 1.0000 0.3333 0 1.0000 0.5000 0 1.0000 0.6667 0 1.0000 0.8333 0 1.0000 1.0000 0
labels = 100×1 cell array
{'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'0 <= T < 30' } {'30 <= T < 60'} {'30 <= T < 60'} {'30 <= T < 60'} {'30 <= T < 60'} {'30 <= T < 60'} {'30 <= T < 60'} {'30 <= T < 60'} {'30 <= T < 60'}
% plot with gscatter
figure(6); hold on; box on;
gscatter(pHs, log(kds), labels, colors)
xlabel('pH');
ylabel('log kd');
title('oxides - synthetic corundum, geothite, gibbsite')
legend('Location','eastoutside')
hold off;

Sign in to comment.

More Answers (0)

Categories

Find more on Colormaps in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!