3D point clouds with variable marker transparency, color and size
33 views (last 30 days)
Show older comments
I would like to make 3D point clouds in which the markers have variable color, transparency and/or marker size. I would like to do this in one function call, because it seems like Matlab can have some strange occlusion issues if multiple point-clouds are combined via a loop and the viewpoint is changed.
I have tried using the hidden MarkerHandle settings as described here and it works brilliantly with the exception that transparency is only binary for markers of the '.' type (i.e. the only alpha value that affects the graph is 0, in which case the point is un-rendered), unless the marker size is > 15, in which it seems that a different openGL primitive may be used. To get small points with variable transparency one can use e.g. 'o', and set EdgeColorType/Binding/Data and FaceColorType/Binding/Data appropriately.
In both cases, however, if the number of points >25,000 then rotating, zooming or scaling the figure resets the marker handles on-the-fly which makes it impossible to interact with the point cloud while maintaining the custom markerhandle settings.
Variable markersize could function as an alternative to transparency but I don't see how to do that with a single function call, and in any case the marker handle resetting still causes problems for interactive data exploration for large point clouds. Any pointers on how to accomplish this?
5 Comments
Adam Danz
on 24 Dec 2019
The layering of colors in the first of your demos above is to be expected. You're plotting the data in layers within a loop and at a very high density. The chances of a point at (x,y,z) overlapping another point at (x0,y0,z0) is very high and since each iteration has it's own color, you're seeing the layers of color change as you change the viewing angle. That's not surprising.
The second and third demo above use undocumented features so I didn't dig too deeply into them.
Answers (3)
Yair Altman
on 3 Jan 2020
As an alternative to scatter3, you could keep using plot3 and attach a callback function to the axes that gets invoked whenever the axes is repainted. In this callback function you could reattach the transparency to the ploted points (don't replot - just update the plotted handles' color property/ies). You can attach such a callback in several maners:
- The zoom, pan, and rotate3d functions enable setting a callback function that gets invoked whenever they are used. This is fully-documented functionality, but requires you to set the callback seperately in several places.
- You can attach the callback to the axes' MarkedClean event, as explained on http://undocumentedmatlab.com/articles/undocumented-hg2-graphics-events
I'm not claiming that this is a better alternative than scatter3, but in cases where you wish to avoid scatter3 (for example, if performance is problematic), then it might be worth checking.
Adam Danz
on 24 Dec 2019
"I would like to make 3D point clouds in which the markers have variable color, transparency and/or marker size. "
I suggest using scatter3() where marker size and marker color can be set for each individual point. Here's a demo that creates a 3D volume of 30k points with varying colors and marker sizes that are defined by the depth of each point along the z-axis. The transparency of all points are set to 0.5.
% Create data (30k 3D points)
n = 30000;
x = rand(1,n)*100;
y = rand(1,n)*100;
z = rand(1,n)*100;
% Define color of each point based on z value
colors = jet(numel(z));
[~, ~, depthIdx] = unique(abs(z));
colorData = colors(depthIdx,:);
% Define size gradient based on z value
dotSize = linspace(10,100,numel(x));
sizeData = dotSize(depthIdx);
% Plot 3D points
scatter3(x,y,z,sizeData,colorData,'filled','o','MarkerEdgeColor','k', ...
'MarkerFaceAlpha',0.5);
grid on
box on
xlabel('x')
ylabel('y')
zlabel('z')
% Choose your viewing angle:
view(0,180) % (x,z) view
view(2) % (x,y) view
view(3) % (x,y,z) view
2 Comments
Adam Danz
on 24 Dec 2019
You can use '.' markers as shown below but you'll want to increase the range of the marker sizes.
% Define size gradient based on z value
dotSize = linspace(10,1000,numel(x));
sizeData = dotSize(depthIdx);
% Plot 3D points
scatter3(x,y,z,sizeData,colorData,'.','MarkerFaceAlpha',0.5);
And yes, it does take some time to render 1-million points with varying colors and sizes but it also solves your problem.
Tim
on 24 Dec 2019
4 Comments
Adam Danz
on 28 Dec 2019
My first two thoughts are
1) use axis equal to equate the aspect ratio across all 3 axes. It seems like that's already being done in the OpenGL version.
2) zoom out a bit by setting the xlim(), ylim(), zlim() so the axis background appears. That's already being done in the OpenGL version, too. It will increase the concentration of the dots.
Here's more info on rendering in Matlab
See Also
Categories
Find more on Graphics Performance in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!