Color code points of 3D scatter plot according to

2019-05-23 16:07发布

I have a 3D scatter plot of points in the xyz-sphere. I was wondering if there is a way to colormap/hue the scatter plot based on the density of the data. Basically, the parts of the scatter plot with the most densely clustered data points would be dark red, semi densely clustered data points would be medium red, and sparsely clustered data points would be light red.

This is the way that I was thinking of, but (hopefully) there might be a simpler function or command to do this.

Set a threshold that a data point in the scatter has to be surrounded by:

[ >= 10 other points within a sphere of radius 1 to be colored dark red,

[ 5-9 other points within a sphere of radius 1 to be colored medium red, and

[ 0-4 within a sphere of radius 1 to be colored light red.

Of course, I'm hoping there is a simpler way to do this that involves more than 3 colors in the color map, so if anyone has any ideas how to code this, I'd appreciate the help! Thank you so much.

Here's a snippet of my array:

184    115   3915
185    115   3916
185    115   1205
186    115   4094
187    115   2237
192    115   1519
193    115   1327
201    115   1170
240    115   2946
241    115   1332
 54    116   1244
 58    116   3650
 59    116   3984
 60    116   1631
 61    116   1198
 61    116   1194
 62    116   1189
 65    116   1185
186    116   3669
188    116   3986
189    116   2027
197    116   1200
201    116   1254
226    116   3752
227    116   1457
242    116   1405
 54    117   1191
 54    117   1305
 56    117   1177
 58    117   1169
 61    117   1367
 62    117   1428
 62    117   1434
 62    117   1435
 63    117   1422
198    117   1197
229    117   1312
230    117   1179
243    117   1272
 55    118   1236
 56    118   1166
 61    118   1191
 65    118   1755
 57    119   1213
 57    119   1176
 58    119   1253
 62    119   1365
 62    119   1331
 63    119   1457
 63    119   1251
 66    119   1842
 66    119   1468
 59    120   1489
 59    120   1387
 60    120   1218
 60    120   1224
 61    120   1214
 61    120   1440
 62    120   1198
 64    120   1240
205    120   3601
205    120   1168
206    120   3727
207    120   4089
208    120   2128
208    120   1160
 56    121   1293
 57    121   1183
 59    121   1371
 59    121   1347
 61    121   1314
 64    121   1346
207    121   3562
208    121   3845
209    121   3534
210    121   1201
210    121   1405
 83    122   1794
206    122   1259
207    122   1161
 83    123   3550

2条回答
时光不老,我们不散
2楼-- · 2019-05-23 16:15

In my approach I'm using a threshold factor T to determine how many other points are considered in the calculation of distances for each individual point. T = 1 means for every point the average distance to all other points is calculated, T = 0.01 means for every point the average distance to the closest 1% of the the other points is calculated.

figure

%// example data
[X,Y,Z] = sphere(15);
x = [0.1*X(:); 0.4*X(:); 0.7*X(:)];
y = [0.2*Y(:); 0.5*Y(:); 0.8*Y(:)];
z = [0.3*Z(:); 0.6*Z(:); 0.9*Z(:)];
D = [x(:), y(:), z(:)];
N = numel(x);

%// calculation of color vector
[n,m] = ndgrid(1:N,1:N);
%// euclidian distance of each point to every other point
X = arrayfun(@(a,b) sum( (D(a,:) - D(b,:)).^2 ), n, m);

%% subplot 1
%// threshold factor
T = 0.01;

%// sort distances of points
Y = sort(X,2);
%// calculate average distance of the closest T% of all points
Z = mean(Y(:,2:ceil(N*T)),2);

%// plot
subplot(121)
scatter3(x,y,z,20,Z,'filled');
title('T = 0.01')
colormap
colorbar

%% subplot 2
%// threshold factor
T = 1;

Y = sort(X,2);
Z = mean(Y(:,2:ceil(N*T)),2);

%// plot
subplot(122)
scatter3(x,y,z,20,Z,'filled');
title('T = 1')
colormap
colorbar

enter image description here

查看更多
成全新的幸福
3楼-- · 2019-05-23 16:31

This is a pretty crude function, but I think it achieves a similar result to what you want.

  1. Loop through each point, calculate the number of points within some tolerance distance.
  2. Plot these points, using the count of nearby points as a scaling for the colour.

Code:

a = rand(1000,3);       % Create random matrix, use your data here
n = zeros(size(a,1),1); % Set up array for number of nearby points
tol = 0.2;              % Tolerance for (squared) distance to count as "nearby" 
sz = size(a,1);         % Shorthand for size of data
% Loop over every point
for ii = 1:sz;
    dists = sum((repmat(a(ii,:), sz, 1) - a).^2, 2); % Get standard Euclidean distance 
    n(ii) = nnz(dists < tol); % Count number of points within tolerance
end
% Plot, colouring by an nx3 RGB array, in this case just 
% scaling the red and having no green or blue.
scatter3(a(:,1), a(:,2), a(:,3), [], [n./max(n), zeros(numel(n),2)], 'filled');
grid on;

Output:

plot

查看更多
登录 后发表回答