How to display labels above a histogram bin?

前端 未结 3 610
暖寄归人
暖寄归人 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:10

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

    0 讨论(0)
  • 2020-12-18 07:13

    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
    
    0 讨论(0)
  • 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).

    0 讨论(0)
提交回复
热议问题