3

I want to update a plot with multiple data lines/curves as fast as possible. I have seen some method for updating the plot like using:

h = plot(x,y);
set(h,'YDataSource','y')
set(h,'XDataSource','x')
refreshdata(h,'caller');

or

set(h,'XData',x,'YData',y);

For a single curve it works great, however I want to update not only one but multiple data curves. How can I do this?

Ander Biguri
  • 35,140
  • 11
  • 74
  • 120
BL_
  • 821
  • 1
  • 17
  • 23
  • 2
    Have you tried setting `x` to be a `Nx2` matrix? – Ander Biguri Mar 22 '16 at 12:58
  • You can use the `drawnow` function. – obchardon Mar 22 '16 at 13:15
  • Thanks for the reply @Ander Biguri. I tried the following code but it seems like it only allows a vector, not a 2D array. `x(:,1) = (1:10); x(:,2) = (1:10); y(:,1) = 2*x(:,1); y(:,2) = 5*x(:,2); h = plot(x,y); % give x,y new data. set(d1,'XData',x,'YData',y); Error using ==> set. Value must be a column or row vector .` – BL_ Mar 22 '16 at 13:22
  • Thank @obchardon. I used `drawnow`, but it's still kind of slow. I want to have a faster updating :d – BL_ Mar 22 '16 at 13:26
  • @bienle strange, on my computer i update a 1x1000 vector 100 time per second and there is no lag :/ – obchardon Mar 22 '16 at 13:30

2 Answers2

9

If you create multiple plot objects with a single plot command, the handle returned by plot is actually an array of plot objects (one for each plot).

plots = plot(rand(2));
size(plots)

    1   2

Because of this, you cannot simply assign another [2x2] matrix to the XData.

set(plots, 'XData', rand(2))

You could pass a cell array of new XData to the plots via the following syntax. This is only really convenient if you already have your new values in a cell array.

set(plots, {'XData'}, {rand(1,2); rand(1,2)})

The other options is to update each plot object individually with the new values. As far as doing this quickly, there really isn't much of a performance hit by not setting them all at once, because they will not actually be rendered until MATLAB is idle or you explicitly call drawnow.

X = rand(2);
Y = rand(2);

for k = 1:numel(plots)
    set(plots(k), 'XData', X(k,:), 'YData', Y(k,:))
end

% Force the rendering *after* you update all data
drawnow

If you really want to use the XDataSource and YDataSource method that you have shown, you can actually do this, but you would need to specify a unique data source for each plot object.

% Do this when you create the plots
for k = 1:numel(plots)
    set(plots(k), 'XDataSource', sprintf('X(%d,:)', k), ...
                  'YDataSource', sprintf('Y(%d,:)', k))
end

% Now update the plot data
X = rand(2);
Y = rand(2);

refreshdata(plots)
Suever
  • 64,497
  • 14
  • 82
  • 101
1

You can use drawnow:

%Creation of the vectors

x = 1:100;
y = rand(1,100);

%1st plot 
h = plot(x,y);

pause(2);

%update y
y = rand(1,100);
set(h,'YData',y)
%update the plot.
drawnow
obchardon
  • 10,614
  • 1
  • 17
  • 33