Why is scatter so slow for variable marker size?

3 views (last 30 days)
Theo
Theo on 17 May 2019
Edited: dpb on 18 May 2019
I found something very strange and annoying. The following code generates 1000 points randomly in the plane, then moves them a bit at each timestep and plots the scatterplot as the system evolves.
% Test scatter plot times
clear
close all
% Fill [0, 1] x [0, 1] with points
rng(1); x = rand(1, 1000);
rng(2); y = rand(1, 1000);
rng(3); cz = rand(1, 1000)*50;
h = scatter(x, y, cz, 'filled', 'MarkerFaceColor', [0,0,0]);
% Replace line below to see speedup
% h = scatter(x, y, 50*ones(size(x)), 'filled', 'MarkerFaceColor', [0,0,0]);
xlim([0, 2]);
ylim([0, 2]);
dt = 0.01;
tic
for j = 1:10
x = x + dt;
y = y + dt;
set(h, 'XData', x, 'YData', y);
drawnow
end
toc
The key is that each scatter point has been given a certain size, specified by the vector cz. The for-loop takes:
Elapsed time is 5.160464 seconds.
However, if cz is replaced with a fixed vector of entries that are all 50, then the speedup is more than a factor of 10.
Elapsed time is 0.336361 seconds.
Increasing the number of points to 5000 drives the difference even further, with one run taking about 30 seconds and the other taking 1 second.
I'm wondering if there is an inefficiency or has Matlab really detected that the vector is entirely constant and uses a special routine to plot?
  7 Comments
dpb
dpb on 17 May 2019
Edited: dpb on 18 May 2019
" why the drawing takes so long for scatter plots of different marker sizes"
I'm guessing it's not really the drawing that's the culprit given the time results with scatter directly, but somehow related to internal data storage between the variable-sized markers and the constant since the majority of the time issue is clearly with the use of set as opposed to just redrawing the plot from scratch.
For a workaround, I'd suggest just foregoing the set route in favor of calling scatter directly. Try something like
h = scatter(x, y, cz, 'filled', 'MarkerFaceColor', [0,0,0]);
for j = 1:10
x = x + dt; y = y + dt;
delete(h)
h = scatter(x, y, cz, 'filled', 'MarkerFaceColor', [0,0,0]);
end
You may have some more bookkeeping to do to keep limits and all and maybe set hold on will be helpful.
NB: I've not tried to create the simulation this way so above is "air code", just general way that I'd try to find a workaround.
Give it the weekend and a couple days and see if by any chance anybody from TMW stumbles by or somebody else has more intimate knowledge of scatter and HG2 and can shed some light--if not, seems like worthy of a "quality of implementation" support request.

Sign in to comment.

Answers (0)

Community Treasure Hunt

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

Start Hunting!