How to speed up surf plot for thousands of objects ?

10 views (last 30 days)
I want to plot thousands of objects in 3d using surf plot. My code looks like this
% src is an m x 3 matrix. Each row is the x, y and z coordinate of an object.
[sx, sy, sz] = sphere;
for ii = 1 : length(src)
surf(sx+src(ii,1), sy+src(ii,2), sz+src(ii,3))
end
There are up to 3000 objects that I want to plot and it takes roughly 30 secs to render. I'm wondering if there is any way to speed this up? I tried very naively with parfor, which ended up with nothing at all. I'm also wondering why parfor won't work?

Accepted Answer

Mike Garrity
Mike Garrity on 10 Feb 2015
Actually the number of points in the surface is probably not a major factor here. That's because the default 20x20 is small enough that, on most systems the bottleneck is going to be surface object creation (which scales with # of objects) rather than updating (which scales with the # of points in the surface).
But the best approach is to start with the sort of scaling analysis I described in this blog post .
Here's a code snippet which you can use for measuring this on your system. Just replace my call to surface with whatever you're doing.
sphere_sizes = [10 15 20 30];
object_counts = [30, 55, 100, 177, 300, 550, 1000, 1771, 3000];
results = zeros(length(sphere_sizes),length(object_counts));
for i1=1:length(sphere_sizes)
npts = sphere_sizes(i1);
for i2=1:length(object_counts)
nobj=object_counts(i2);
cla reset
drawnow
src = randn(nobj,3);
[sx,sy,sz] = sphere(npts);
tic
for ii=1:nobj
surface(sx+src(ii,1),sy+src(ii,2),sz+src(ii,3), ...
'EdgeColor','none','FaceColor',rand(1,3))
end
drawnow
dt = toc;
results(i1,i2) = dt;
disp([num2str(dt), ' for ', num2str(nobj), ' pts'])
end
end
cla reset
hold on
for i1=1:size(results,1)
plot(object_counts,results(i1,:), ...
'DisplayName',[num2str(sphere_sizes(i1)), ' points']);
end
legend('show','Location','NorthWest');
set(gca,'YScale','log')
As you can see by running this, there isn't much of a difference until you get past 20.
Now start modifying this to try different settings and see what works well for your situation. You'll notice that in my example, I turned off the edges and use the surface command instead of the surf command.
I often turn off the edges in cases like this because they don't really add a lot to the appearance and they do have a cost per object.
The surface command is more appropriate in this case because it has lower object creation time. The surf command is really designed for creating simple surface plots and it spends quite a bit initializing support for things like data sources.
As for parfor, unfortunately we can't do object creation in parallel yet, so that doesn't help.

More Answers (2)

CY Y
CY Y on 10 Feb 2015
Thanks, guys.
I tried reducing the number of faces and it didn't really make a difference.
Changing the command surf to surface did the trick. It makes my entire script roughly three times faster !

Titus Edelhofer
Titus Edelhofer on 10 Feb 2015
Hi,
parfor won't work, because the figure you plot to is bound to the MATLAB desktop you work on. You can transfer computations to workers using parfor, not display of graphics.
Regarding the question on speed up: you might reduce complexity of each object using e.g. sphere(15) instead of the default 20 segments...
Titus

Categories

Find more on Graphics Performance in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!