# Scatter plot with mean for multiple groups

23 views (last 30 days)

Show older comments

Hello,

I'm trying to create a scatter plot looks like this:

I don't know the original name but I found this link : https://www.mathworks.com/matlabcentral/fileexchange/62871-cigarscatterplot?s_tid=srchtitle_scatter%20plot_15 I also attached the code that I used. It's slightly different than the original one (because I have more groups).

This is the part of data. I have 4 ranges and 3 experiments for each drug group. for every range I'm trying to add all 3 experiment for each group in same vertical area and box. eventually, my aim is to create 4 boxes for each range next to each other . (I mean; box = the area whic is seperated with dashlines in the scatterplot) and each box is needed to have 4 groups.

I wrote this command

Control= [0,0,0]

ap= [5, 36, 52]

Drug1 = [1,1,1]

bp = [32, 16, 0]

Drug2 = [2,2,2]

cp = [0, 15, 5]

Drug3 = [3,3,3]

dp= [16, 0.00, 1]

x = [Control, Drug1, Drug2, Drug3]

y= [ap, bp, cp, dp]

[x,y]= Tugce3CigarScatterPlot(x,y)

I could only add 1 range for 4 groups with all 3 experiment and looked like this. 0 is Control, 1 is Drug 1,.... , and ylim is experiment data.

I need to change 0 with Control, 1 with Drug 1,... n the xlim. Also need to add different ranges next to this plot.

I'm not sure if it's multiple questions in one question but I couldn't find any information to create this kind of plot other than the link above. If anyone knows this scatterplot's original name, maybe I can search for it and find more information, otherwise I would be really apreaciated for any suggestions for any steps.

Thank you so much

### Accepted Answer

dpb
on 27 Sep 2022

Edited: dpb
on 28 Sep 2022

fn=websave('MATLAB_exampledata.xlsx','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1136975/MATLAB_exampledata.xlsx');

tData=readtable(fn);

iscat=vartype('cellstr');

tData=convertvars(tData,@iscellstr,'categorical');

tData.Mean=mean(tData{:,vartype('double')},2)

hTL=tiledlayout(1,3);

R=categories(tData.Range);

for i=1:numel(R)

hT(i)=nexttile;

if i==1, posn=hT(i).Position; L=posn(1);B=posn(2);H=posn(4);end % left, bottom, height

ix=(tData.Range==R(i));

hSC=scatter(tData(ix,:), 'Group', {'percentage', 'percentage_1', 'percentage_2'},'filled');

hold on

hL=plot(double(tData.Group(ix)).'+0.5*[-1;1],double(tData.Mean(ix)).'+[-0;0], 'r-');

ylim([0 100]+[-2 2]) % add just a little whitespace

hT(i).XAxisLocation='origin'; % and keep axis at origin

title(R(i))

if i>1, hT(i).YAxis.Visible='off';end

xlabel('')

if i==numel(R)

hLg=legend([hSC(:);hL(1)],'Pct 0','Pct 1','Pct 2','Mean', ...

'Location','eastoutside','Orientation','vertical');

posn=hT(i).Position; W=posn(1)+posn(3)-L; % width overall after adding legend

end

end

hA=annotation('rectangle',[L B W H]);

Would be my starting point with a traditional scatter can't run the cigarScatter on online platform; I'll see if I can find some time to look at it some later...that's most of what you wanted on the axes; it isn't so easy to draw the horizontal line with categorical variables; yline works but goes across the whole axis range so that doesn't help and there's only the one point on a categorical axes at which can plot. One way is to introduce "fake" categories into the variable to introduce more granularity in the axis. Another is to lay another axis on top the the existing that is numeric and plot into it; alternatively, just do as the cigar plot guy did; do it all numerically and the just label the ticks; the tick labels and the ticks are independent properties.

Mayhaps that will give some ideas on approaches...

ADDENDUM: "Stealing" from @Chunru using the table variable names and the new feature (introduced R2022b) of being able to use other than a categorical variable in a categoricalRuler axis, just a few enhancements.

Also to add the overall figure box is not too bad with the annotation function; just have to compute the outer boundaries of the axes from first to last to find the overall coordintes.

To add the dividing lines between is another application of annotation with a line; one needs to add the computation of the x-location between the first two and the last two axes to come up with the position at which to draw it; I've left that as "exercise for student" -- it would follow the idea illustrated above in the computation of the overall width -- one has to find the RH position of the first axis by adding the Left and Width position values and then add halve the distance between that location and the Left postion of the second.

With the advent of being able to use numeric data on categorical axis, all it would take would be to add a little jitter to the x position vector to be able to create the "cigarscater" figure without having to fool with it. I looked at it a little last night but it had so much extra baggage coming along with it to handle all the "what ifs" that it does that I didn't feel like trying to delve into just how it actually worked to try to do anything more with it.

##### 6 Comments

dpb
on 28 Sep 2022

Hmmm...mayhaps I was/am wrong; I thought one could do so with the more recent changes -- I know it doesn't cost a poster status points if change, though.

On the xlabel position, if you want to move it, then save its handle when creating it and adjust the 'Position' value...it's just a text object with (x,y,z) coordinates (z-->0 for 2D graphs)

hXLab=xlabel('X'); % write a label; save handle

posn=hXLab.Position; % retrieve default position

posn=posn.*[1 1.1 1]; % adjust y position by 10% (will be negative so down)

hXLab.Position=posn; % set new position

On axis location,

hT(i).XAxisLocation='origin' , 'Location','southoutside'; % and keep axis at origin

is mixing metaphors of the legend positon with the axis -- they're entirely different; the axis location is only one of 'origin', 'top', 'bottom'; anything else is unallowble.

It's some other modifications up earlier to be able to put the legend at 'southoutside'; I actually had tried it and decided didn't want to take the time to make the other modifications to do so, so took the easiest way out.

To do that and make it all work out in the end, you'll have to add it first before calculating the location of the bottom axes because adding it causes the axes to all be shrunk to be shorter to make room. That'll mean moving the logic up top inside the loop that computes L, B, H to after the legend is created in order to have the axes final positions.

It's all doable; just a lot of bookkeeping and nits to take care of to create the special effects desired. Welcome to HG2!!! You'll be a whizard here shortly and be complaining like me about stuff that should be simpler than it is...

### More Answers (1)

Chunru
on 27 Sep 2022

x = readtable("https://www.mathworks.com/matlabcentral/answers/uploaded_files/1136975/MATLAB_exampledata.xlsx");

x.Group = categorical(x.Group);

x.Range = categorical(x.Range)

urange = unique(x.Range);

n = length(urange);

for i=1:n

subplot(1,n,i)

x1 = x(x.Range==urange(i), :);

scatter(x1, 'Group', {'percentage', 'percentage_1', 'percentage_2'});

hold on

plot((double(x1.Group)+[-.5 .5])', (mean(x1{:, 3:5}, 2)+[0 0])', 'r-')

title(urange(i))

end

##### 4 Comments

dpb
on 28 Sep 2022

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!