# Can you organize scatter plot points?

31 views (last 30 days)

Show older comments

Hi,

I would like to graph my data with the mean +/- SEM and display the data points. When I plot this, my data points are overlapping and difficult to distinguish. Rather than a random distribution/jitter, I would like my data points for same/similiar values to form nonoverlaping rows of points. Is this poissible in Matlab? Any help is greatly appreciated!

Thanks,

Dan

Example code:

subplot 133

% Plot horizontal line at 50%

yline(0.5,'k--','LineWidth',ylineLW)

hold on

% Plot data points

scatter(y1(:,1),data(:,1),'black','filled','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'XJitter','randn')

scatter(y1(:,2),data(:,2),'red','filled','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'XJitter','randn')

scatter(y1(:,3),data(:,3),'black','filled','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'XJitter','randn')

scatter(y1(:,4),data(:,4),'red','filled','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'XJitter','randn')

% Plot errorbar (SEM)

errorbar(y2(1),mData(1),SEM(1),'k_','LineWidth',errorbarLW)

errorbar(y2(2),mData(2),SEM(2),'r_','LineWidth',errorbarLW)

errorbar(y2(3),mData(3),SEM(3),'k_','LineWidth',errorbarLW)

errorbar(y2(4),mData(4),SEM(4),'r_','LineWidth',errorbarLW)

% Plot mean values

plot(y2(1),mData(1),'k_','LineWidth',plotLW,'MarkerSize',plotMS)

plot(y2(2),mData(2),'r_','LineWidth',plotLW,'MarkerSize',plotMS)

plot(y2(3),mData(3),'k_','LineWidth',plotLW,'MarkerSize',plotMS)

plot(y2(4),mData(4),'r_','LineWidth',plotLW,'MarkerSize',plotMS)

hold off

PS I attached one of my plots to help visualize the problem. Please let me know if you have any questions... thanks again!

##### 12 Comments

Matt J
on 7 May 2021

What you describe is basically the same as a histogram. Why not just use the histogram() command?

### Accepted Answer

Matt J
on 7 May 2021

Edited: Matt J
on 7 May 2021

I think it may make more sense for you to move to a proper violin plot. With this 3rd party file, for example

you can generate plots like the one below. The violin envelope clearly delineates the boundaries of the estimated distribution for each level y, which I think is ultimately what you want.

load Data.mat

hv=violinplot(data,{'Sham','TBI'});

ylabel 'Discrimination Ratio'

for i=1:2

hv(i).ViolinAlpha=0.1;

hv(i).ScatterPlot.MarkerFaceAlpha=0.7;

end

hv(1).ViolinColor='k';

hv(2).ViolinColor='r';

If you wish, the jittered data points can be overlaid as well:

[hv.ShowData]=deal(true); %remove if you don't want data points included

##### 2 Comments

dpb
on 7 May 2021

Edited: dpb
on 7 May 2021

y=sort(data(:,1));

delta=0.075;

dx=zeros(size(y));

dx(1:2)=delta*[-1 1].';

dx(6:end-3)=delta*repmat(-1:1,1,4);

hSc=scatter(x+dx,y,'black','filled');

xlim([0 5])

produces

I didn't work on the differences algorithm much, but look at something like

find(diff(y<=thresh))

where thresh is about 0.02. If you want more separation, increase dx.

I can count 20 individual points in the above, although a few are still touching with above choices.

ADDENDUM: Remember the length(diff(y)) is one less than length(y) when locating indices to modify.

### More Answers (2)

Matt J
on 7 May 2021

Edited: Matt J
on 7 May 2021

This may be more along the lines of what you were originally looking for

load Data;

w=max( max(data,[],1) - min(data,[],1) ); %Maximum swarm width

xoffset=w; %separation between swarms

P=size(data,2);

for n=1:P

y=data(:,n);

bins=linspace(min(y),max(y),15);

[counts,~,G]=histcounts(y,bins);

sumc=sum(counts);

x=nan(size(y));

for i=1:numel(counts)

J=(G==i);

N=counts(i);

if N<2

x(J)=0;

else

x(J)=(w*N/sumc)*linspace(-0.5,+0.5,N);

end

end

x=x+n*xoffset;

h(i)=scatter(x,y,'filled');

axis equal

hold on

end

hold off

xticks((1:P)*xoffset)

xlim([xoffset/2,P*w+xoffset/2])

xticklabels({'Sham','TBI'})

##### 0 Comments

Steven Lord
on 7 May 2021

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!