Matlab 如何使用给定数据绘制三维数密度散点图?
我有一个立方体盒子,每个方向都有300个。我有一些数据(包含X,Y,Z坐标),它们代表了这个框中近100万个数据点的分布。我想为它们的数字密度指定一种颜色(这是一个密集的数量,用于描述可数对象在本例中的数据点的集中程度)。换句话说,使用颜色来说明哪个部分在数据点方面比其他部分更精简。最终图像中颜色栏的索引应表示使用该颜色指定的数据点的百分比 我试着将立方体盒子中的整个空间分割成100万个小立方体(每个立方体在所有方向上都有3个长度)。通过计算这些立方体中粒子的数量,我将知道它们在盒子中的分布情况以及其中存在的数据点的数量。然后我可以为它们指定一种我在计数和指定时没有成功的颜色。如有任何建议,我们将不胜感激Matlab 如何使用给定数据绘制三维数密度散点图?,matlab,plot,matlab-figure,Matlab,Plot,Matlab Figure,我有一个立方体盒子,每个方向都有300个。我有一些数据(包含X,Y,Z坐标),它们代表了这个框中近100万个数据点的分布。我想为它们的数字密度指定一种颜色(这是一个密集的数量,用于描述可数对象在本例中的数据点的集中程度)。换句话说,使用颜色来说明哪个部分在数据点方面比其他部分更精简。最终图像中颜色栏的索引应表示使用该颜色指定的数据点的百分比 我试着将立方体盒子中的整个空间分割成100万个小立方体(每个立方体在所有方向上都有3个长度)。通过计算这些立方体中粒子的数量,我将知道它们在盒子中的分布情况
%reading the files
[FileName,PathName,FilterIndex] = uigetfile('H:\*.txt','MultiSelect','on');
numfiles = size(FileName,2);%('C:\final1.txt');
j=1;
X=linspace(0,300,100);
for ii = 1:numfiles
FileName{ii}
entirefile = fullfile(PathName,FileName{ii});
a = importdata(entirefile);
x = a(:,2);
y = a(:,3);
z = a(:,4);
%% I DON'T KNOW HOW TO CREAT THIS LOOP TO COUNT FOR THE NUMBER OF PARTICLES WITHIN EACH DEFINED CUBE %%
for jj = 2:size(X,2)
%for kk=1:m
if x(:)<X(jj) & y(:)<X(jj) & z(:)<X(jj)
x;
end
%end
end
h=figure(j);
scatter3(x, y, z, 'filled', 'MarkerSize', 20);
cb = colorbar();
cb.Label.String = 'Probability density estimate';
end
%正在读取文件
[FileName,PathName,FilterIndex]=uigetfile('H:\*.txt','MultiSelect','on');
numfiles=大小(文件名,2);%('C:\final1.txt');
j=1;
X=linspace(0300100);
对于ii=1:numfiles
文件名{ii}
entirefile=fullfile(路径名,文件名{ii});
a=导入数据(完整);
x=a(:,2);
y=a(:,3);
z=a(:,4);
%%我不知道如何创建此循环来计算每个已定义立方体%%内的粒子数
对于jj=2:尺寸(X,2)
%对于kk=1:m
如果x(:)这里有一种计算点云三维密度的方法。尽管我对您提供的示例数据感到震惊,但与您的示例图像相比,它并没有产生相同的3D分布
为了计算密度,该方法分为几个步骤:
- 计算
[X,Y]
平面中的二维密度:计算每个(X,Y)
箱子中放置的点数。然而,在这个阶段,这个点数包含了给定箱子的所有Z
列
- 对于每个非空的
(x,y)
bin,计算沿Z
列的分布。现在,我们有了每个(x,y,z)
箱子中落下的点数。计算密度/百分比只需将每个计数除以总点数即可
- 现在,对于每个非空的
(x,y,z)
箱,我们确定属于该箱的点的线性指数。然后,我们将bin值(颜色、百分比或与此bin关联的任何值)分配给所有已识别的点
- 显示结果
在代码中,它是这样的:
%% Import sample data
entirefile = '1565015520323.txt' ;
a = importdata(entirefile);
x = a(:,1);
y = a(:,2);
z = a(:,3);
npt = numel(x) ; % Total Number of Points
%% Define domain and grid parameters
nbins = 100 ;
maxDim = 300 ;
binEdges = linspace(0,maxDim,nbins+1) ;
%% Count density
% we start counting density along in the [X,Y] plane (Z axis aglomerated)
[Nz,binEdges,~,binX,binY] = histcounts2(y,x,binEdges,binEdges) ;
% preallocate 3D containers
N3d = zeros(nbins,nbins,nbins) ; % 3D matrix containing the counts
Npc = zeros(nbins,nbins,nbins) ; % 3D matrix containing the percentages
colorpc = zeros(npt,1) ; % 1D vector containing the percentages
% we do not want to loop on every block of the domain because:
% - depending on the grid size there can be many
% - a large number of them can be empty
% So we first find the [X,Y] blocks which are not empty, we'll only loop on
% these blocks.
validbins = find(Nz) ; % find the indices of non-empty blocks
[xbins,ybins] = ind2sub([nbins,nbins],validbins) ; % convert linear indices to 2d indices
nv = numel(xbins) ; % number of block to process
% Now for each [X,Y] block, we get the distribution over a [Z] column and
% assign the results to the full 3D matrices
for k=1:nv
% this block coordinates
xbin = xbins(k) ;
ybin = ybins(k) ;
% find linear indices of the `x` and `y` values which are located into this block
idx = find( binX==xbin & binY==ybin ) ;
% make a subset with the corresponding 'z' value
subZ = z(idx) ;
% find the distribution and assign to 3D matrices
[Nz,~,zbins] = histcounts( subZ , binEdges ) ;
N3d(xbin,ybin,:) = Nz ; % total counts for this block
Npc(xbin,ybin,:) = Nz ./ npt ; % density % for this block
% Now we have to assign this value (color or percentage) to all the points
% which were found in the blocks
vzbins = find(Nz) ;
for kz=1:numel(vzbins)
thisColorpc = Nz(vzbins(kz)) ./ npt * 100 ;
idz = find( zbins==vzbins(kz) ) ;
idx3d = idx(idz) ;
colorpc(idx3d) = thisColorpc ;
end
end
assert( sum(sum(sum(N3d))) == npt ) % double check we counted everything
%% Display final result
h=figure;
hs=scatter3(x, y, z, 3 , colorpc ,'filled' );
xlabel('X'),ylabel('Y'),zlabel('Z')
cb = colorbar ;
cb.Label.String = 'Probability density estimate';
正如我在开始时所说,结果与示例图像略有不同。此样本集产生以下分布:
如果需要一种“双重检查”结果是否为垃圾的方法,可以查看每个轴上的二维密度结果,并检查其是否与点的外观分布相匹配:
%% Verify on 3 axis:
Nz = histcounts2(y,x,binEdges,binEdges) ./ npt *100 ;
Nx = histcounts2(z,y,binEdges,binEdges) ./ npt *100 ;
Ny = histcounts2(x,z,binEdges,binEdges) ./ npt *100 ;
figure
ax1=subplot(1,3,1) ; bz = plotDensity(Nz,ax1) ; xlabel('X'),ylabel('Y') ;
ax2=subplot(1,3,2) ; bx = plotDensity(Nx,ax2) ; xlabel('Y'),ylabel('Z') ;
ax3=subplot(1,3,3) ; by = plotDensity(Ny,ax3) ; xlabel('Z'),ylabel('X') ;
单击图像以查看更大的图像:
plotDensity.m的代码
:
function hp = plotDensity(Ndist,hax)
if nargin<2 ; hax = axes ; end
hp = bar3(Ndist,'Parent',hax) ;
for k = 1:length(hp)
zdata = hp(k).ZData;
hp(k).CData = zdata;
hp(k).FaceColor = 'interp';
end
shading interp
函数hp=plotDensity(Ndist,hax)
如果narginI建议您创建一个每个人都可以复制的小型可行样本数据集。人们无法处理他们无权访问的数据集@谢谢你。我已添加到采样数据的链接。@Mehdi。如果您想要点的数量而不是它们的密度%,那么只需替换以下行:thiscorrorpc=Nz(vzbins(kz))./npt*100代码>通过更简单的thiscorrorpc=Nz(vzbins(kz))代码>。(并明显更改颜色栏的标题)感谢您的明确解释。非常感谢