【问题标题】:MatLab: Create 3D Histogram from sampled dataMatLab:从采样数据创建 3D 直方图
【发布时间】:2014-07-17 11:00:46
【问题描述】:

我在数组transitions=zeros(101,101) 的区间 [0,1] 中采样了数据,我想将其绘制为 3D 直方图。 transitions 填充的数据类似于此线程末尾提供的示例数据。

第一列是第一个观察变量X,第二列是第二个变量Y,第三列是归一化频率。 IE。对于第一行:观察到的变量对 (0,0) 的归一化频率为 0.9459。 (0,Y)thus 的归一化频率之和为 1

我尝试使用以下代码制作(某种程度的)3D 直方图:

        x_c = (transitions(:,1) * 100)+1;
        y = (transitions(:,2) * 100)+1;
        z = transitions(:,4);
        %A = zeros(10,10);
        A = zeros(max(x_c),max(y));
        for i = 1:length(x_c)
            try
                    if(z(i)>0)
                        A(int32(x_c(i)), int32(y(i))) = abs(log(z(i)));
                    else
                        % deal with exceptions regarding log(0)
                        A(int32(x_c(i)), int32(y(i))) = 0;
                    end
            catch
                disp('');
            end
        end
        bar3(A);

但是,由于它是离散空间A 中的采样数据,因此输出如下图所示。这在某种程度上具有误导性,因为图中存在“间隙”(对于没有采样数据的坐标,z 值 = 0)。我宁愿将采样数据分配给它们相应的图,从而产生一个“真实的”3d 直方图。

顺便说一句,由于我创建A 的“hack”,x-、y- 和 z 比例也不正确。 3D 直方图的轴(全部三个)应在 [0,1] 的区间内。

ans =

     0         0    0.9459
     0    0.0500    0.0256
     0    0.1000    0.0098
     0    0.1100    0.0004
     0    0.1500    0.0055
     0    0.1600    0.0002
     0    0.2000    0.0034
     0    0.2100    0.0001
     0    0.2500    0.0024
     0    0.2600    0.0001
     0    0.3000    0.0018
     0    0.3200    0.0000
     0    0.3700    0.0000
     0    0.4000    0.0010
     0    0.4200    0.0000
     0    0.4500    0.0007
     0    0.5000    0.0007
     0    0.5300    0.0000
     0    0.5500    0.0005
     0    0.6000    0.0005
     0    0.6300    0.0000
     0    0.7000    0.0002
     0    0.7400         0
     0    0.7500    0.0003
     0    0.7900    0.0000
     0    0.8000    0.0002
     0    0.8400    0.0000
     0    0.8500    0.0002
     0    0.8900    0.0000
     0    0.9000    0.0002
     0    0.9500    0.0001
     0    1.0000    0.0001
0.0500         0    0.0235
0.0500    0.0500    0.0086
0.0500    0.1000    0.0045

     .         .         .
     .         .         .
     .         .         .
     .         .         .
     .         .         .
0.9500    0.9000    0.0035
0.9500    0.9500    0.0066
0.9500    1.0000    0.0180
1.0000         0    0.0001
1.0000    0.0500    0.0001
1.0000    0.1000    0.0001
1.0000    0.1100    0.0000
1.0000    0.1500    0.0001
1.0000    0.1600    0.0000
1.0000    0.2000    0.0001
1.0000    0.2100    0.0000
1.0000    0.2500    0.0001
1.0000    0.2600    0.0000
1.0000    0.3000    0.0001
1.0000    0.3200    0.0000
1.0000    0.3700    0.0000
1.0000    0.4000    0.0002
1.0000    0.4200         0
1.0000    0.4500    0.0002
1.0000    0.5000    0.0003
1.0000    0.5300    0.0000
1.0000    0.5500    0.0004
1.0000    0.6000    0.0004
1.0000    0.6300    0.0000
1.0000    0.7000    0.0007
1.0000    0.7400    0.0000
1.0000    0.7500    0.0010
1.0000    0.7900    0.0000
1.0000    0.8000    0.0015
1.0000    0.8400    0.0001
1.0000    0.8500    0.0024
1.0000    0.8900    0.0002
1.0000    0.9000    0.0042
1.0000    0.9500    0.0111
1.0000    1.0000    0.3998

【问题讨论】:

  • 你为什么不用hist3
  • 这给出了错误的结果。据我所知, hist/hist3 仅适用于实际数据量。在我的例子中,第三列包含数据量的总和(另外是标准化的)。

标签: matlab 3d histogram sample-data


【解决方案1】:

我通过处理非聚合数据找到了解决方案。特别是数据集transitions 的每一行都包含XY 的一个观察值。我使用下面的代码生成了一个归一化的 3D 直方图(和一个 2D 地图),如下所示:

function createHistogram(transitions)
   uniqueValues = unique(transitions(:,1));
   biases = cell(numel(uniqueValues),1);

   for i = 1:numel(uniqueValues)
       start = min(find(transitions(:,1) == uniqueValues(i)));
       stop = max(find(transitions(:,1) == uniqueValues(i)));
       biases(i) = mat2cell(transitions(start:stop,2));
   end

   combinedBiases = padcat(biases{1},biases{2},biases{3},biases{4},...
       biases{5},biases{6},biases{7},biases{8},biases{9},biases{10},...
       biases{11},biases{12},biases{13},biases{14},biases{15},biases{16},...
       biases{17},biases{18},biases{19});

   bins = 0:0.1:1;
   [f, x] = hist(combinedBiases, bins);

   %
   % normalize
   %
   for i = 1:numel(f(1,:))
       for j = 1:numel(f(:,i))
            f(j,i) = f(j,i)/numel(biases{i});
       end
   end
   bHandle = bar3(x, f);
   ylim([-0.04,1.04])
   for k = 1:length(bHandle)
        zdata = get(bHandle(k),'ZData');
        set(bHandle(k),'CData',zdata, 'FaceColor','interp');
   end
   colormap('autumn');
   hcol = colorbar();
   axis('square');
   cpos=get(hcol,'Position');
   cpos(4)=cpos(4)/3; % Halve the thickness
   cpos(2)=0.4; % Move it down outside the plot#
   cpos(1)=0.82;
   set(hcol, 'Position',cpos);
   xlabel('Enrollment biases');
   ylabel('Aging biases');
   zlabel('Bias transition probability');
   title(strcat('Probability mass function of bias transitions (', device,')'));
   set(gca,'XTick',0:2:20);
   set(gca,'XTickLabel',0:0.1:1);
   print('-dpng','-r600',strcat('tau_PMF3D_enrollment-ageing-', device));
   view(2);
   cpos(1)=0.84;
   set(hcol, 'Position',cpos);
   print('-dpng','-r600',strcat('tau_PMF2D_enrollment-ageing-', device));
end

【讨论】:

  • 我很抱歉我错过了这个,直到你自己的答案碰到了它,我已经发布了可能是一个更简单的替代方案。然而,自己修复它并花时间分享是件好事
【解决方案2】:

从对问题的评论看来,您有想要表示每个 bin 计数的值。如果是这样,另一种解决方案是使用 hist3 和“垃圾”数据使用正确的 x 和 y 比例进行绘图,然后更新使用 bin 数据创建的表面对象的 zdata(修改为正确的格式)。
这种对 bin 数据的修改相当简单,包括重塑为矩阵,然后复制和填充所有元素,该方法包含在下面的代码中。

基于问题末尾的ans变量,假设

  • ans(:,1) 给出 x 值
  • ans(:,2) 给出 y 值
  • ans(:,3) 给出归一化的 bin 计数

代码

%// Inputs
zdata=ans(:,3);  %// zdata=rand(21*21,1); % for testing
xvalues = 0:0.05:1; 
yvalues = 0:0.05:1;

%// plot with junk data, [0,0] in this case
nx = numel(xvalues); ny = numel(yvalues);    
bincenters = { xvalues , yvalues };
hist3([0,0],bincenters);
Hsurface = get(gca,'children');

%// apply bin count format
pad = [0 0 0 0 0;0 1 1 0 0;0 1 1 0 0;0 0 0 0 0;0 0 0 0 0]; %// padding for each point
ztrans=kron(reshape(zdata,[nx,ny]),pad); %// apply padding to each point

%// update plot
set(Hsurface,'ZData',ztrans)

%// to set colour based on bar height
colormap('autumn');
set(Hsurface,'CData',ztrans,'FaceColor','interp')

输出

【讨论】:

    猜你喜欢
    • 2013-02-06
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 2011-12-02
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多