MATLAB - updating plot in gui?

pedro silva picture pedro silva · Jul 9, 2012 · Viewed 18.3k times · Source

Getting started with matlab guide, hit a stumbling block. Got it as simple as I can as a toy gui to illustrate my problem. A gui (named asas) has a pushbutton and an axis. The callback of the button reads

axesHandle= findobj(gcf,'Tag','axes1');
x=rand(randi(10+20,1),4);
plot(axesHandle, x)

There's no other code written by me (guide wrote it).
The 1st time I push the button, everything is fine: the plot gets done. The 2nd time around, I get an error, from the console:

Error using plot
Vectors must be the same lengths.

Error in asas>pushbutton1_Callback (line 83)
plot(axesHandle, x)

Error in gui_mainfcn (line 96)
        feval(varargin{:});
etc...

I want to plot the new data x, replacing the old one.
It looks like matlab is not replacing the data to plot, but somehow trying to append to the plot?

I have searched, but haven't found anything that applies.

Answer

Ole Thomsen Buus picture Ole Thomsen Buus · Jul 9, 2012

The explanation is not straightforward - and certainly not if you are new with MATLAB and its handle graphics subsystem.

Your code as it is, line by line:

axesHandle= findobj(gcf,'Tag','axes1');
x=rand(randi(10+20,1),4);
plot(axesHandle, x);

The first line attempts to locate in the current figure (gcf, "get current figure") any child object with the property 'Tag' set to the string 'axes1'. I guess you are aware of this? The second line of course generates some random data to plot. The third line plots the data in x.

But after the plot-call the property 'Tag' is actually reset to '' (the empty string), which in turn makes findobj fail in any subsequent searches for the axes-handle. The variable axesHandle with therefore NOT contain an actual handle but instead the empty matrix []. This will make plot default to another mode an interpret the empty matrix as data for the x-axes (the first argument to plot). This expectedly results in the error you receive:

...
Error using plot Vectors must be the same lengths.
...

The solution by Dan in the comment above is a workaround, but there is good sense in telling plot where to plot - especially in GUIs.

You can instead add a fourth line:

set(axesHandle,'Tag','axes1');

This will set property 'Tag' back to 'axes1' and any subsequent clicks on the button should now also work. And you can add more than one axes-objects now. If that is what you want to.