0

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

第一列是指第一个观察变量X,第二列是第二个变量Y,第三列是归一化频率。即第一行:观察到的变量对的归一化频率(0,0)为 0.9459。因此的归一化频率之和(0,Y)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 直方图。

假直方图

顺便说一句,由于我创建Ax-、y- 和 z 比例的“hack”结果是不正确的。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
4

2 回答 2

2

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

标准化 3D 直方图

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
于 2014-06-02T09:38:57.930 回答
0

从对问题的评论看来,您拥有要表示每个 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')

输出

在此处输入图像描述

于 2014-06-02T12:03:07.307 回答