How to group by 2 variables, with unique colors for one and unique shapes for the other
8 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Ellen Maas
el 9 de Abr. de 2021
Respondida: Cris LaPierre
el 9 de Abr. de 2021
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.
0 comentarios
Respuesta aceptada
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"])
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")
0 comentarios
Más respuestas (0)
Ver también
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!