How to group by 2 variables, with unique colors for one and unique shapes for the other

8 visualizaciones (últimos 30 días)
I am trying to plot a set of paired data in a correlation graph. It's a 3-year study with two field treatments and 8 levels of inputs to judge a plant response. I want to display the data showing 8 different colors representing the 8 input levels and 3 different shapes to represent the 3 different years of the study. I am using gscatter but according to the documentation it can't handle the independent nature of the variables with their respective colors and shapes. The end result is that for each unique grouping (24 of them), it applies a unique combination of color and shape for each unique combination of input and year.
Here is a graph with the output using one grouping variable (input). It correctly assigns a unique color to each input level. There are 2 points for each of 3 years, for a total of 6 points per color.
Now I just want to change the shape of the 2nd and 3rd years and keep the colors the same for that input. So for example, for input = 0, there would be 2 red points (2016), 2 red squares (2017), and 2 red triangles (2018).
There must be a reasonable way to do this. I'm open to all suggestions either getting this method to work, or using a different function.
Here is the code with a smaller sub-set of the data:
clear
Treatments = table([{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'};{'T1'};{'T2'}]);
Data = [2016 2016 2017 2017 2018 2018 2016 2016 2017 2017 2018 2018 2016 2016 2017 2017 2018 2018;...
0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2;...
4704.5 4059.5 10891 11440.5 4083.5 2876 11459.66667 11752 11566 12036 11323.5 11118.5 10296.5 10234 13074.5 14166 9062 9669]';
% split by treatment
t1Response = Data(strcmp(Treatments.Var1,'T1'),3);
t2Response = Data(strcmp(Treatments.Var1,'T2'),3);
Inputs = Data(strcmp(Treatments.Var1,'T2'),2); % treatment doesn't matter, just need one set
Years = Data(strcmp(Treatments.Var1,'T2'),1); % treatment doesn't matter
% all points one shape, group colors just by inputs
figure;
colors = lines(8);
colors(8,1)=0.5;
g = gscatter(t1Response,t2Response,Inputs,colors([7,2,3],:),'.',20,'on');
% group by input and year - this results in unique colors and shapes to
% unique combinations of input and year, together. can't assign point
% attributes by variables independently
figure;
g2 = gscatter(t1Response,t2Response,{Inputs,Years},colors([7,2,3],:),'.s^',20,'on'); g2(1).MarkerFaceColor = colors(7,:);
% manually re-assigning colors to data points doesn't work - order of g2
% doesn't match legend. figuring this out for 24 entries would be tedius and not
% guaranteed to work as expected
% g2(1).MarkerFaceColor = colors(7,:);
% g2(2).MarkerFaceColor = colors(7,:);
% g2(3).MarkerFaceColor = colors(7,:);
% g2(4).MarkerFaceColor = colors(2,:);
% g2(5).MarkerFaceColor = colors(2,:);
% g2(6).MarkerFaceColor = colors(2,:);
% g2(7).MarkerFaceColor = colors(3,:);
% g2(8).MarkerFaceColor = colors(3,:);
% g2(9).MarkerFaceColor = colors(3,:);
Thanks in advance for any ideas.

Respuesta aceptada

Cris LaPierre
Cris LaPierre el 9 de Abr. de 2021
There are a couple competing issues. First, all points in a series will have the same color and marker by default. Rather than fight this, you might as well take advantage of it - one plot command for each year, specifying the marker to use.
The next issue is that MATLAB will continue on to the next color in the colororder when the next plot is added by default. You will need to reset this or explicitly assign colors to give each year the same color.
This may not be pretty, but I think your problem is greatly simplified if you rearrange your data a little and use a table. Specifically, reshape the data so that T1 and T2 repsonse values are in their own columns. This will simplify the indexing you have to do.
How helpful this approach is will depend on how representative your sample data set is to your actual data.
% Original data
Year = [2016 2016 2017 2017 2018 2018 2016 2016 2017 2017 2018 2018 2016 2016 2017 2017 2018 2018];
Input = [0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2];
Response = [4704.5 4059.5 10891 11440.5 4083.5 2876 11459.66667 11752 11566 12036 11323.5 11118.5 10296.5 10234 13074.5 14166 9062 9669];
% Reormat the data
Year = min(reshape(Year,2,[]),[],1)';
Input = min(reshape(Input,2,[]),[],1)';
Response = reshape(Response,2,[])';
% Visualize the data
Data = array2table([Year,Input,Response],'VariableNames',["Year","Input","T1","T2"])
Data = 9×4 table
Year Input T1 T2 ____ _____ ______ ______ 2016 0 4704.5 4059.5 2017 0 10891 11440 2018 0 4083.5 2876 2016 1 11460 11752 2017 1 11566 12036 2018 1 11324 11118 2016 2 10296 10234 2017 2 13074 14166 2018 2 9062 9669
gscatter(Data.T1,Data.T2,Data.Input)
% plot each year separately, but still group by input
figure
mrkr = {'.','s','^'};
ax = axes;
hold on
Yr = unique(Data.Year);
for y = 1:length(Yr)
ind = Data.Year == Yr(y);
% just plot data for this year, specifying marker style and turning legend off
gscatter(ax,Data.T1(ind),Data.T2(ind),Data.Input(ind),[],mrkr{y},[],'off');
ax.ColorOrderIndex = 1;
end
hold off
% Use some string manipulation to create legend labels for all color+marker combinations
legend(Yr' + "_" + unique(Data.Input),'NumColumns',length(Yr),'Interpreter',"none",'Location',"best")

Más respuestas (0)

Categorías

Más información sobre 2-D and 3-D Plots en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by