I have an array a(30,2)
where the first column is a unique sample number and the second column is a value assigned to the sample. I plot a histogram of the 2nd
Use histc
, which return an index for each entry, to which bin did it 'fall':
[n, bin] = histc (a(:, 2), bins);
Then the samples above the k'th bin is:
a(bin==k, 1);
Pay attention, you must specify the bins' boundaries yourself (unlike hist
which uses the mid-value between boundaries).
First, create a histogram using HISTC as suggested by @Itamar Katz. To make the bins the same as with HIST, you need to properly calculate bin edges. Then you can plot the distribution and add the labels using TEXT and NUM2STR.
%# get the edges, bin centers
nBins = 10;
edges = linspace(min(a(:,2),max(a(:,2),nBins+1); %# edges go from minimum to maximum of distribution
bins = (edges(1:end-1)+edges(2:end))/2;
%# get the counts and the bin-index
[counts,binIdx] = histc(a(:,2),edges);
%# plot the counts and bins (not edges) with `bar`
figure
bar(bins,counts);
%# Set the axes limits such that you have enough space for the labels
ylim([0,2*max(counts)]);
%# add the labels. Vertically align such that the text goes from the y-coordinate
%# down (as opposed to being centered on the y-coordinate).
for b = 1:nBins
text(bins(b),counts(b)*2,num2str(a(b==binIdx,1)),'VerticalAlignment','top')
end
As was shown by both @Jonas and @Itamar Katz, the idea is to use HISTC to get the bin indices that each sample belongs to, then use BAR to plot the result (note that we use the 'histc'
mode of display for the BAR function). My answer below is a variation of @Jonas's post:
%# random data
a = [(1:30)' rand(30,1)]; %'#
%# compute edges (evenly divide range into bins)
nBins = 10;
edges = linspace(min(a(:,2)), max(a(:,2)), nBins+1);
%# compute center of bins (used as x-coord for labels)
bins = ( edges(1:end-1) + edges(2:end) ) / 2;
%# histc
[counts,binIdx] = histc(a(:,2), edges);
counts(end-1) = sum(counts(end-1:end)); %# combine last two bins
counts(end) = []; %#
binIdx(binIdx==nBins+1) = nBins; %# also fix the last bin index
%# plot histogram
bar(edges(1:end-1), counts, 'histc')
%#bar(bins, counts, 'hist') %# same thing
ylabel('Count'), xlabel('Bins')
%# format the axis
set(gca, 'FontSize',9, ...
'XLim',[edges(1) edges(end)], ... %# set x-limit to edges
'YLim',[0 2*max(counts)], ... %# expand ylimit to accommodate labels
'XTick',edges, ... %# set xticks on the bin edges
'XTickLabel',num2str(edges','%.2f')) %'# round to 2-digits
%# add the labels, vertically aligned on top of the bars
hTxt = zeros(nBins,1); %# store the handles
for b=1:nBins
hTxt(b) = text(bins(b), counts(b)+0.25, num2str(a(b==binIdx,1)), ...
'FontWeight','bold', 'FontSize',8, 'EdgeColor','red', ...
'VerticalAlignment','bottom', 'HorizontalAlignment','center');
end
%# set the y-limit according to the extent of the text
extnt = cell2mat( get(hTxt,'Extent') );
mx = max( extnt(:,2)+extnt(:,4) ); %# bottom+height
ylim([0 mx]);
If the ticks on the x-axis become too crowded, you can display them rotated with an angle using XTICKLABEL_ROTATE function (submission on FEX).