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;