MATLAB: Bin matrix data with nested for loops to create histogram of any size bins

binningfor loops

Hello!
I am fairly new to programming and could use some help. I have a matrix that contains x & y values for an associated voltage (negative potential values to be specific).
Let's consider just X values for simplicity. What I'd like to do is calculate the average x value, calculate the deviation of x relative to this mean and then plot the x scatter relative to the potential. This gives me a lot of overlappping data points so I want to bin the data (want to be able to vary bin size on the fly). I am having trouble getting my nested for loops which count up data points per bin to output the correct matrix. Basically they are just giving me the negative x and p values out and missing all positive x values. I can't wrap my head around what's incorrect. I'd appreciate any suggestions you might have.
Here's part of my code:
%Calculates the values for x & y relative to their means
xcorr=x-x_avg;
ycorr=y_avg-y;
%Spacer is the predefined bin size in pixels
%p is the vector of potential values (all are negative)
xbins=(ceil(max(xcorr))-floor(min(xcorr)))/spacer;
ybins=(ceil(max(ycorr))-floor(min(ycorr)))/spacer;
pbins=(ceil(abs(max(p)))-floor(min(p)))/spacer;
xstart=floor(min(xcorr));
ystart=floor(min(ycorr));
pstart=ceil(max(p));
for kk=1:pbins
for ii=1:xbins
rowsx=find(xcorr>=xstart+spacer*(ii-1) & xcorr<xstart+spacer*ii & p<=pstart-spacer*(kk-1) & p>pstart-spacer*kk);
numfitx(kk,ii)=length(rowsx);
clear rowsx
end
end
%pixsize is the camera pixel size
xnm_centroid=xstart:spacer:xstart+xbins*spacer;
xnm_centroid=xnm_centroid*pixsize;
%Create histogram figure
figure
iptsetpref('ImshowAxesVisible','on')
imshow(fliplr(numfitx),[],'Xdata',pot_axis,'YData',xnm_centroid)
set(gca,'XDir', 'reverse')

Best Answer

I'm still unclear on some points. Your plots switch axes from {x, P} to {x, y} so I'm not sure of their relationship. Furthermore you say there are only negative values for x, whereas I can clearly see values for positive x on your plot.
With regards to the histogram, if I understood correctly, this should work:
x = randn(1, 20000), y = randn(1, 20000); %demo data, 20000 points
spacer = 0.05; %demo data
xbins = floor(min(x)):spacer:ceil(max(x));
ybins = floor(min(y)):spacer:ceil(max(y));
%find where points end up on the x/y axis
[~, ~, idx] = histcounts(x, xbins);
[~, ~, idy] = histcounts(y, ybins);
%switch from 2d to 1d, so histogram of 2d data can be computed:
ii = sub2ind(max([idx' idy']), idx, idy); %convert to linear indices
pdf = histc(ii, 1:max(idx)*max(idy)); %histogram of linear indices
%switch back to 2d:
pdf = reshape(pdf, max(idx), max(idy));
imshow(pdf, [], 'XData', xbins, 'YData', ybins);