How to display labels above a histogram bin?

前端 未结 3 609
暖寄归人
暖寄归人 2020-12-18 07:02

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

3条回答
  •  囚心锁ツ
    2020-12-18 07:34

    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:

    [EDITED]

    %# 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]);
    

    alt text

    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).

提交回复
热议问题