【问题标题】:How to display labels above a histogram bin?如何在直方图 bin 上方显示标签?
【发布时间】:2011-01-11 12:42:36
【问题描述】:

我有一个数组a(30,2),其中第一列是唯一的样本编号,第二列是分配给样本的值。我绘制了第二列的直方图:

hist(a(:,2))

我有N bins,y 轴告诉我有多少样本的值为 x, 但没有关于哪些样本在哪个 bin 中的信息。

如何在每个 bin 上方绘制落入每个 bin 的样本列表(我的数组 a 第一列的数字)?

【问题讨论】:

    标签: matlab plot histogram


    【解决方案1】:

    正如@Jonas@Itamar Katz 所示,想法是使用 HISTC 获取每个样本所属的 bin 索引,然后使用 BAR 绘制结果(注意我们使用 'histc' 模式BAR 功能的显示)。我在下面的回答是@Jonas 帖子的变体:

    [已编辑]

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

    如果 x 轴上的刻度太拥挤,您可以使用 XTICKLABEL_ROTATE 函数将它们旋转一个角度显示(提交到 FEX)。

    【讨论】:

    • 我等了一会儿才回答,因为我以为这就是你的胡同。当然,你会用漂亮的图片给出一个很好的答案!挑剔:lastEdge 实际上是edges(end);您不需要从轴限制中提取它。无论如何 +1 以获得比我更漂亮的解决方案(我喜欢矩形),尽管我会将文本放在 counts+0.5 处。
    • @Jonas:感谢您发现最后一个 bin 错误,我已修复它...我想值得一提的是,在最后一个 bin HISTC 仅计算与 edges(end) 完全匹配的值(这就是为什么我合并了最后两个垃圾箱)。
    【解决方案2】:

    首先,按照@Itamar Katz 的建议,使用HISTC 创建一个直方图。要使 bin 与 HIST 相同,您需要正确计算 bin 边缘。然后您可以绘制分布并使用TEXTNUM2STR 添加标签。

    %# 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
    

    【讨论】:

    • +1 正是我的想法,我根据您的回答发布了另一个解决方案
    【解决方案3】:

    使用histc,它为每个条目返回一个索引,它“落”到哪个bin:

    [n, bin] = histc(a(:, 2), bins);

    那么第k个bin上面的样本就是:

    a(bin==k, 1);

    注意,您必须自己指定 bin 的边界(不像 hist 使用边界之间的中间值)。

    【讨论】:

      猜你喜欢
      • 2013-04-03
      • 1970-01-01
      • 2011-08-23
      • 2021-01-06
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多