Matlab GUI using GUIDE : Want to dynamically update graphs

c0d3rz picture c0d3rz · Jan 6, 2012 · Viewed 28.9k times · Source

I've written a Matlab script that reads in data using a virtual COMM port in real-time. I've done a significant amount of signal processing in an mfile.

Next, I felt the need to have a compact GUI that displays the information as summary.

I only recently started digging and reading more of Matlab's built-in GUI tool, GUIDE. I've followed a few tutorials and am successfully able to get my graphs to display on my GUI after a button-press.

However, I want the GUI to update in real-time. My data vector is constantly updating (reading in data from the COMM port). I want the GUI to keep updating the graphs with the newer data, as opposed to relying on a button press for an update. Can someone please point me in the right direction for background updating?

Here is the relevant code currently for the GUI:

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global data
global time

% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);

EDIT Changed code:

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%Setting it to display something when it ends
% t = timer('TimerFcn', 'timerOn=false; disp(''Updating GUI!'')',... 
t = timer(... 
            'TasksToExecute', 10, ... % Number of times to run the timer object
            'Period', 3, ...                
            'TimerFcn', GUIUpdate()); 

%Starting the timer
start(t)

function GUIUpdate()
global data
global time
%Parameters below axes
    global min
    global max 
      % Time domain plot
    axes(handles.timeDomainPlot);
    cla;
    plot (time, data);
    %Other parameters:
    set(handles.mean, 'String', mean);
    set(handles.max, 'String', max);

The error that I get is:

??? Error using ==> GUI_Learning>GUIUpdate
Too many output arguments.

Error in ==>
@(hObject,eventdata)GUI_Learning('pushbutton1_Callback',hObject,eventdata,guidata(hObject))


??? Error while evaluating uicontrol Callback

Answer

Aero Engy picture Aero Engy · Jan 8, 2012

Here is an example using a timer with a timerFcn callback. I made a simple GUI with 1 axes and 1 button.

In the opening function I initialize the plot and create the timer. In the start button callback I start the timer and start manipulating the data. The timer function callback the just updates the y-data of the line via its handle. Below are the relevant functions from the GUI's M-file (snipped init section and output fcn.

function testTimer_OpeningFcn(hObject, eventdata, handles, varargin)
global y x
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
handles.plot = plot(handles.axes1,x,y);
handles.timer = timer('ExecutionMode','fixedRate',...
                    'Period', 0.5,...
                    'TimerFcn', {@GUIUpdate,handles});
handles.output = hObject;
guidata(hObject, handles);

% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
global y x
start(handles.timer)
for i =1:30
   y = sin(x+i/10); 
   pause(1) 
end

function GUIUpdate(obj,event,handles)
global y 
set(handles.plot,'ydata',y);

You may want a Stop button to stop the timer depending on how your GUI is structured and were/how the data is updated.

Edit: Basic handles info some of this is pretty basic and you may already know it:

An individual handle to an object contains a bunch of properties that you can read with the get() function or set with the set() function. So for example maybe I wanted to change the text of the startButton for some reason in my GUI.

set(handles.startButton,'String','Something Other Than Start');

You may just want to set a break point in your code somewhere (maybe in a button press) and play around with the handles struct. Running get() commands on various objects to learn their properties.

Now the handles structure contains all of the ... umm... handles to your GUI's objects as well as any custom items that may be convenient for your to store there. Most GUI callbacks automatically get passed the handles struct so you have easy access to all parts of the GUI.

Ex. The 'startButton' callback was automatically passed handles. So I had easy access to the timer object via handles.timer.

Which brings me to sticking custom things into handles. In the opening function I added a new item to the handles structure handles.timer and handles.plot because I knew they would be useful in other callbacks (like button press and the timerFcn callback).

However, to store these things permanently you need to use the 'guidata' function. This function basically either stores the modified handles struct or retrieves a copy of handles depending on how you call it. So the following line in the opening function is storing the modified handles structure (added .timer and .plot) into the main GUI.

guidata(hObject,handles);

Basically any time you add something in handles you should have that line to make the change permanent.

Now the other method of calling it is:

handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI.

This will retrieve the handles structure for the GUI.

And last handles.output = hObject is just the default output when you launch your GUI. IF you call your GUI via Matlab's command line like this h = myGUI; it should return the handle to your GUI.