Matlab 无插值网格化散乱数据

Matlab 无插值网格化散乱数据,matlab,matrix,multidimensional-array,indexing,vectorization,Matlab,Matrix,Multidimensional Array,Indexing,Vectorization,我有三个向量,X、Y和Z,它们表示在矩阵V中找到的一些数据的三维坐标(即V=f(X,Y,Z))。以下是该数据的一些特征(假设/断言,如果您愿意): X和Y的长度相同,通常不同于Z numel(X) == numel(Y); X中唯一元素的数量通常不同于Y中唯一元素的数量 Z中的所有值都是唯一的 numel(unique(Z)) == numel(Z); V的大小为[numel(X),numel(Z)] 在过去,我没有区分X和Y,我使用一个索引来引用它们,这使得绘制一个轴上有“XY组合

我有三个向量,
X
Y
Z
,它们表示在矩阵
V
中找到的一些数据的三维坐标(即
V=f(X,Y,Z)
)。以下是该数据的一些特征(假设/断言,如果您愿意):

  • X
    Y
    的长度相同,通常不同于
    Z

    numel(X) == numel(Y);
    
  • X
    中唯一元素的数量通常不同于
    Y
    中唯一元素的数量

  • Z
    中的所有值都是唯一的

    numel(unique(Z)) == numel(Z);
    
  • V
    的大小为
    [numel(X),numel(Z)]

在过去,我没有区分
X
Y
,我使用一个索引来引用它们,这使得绘制一个轴上有“XY组合数”(即
1:numel(X)
)而另一个轴上有
Z
)的图表变得很容易,因此
V
的大小非常合适

目前,我想分别看到
X
Y
的效果,这就是为什么我想在3d中使用和的混合体来可视化它

分散部分很容易,因为我可以沿着它们的单态维度
numel(Z)
时间
repmat
X
Y
,对于
Z
(使用
numel(X)
)也是如此。这导致:

至于等高线,这些需要以3d阵列的形式提供数据——这意味着我必须将点放置在结构化网格中。使用
meshgrid
可以直接创建网格坐标
XX
YY
ZZ

[ XX, YY, ZZ ] = meshgrid( unique(X), unique(Y), unique(Z) );
我正在努力创建3d阵列
VV

从上图中我们可以看到,该卷的大部分不包含点-我非常希望保持这种方式。换句话说,理想的
VV
应仅包含与原始数据集对应的点,其余空间应包含
NaN
s

函数类似于并执行插值,这将“填充”点云内部的孔,这是非常不希望的。我认为可以在这里使用索引来使用
V
中的值填充
VV
,但我想不出一种方法

我的问题是:如何生成不包含任何插值数据的
VV

下面是一个简单的例子:

%% Generate some data:
X = randi(10,100,1);
Y = randi(15,100,1) - 5;
Z = 1:50;
V = X./Y.*Z;

%% Scatter plot:
nXY = numel(X); nZ = numel(Z);
figure();
scatter3( reshape( repmat(X,[1, nZ]),  [], 1), ...
          reshape( repmat(Y,[1, nZ]),  [], 1), ...
          reshape( repmat(Z,[nXY, 1]), [], 1), ...
          [], V(:), '.');

%% Contours:
% Create the 3d grid:
[XX, YY, ZZ] = meshgrid( unique(X), unique(Y), unique(Z) );

% Preallocate VV:
VV = NaN(size(XX));

% Populate VV: <--------------------------------------------- Help needed with this stage
ind = randperm( numel(XX), numel(V) ); % PLACEHOLDER 
VV(ind) = V;

% Plot:
hold on; contourslice(XX, YY, ZZ, VV, X(2), Y(3), Z(10) );
%%生成一些数据:
X=randi(10100,1);
Y=randi(15100,1)-5;
Z=1:50;
V=X./Y*Z;
%%散点图:
nXY=numel(X);nZ=努美尔(Z);
图();
散射3(重塑(repmat(X,[1,nZ]),[],1)。。。
重塑(repmat(Y,[1,nZ]),[],1)。。。
重塑(repmat(Z,[nXY,1]),[],1)。。。
[],V(:),'。);
%%轮廓:
%创建三维网格:
[XX,YY,ZZ]=meshgrid(唯一(X),唯一(Y),唯一(Z));
%预分配VV:
VV=NaN(尺寸(XX));

%填充VV:我相信,通过将所有网格索引与所有线性数据点进行匹配,可能会有一种杀伤力过大的方法。为此,我们需要注入一些维度,以便将3d阵列
XX
etc与2d阵列
X
etc元素进行比较:

Xbc = reshape(X, [1,1,1,size(X)]);
Ybc = reshape(Y, [1,1,1,size(Y)]);
Zbc = reshape(Z, [1,1,1,size(Z)]);
对这些阵列进行重塑,使其与大小为
[N,M,K]
(“bc”代表广播)的阵列
XX
等一起广播。因此,元素比较现在起作用了:

match = reshape((XX == Xbc) & (YY == Ybc) & (ZZ == Zbc), [size(XX), numel(V)]);
如果
V
是大小
[p,Q]
,则此逻辑数组具有大小
[N,M,K,p,Q]
。它包含的
true
s数量与您想要的数量完全相同:

>> sum(match(:)) == numel(V)

ans =

  logical

   1
因此,现在我们需要沿着前三个维度选择相应的索引,并将它们与
V
的正确元素配对。我们需要一些线性到多指数弯头润滑脂:

[ii,jj,kk,ll] = ind2sub(size(match), find(match));
现在,左侧的所有阵列都是大小
[numel(V),1]
;前三个将索引分为
XX
等,最后一个将索引分为
V

V_inds = ll;
VV_inds = sub2ind(size(VV), ii, jj, kk);

VV(VV_inds) = V(V_inds);
现在,由于某种原因,我在结果中只看到5000个独特指数中的3750个:

>> numel(VV_inds)           

ans =

        5000

>> numel(unique(VV_inds))

ans =

        3750
我似乎找不到任何其他原因来解释这一点,除了由于
X
Y
的值重复,您的一些原始数据点会重叠,因此您实际上无法在唯一点的三维网格中表示它们(因为一些三维点包含多个数据点)。我相信以下事实证明了这一点:

>> size(unique([X,Y], 'rows'))

ans =

    75     2

>> size([X,Y])

ans =

   100     2
有100个
(x,y)
对,但只有75个唯一的对。无论您如何将这些与正交
z
点集组合,最终都会在点中重复。因此,您要么必须剔除原始数据中的冗余,要么需要找到另一种表示法(或取冲突值的平均值)


我想我也得到了一个更有效的版本,在运行期间使用
unique
生成的索引。请注意,我将假设您使用
meshgrid
而不是
ndgrid
来生成网格,以便生成的数组(以及
VV
)的尺寸分别对应于
X
Y
Z
上的唯一尺寸

% take the indices
[uX, ~, iX] = unique(X);
[uY, ~, iY] = unique(Y);
[uZ, ~, iZ] = unique(Z);

% generate mesh and allocate result
[XX, YY, ZZ] = ndgrid(uX, uY, uZ);
VV = NaN(size(XX));

% switch from `iX`, `iY` and `iZ` to a 2d mesh of size `[P,Q]` where `iX` and `iY` are of size `[P,1]` and `iZ` is of size `[Q,1`]:
% a.k.a. lazy repmat
iXbig = iX + 0*iZ.';
iYbig = iY + 0*iZ.';
iZbig = iZ.' + 0*iX;

% turn 3d indices into linear index into VV
VV_inds = sub2ind(size(VV), iXbig, iYbig, iZbig);

% profit
VV(VV_inds) = V;