live updating edit field when slider value is changing - matlab

I have a slider and a edit field, which are defined as
uicontrol(fig,'Style','Slider','Units','characters','Position',[17.1+f*iwidth 10.5 4 28.6],'Min',0,'Max',1000,'Value',500,'SliderStep', [1/500 , 10/500 ],'Callback','evaluation_callbacks(''results'',guidata(gcbo))','Tag',['slider' int2str(f)]);
uicontrol(fig,'Style','Edit','Enable','inactive','Units','characters','Position',[14+f*iwidth 8.2 9 1.6],'FontSize',10,'String',500,'Tag',['rating' int2str(f)]);
With the following Callback functions:
function evaluation_callbacks(varargin)
% EVALUATION_CALLBACKS Callback functions for the evaluation interface
%
% evaluation_callbacks(fname,varargin) executes the callback function
% fname_callback with various parameters
fname=[varargin{1},'_callback'];
feval(fname,varargin{2:end});
%%%saving the rating results and proceeding to the next experiment or exiting
function results_callback(handles)
% stop audio
clear sound
%getting the ratings for all files
for f=1:handles.nbfile
handles.ratings(handles.expe_order(handles.expe),handles.file_order(f))=get(getfield(handles,['slider' int2str(f)]),'Value');
end
%saving the whole results (to avoid losing data if the program terminates early)
results='';
fid=fopen(handles.resultfile,'w');
for e=1:handles.nbexpe
for f=1:handles.nbfile
fprintf(fid,'%d\n',handles.ratings(e,f));
end
end
fclose(fid);
if handles.expe<handles.nbexpe
handles.expe=handles.expe+1;
% updating title
set(handles.experiment,'String',handles.parameter{handles.expe});
% update evaluation parameters
set(handles.scale90,'String',handles.high{handles.expe});
set(handles.scale10,'String',handles.low{handles.expe});
if handles.expe==handles.nbexpe
pos=get(handles.results,'Position');
pos(1)=pos(1)+2.5;
pos(3)=19;
set(handles.results,'Position',pos,'String','Save and exit');
end
%moving all the sliders back to 50
for f=1:handles.nbfile
shandle=getfield(handles,['slider' int2str(f)]);
set(shandle,'Value',500);
rhandle=getfield(handles,['rating' int2str(f)]);
set(rhandle,'String',500);
end
%randomizing the order of the tested files for the next experiment
handles.file_order=randperm(handles.nbfile);
%testing whether a break is needed before the next experiment
if etime(clock,handles.time) > 20*60
wfig=warndlg(['You have been working for ' int2str(round(etime(clock,handles.time)/60)) 'minutes. It is recommended that you take a break of at least the same duration before starting the next experiment. Click on OK when you are ready.'],'Warning');
uiwait(wfig);
end
handles.time=clock;
% Start next audio sample
play_callback(handles,1)
guidata(gcbf,handles);
else
%exiting
close(gcbf);
end
%%%rounding and displaying the values of the sliders
function slider_callback(handles,f)
shandle=getfield(handles,['slider' int2str(f)]);
set(shandle,'Value',round(get(shandle,'Value')));
rhandle=getfield(handles,['rating' int2str(f)]);
set(rhandle,'String',get(shandle,'Value'));
As it is right now, the edit field value are not live updated if. The value of the edit field are only updated if the slider is moved and the mouse button is released.
I have tried to add a listener to the slider, but I cannot make it work. So far I have followed the following guides/posts without any luck.
http://undocumentedmatlab.com/blog/continuous-slider-callback
and
https://se.mathworks.com/matlabcentral/answers/140706-use-slider-for-live-updating-of-threshold-on-2d-contour-plot
Can anybody help?

Add a listener in the myGUI_OpeningFcn. Note you need to change myGUI to match your GUI script filename.
addlistener(handles.slider1,'ContinuousValueChange',#(hObject,eventdata)myGUI('updateText',hObject,eventdata,guidata(hObject)));
Then, add the following function in your GUI script.
function updateText(hObject, eventdata, handles)
set(handles.text2,'String',get(hObject,'Value'));
guidata(hObject,handles);
More specifically, in your case, you need to add a bunch of listeners:
for i=1:handles.nbfile
addlistener(getfield(handles,['slider' int2str(i)]),'ContinuousValueChange',#(hObject,eventdata)myGUI('updateText',hObject,eventdata,guidata(hObject)));
end
Then add:
function updateText(hObject, eventdata, handles)
f = hObject.Tag(7:end);
set(getfield(handles,['rating' f]),'String',get(hObject,'Value'));
guidata(hObject,handles);
Update
In your GUI script, add listeners in the OpeningFcn (which is the second function automatically generated by Matlab when your GUI was created):
for i=1:handles.nbfile
addlistener(getfield(handles,['slider' int2str(i)]),'ContinuousValueChange',#(hObject,eventdata)myCallBackFileName('updateText',hObject,eventdata,guidata(hObject)));
You will need to change myCallBackFileName to match the filename of your callback script. Then add the updateText function.

Related

Make MATLAB accept KeyPress only once

I am currently trying to write an experiment in MATLAB. As part of it, it should accept and record a key response, either 1 or 0. The problem is that I only need the keys to be recorded at one specific time slot, and to be ignored in the other parts of the experiment. The response has to be recorded along with the time it took to respond, and it should be done once only, the earliest (so that once the user has pressed a key, the program does not record the subsequent ones).
So far, I have attempted numerous ways. These are probably nooby workarounds, but I am not good with object oriented programming.
One option is to use
set(gcf,'KeyPressFcn',#KeyDownListener)
where KeyDownListener is
function KeyUpListener(key_hand, key_obj, starting_time)
toc(starting_time)
key_pressed = key_obj.Key; return; end
However, there are two problems: 1) I am struggling trying to get the value from this function back to the calling script; 2) Once MATLAB reads this set(...) piece of code, it keeps capturing every single key pressed. So, basically, if there are 100 trials (each consisting of, say, 5 stages, of which the keypress should only be accepted at stage 4) in the experiment put in a loop, the set(...) will be ignored at the first run at stages 1-3 before it first appears, but will then be present in all the runs from the second, at every stage, 1-5.
Then I tried to put both the calling script and the called function into another function called from an outer script, so that once the control is returned to that higher level script, I put in another
set(gcf,'KeyPressFcn',#mute)
by which mute function performs no actions whatsoever. This seems to work for problem No 2, but it still does not allow me to obtain the value for the keypress callback, and, as I am using pause(..) to allow the user time for response, it does not interrupt with the first key pressed, it waits for the entire time allocated in the brackets for pause.
Passing variable around:
I recommend using setappdata and getappdata to pass variables around between callbacks of a GUI.
You can also read Share Data Among Callbacks for more informations about this aspect.
Assigning and disabling callbacks:
To disable a callback function, you do not need to re-assign the callback to a function that does nothing, you can simply assign an empty array:
% assign the 'KeyDownListener' function and pass one parameter ('var1') with it
set( h.fig, 'KeyPressFcn',{#KeyDownListener,var1})
% then later when you don't need it anymore:
% Disable the 'KeyPressFcn listener, assign 'empty' to it
set( h.fig, 'KeyPressFcn',[])
Full example:
Below is a minimal GUI which demonstrate how to capture a single key press (and the time), then save the data collected into the appdata space of the application, where they are collected again by a 'display' function (where you could also do whatever you want with the data collected).
code for SingleKeyPressDemo.m:
function h = SingleKeyPressDemo
% create a minimal figure with a button and 2 text fields
h.fig = figure ;
h.btn = uicontrol('Style','Pushbutton','String','Start capture',...
'units','Normalized','Position',[0.1 0.6 0.8 0.3],...
'Callback',#StartKeyCapture) ;
h.txtKey = uicontrol('Style','text','String','Key pressed:',...
'units','Normalized','Position',[0.1 0.4 0.8 0.1]) ;
h.txtTime = uicontrol('Style','text','String','Elapsed time:',...
'units','Normalized','Position',[0.1 0.3 0.8 0.1]) ;
% assign a callback to the KeyRelease event to intercept passing the
% eventdata to the command window
set(h.fig,'KeyReleaseFcn',#KeyReleased)
% initialise appdata variables to hold the captured key and the time
setappdata( h.fig , 'CapturedKey' , [] )
setappdata( h.fig , 'Elapsed_time' , [] )
% save the handle structure
guidata( h.fig , h)
function StartKeyCapture(hobj,~)
h = guidata( hobj ) ; % retrieve the handle structure
StartTime = tic ; % Start a stopwatch
% assigne the callback funtion, passing the stopwatch in parameter
set(h.fig,'KeyPressFcn',{#KeyDownListener,StartTime})
% disable the button until a key is pressed (also makes it loose the
% focus, which is handy otherwise the button keeps the focus and hides
% the 'KeyPressedFcn'
set( h.btn , 'Enable','off')
function KeyDownListener(hobj, key_obj, starting_time)
% Detect key pressed and time elapsed
Elapsed_time = toc(starting_time) ;
key_pressed = key_obj.Key;
h = guidata( hobj ) ; % retrieve the handle structure
setappdata( h.fig , 'CapturedKey' , key_pressed ) ; % save the captured key
setappdata( h.fig , 'Elapsed_time' , Elapsed_time ) ; % save the elapsed time
set(h.fig,'KeyPressFcn',[]) % remove listener so new key press will not trigger execution
set( h.btn , 'Enable','on') % re-enable the button for a new experiment
% (optional) do something after a key was pressed
display_results(h.fig) ;
function display_results(hobj)
h = guidata( hobj ) ; % retrieve the handle structure
% retrieve the saved data
CapturedKey = getappdata( h.fig , 'CapturedKey' ) ;
Elapsed_time = getappdata( h.fig , 'Elapsed_time' ) ;
% update display
set( h.txtKey , 'String', sprintf('Key pressed: %s',CapturedKey) ) ;
set( h.txtTime , 'String', sprintf('Elapsed time: %f ms',Elapsed_time) ) ;
function KeyReleased(~,~)
% do nothing
% The only purpose of this function is to intercept the KeyReleased event
% so it won't be automatically passed on to the command window.
Creating GUI programmatically is full of verbose in Matlab, focus on the code in the 2 functions StartKeyCapture and KeyDownListener to achieve what you were asking.
This example will produce the following GUI:
Additional note:
I would also recommend against the use of gcf in a GUI application. It is a handy shortcut when debugging or working in the console with figures opened around, but in a GUI the calls to its own elements should be as self-contained as possible. MATLAB offers way to save the handles of all your GUI elements (all the uicontrols, including the main figure), so you can call them explicitely when you need them. This reduces the risk of errors (imagine your user is also running other figures in the same MATLAB session, if your callback triggers and call gcf when the user was fiddling with another figure, you are going to try to execute code on a different figure than it was intended to ... which can easily result in errors).
Read the documentation on guidata for more information (and/or observe how I've used it in the example above).
Edit:
To avoid the focus coming back to the command window at every key pressed, you also have to also define a callback function to the corresponding KeyRelease event, otherwise the event will automatically be forwarded to the command window (which will take the focus).
A clean way to do is to simply add callback assignment
set(h.fig,'KeyReleaseFcn',#KeyReleased)
once and for all in the figure definition (you don't have to set/undo this callback at each experiment), and then define an empty function function KeyReleased(~,~) which does nothing. This way is implemented in the modified code example above.
Another way to do without the extra empty function, would be to simply define the callback in line at the assignment time:
set(h.fig,'KeyReleaseFcn','disp([])')
This way you do not need to have an empty KeyReleased function.
Note however that a callback function must be defined (either inline or later in the code). Simply assigning empty to the callback will not work. (e.g. both options below will fail to intercept the event and will forward it to the command window:
set(h.fig,'KeyReleaseFcn','') % not working
set(h.fig,'KeyReleaseFcn',[]) % not working either

For Loop within Matlab GUIDE

I have Matlab GUI that uses push button that executes certain code.
all of that works, except that when code reaches for loop, execution does not seem to enter that.
1) Any idea how for loop is implemented within framework of Matlab GUIDE code?
2) is there a way to debug GUI code ( only way I could was trough 'disp' statements,) using breakpoints, as when I run the GUI, breakpoints get removed.
after having read the solutions, I found that
(1) happened because the for loop index was not changing as length of array
that I was indexing on, was not changing. I explain this in the code.
(2) My bad, I was putting breakpoints before running the GUI, when I did the other way around, it breaks fine.
% Opening func
function Regression_OpeningFcn(hObject, ~, handles, varargin)
NoiseMin = -12;
NoiseMax = 10;
NoiseRes = 2;
handles.noiseMin = NoiseMin;
handles.noiseMax = NoiseMax;
handles.noiseRes = NoiseRes;
%**this executed when value changed in edit text box***
function noiseMinDbEditText_Callback(~, ~, handles)
handles.noiseMin = str2num(get(handles.noiseMinDbEditText,'String'));
% When GUI is running, following shows change from -12 sucessfully
disp(strcat('Noise Min = ',num2str(handles.noiseMin)));
function noiseMinDbEditText_CreateFcn(hObject, ~, ~)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%Similar code for noiseMax and noiseRes(not shown here)
`% Here, code enters the Pushbutton callback
function StartRegressionPushButton_Callback(~, ~, handles)
snr_res = handles.noiseRes;
% here, snr_vecs still shows [-12 2 10]
snr_vecs = [handles.noiseMin:handles.noiseRes:handles.noiseMax];
So, basically, when GUI runs, entering and changing the values in text box corresponding to min, max and res snr variables shows me the change, but as soon as I enter the pushbutton dialog box, the changed values( that were captured in global variable "handles") do not show up as I break in the code there.
Any help with this? [for loop problem arose as I was indexing based on snr_vecs array, which is not changing, and so for loop was executing,but not as it should be]
sedy
Using Matlab guide
Guide is basically only a tool to create fig. files. All you can do with guide you could do yourself programmatically. Creating ui-elements works by hand just as easy as with guide (I actually prefere creating gui elements programmatically, since I think guide is very poorly coded)...
Every guide-elements has its callbacks which have to be coded somewhere, usually (I think 100% of the time) the fig file has the same name as the .m file. Find the corresponding .m-file and go to the callback you are interessted in. There you can place breakpoints just as easy as in any other piece of code.
Note: you can even change the code without having to reopen the fig file!
For loops or anything that works in regular code works for ui-element code.
The reason for handles not getting updated was missing following statement at end of function callback whose variable needs to be used in other callback.
guidata(hObject,handles);
I fixed that and it works nicely.
sedy

Showing data on Matlab GUI which is continuously being updated in a separate Matlab function

I have a function in Matlab which is getting continuous sensor values from a hardware. It gives a flag when new values are available and we can update the variables holding these values. Following is a dummy function to mimic what this function is doing.
function example( )
% Example function to describe functionality of NatNetOptiTrack
% Hardware initialization,
% Retriving real time information continuously
for i = 1:100 %in real time this loop runs for ever
data = rand(3,6);
% Send the updated data to gui in each iteration
end
end
i have made a gui using guide as shown in the figure:
So the data to be displayed is a 3x6 matrix with columns corresponding to X Y Z Roll Pitch and Yaw values while rows correspond to Objects.
I want to show the continuously updated values from this function on the gui. Is there a way i can initialize gui inside my example function and update the output value by using the handles inside my loop. I tried copying the gui code inside the example function as a script, it was able to initialize but was not recognizing the handles.
Also i want to show the current values on command window when i press the button.
Thanks
If you launch the GUI and then run the function, you should be able to get the handles to the controls on the GUI provided that you make the GUI figure handle visible and set its tag/name to something appropriate. In GUIDE, open the Property Inspector for the GUI and set the HandleVisibility property to on, and the Tag property to MyGui (or some other name). Then in your example.m file do the following
function example( )
% Example function to describe functionality of NatNetOptiTrack
% get the handle of the GUI
hGui = findobj('Tag','MyGui');
if ~isempty(hGui)
% get the handles to the controls of the GUI
handles = guidata(hGui);
else
handles = [];
end
% Hardware initialization,
% Retriving real time information continuously
for i = 1:100 %in real time this loop runs for ever
data = rand(3,6);
% update the GUI controls
if ~isempty(handles)
% update the controls
% set(handles.yaw,…);
% etc.
end
% make sure that the GUI is refreshed with new content
drawnow();
end
end
An alternative is to copy the example function code into your GUI - the hardware initializations could occur in the _OpeningFcn of your GUI and you could create a (periodic) timer to communicate with the hardware and get the data to display on the GUI.
As for displaying the current data when pressing the GUI button, you can easily do this by writing the contents of the GUI controls to the command line/window with fprintf. You will though need to make your example function interruptible so that the push button can interrupt that continuously running loop. You can do this by either adding a pause call (for a certain number of milliseconds) that gets executed at the end of each iteration of your loop, or just make use of the drawnow call from above (that is why I placed it outside of the if statement - so that it will be called on each iteration of your loop.
Try the above and see what happens!

MATLAB GUI stop button issues

EDIT: I rephrased my question a bit, because I have a better understanding of the problem now and there was a lot of unnecessary info in the first draft.
I am creating a standalone MATLAB application, which needs a toggle button that can initiate and stop a looping script.
Based on this helpful video, I was able to implement this idea like this in my gui.m file:
function startBtn_Callback(hObject, eventdata, handles)
if get(handles.startBtn,'Value')
set(handles.startBtn,'String','Stop Recording');
else
set(handles.startBtn,'String','Start Recording');
end
while get(handles.startBtn,'Value');
disp('looping..');
pause(.5);
end
This script works as expected, but when I replace the contents of the while loop the function I would like to loop, the button stops working. It still toggles when I push it, but the callback only gets called the first time the button is pushed. Here is what my final code looks like:
function startBtn_Callback(hObject, eventdata, handles)
if get(handles.startBtn,'Value')
set(handles.startBtn,'String','Stop Recording');
pause(.1);
else
set(handles.startBtn,'String','Start Recording');
disp('Recording Stopped')
end
while get(handles.startBtn,'Value');
myFunction();
end
When I push the start button, this callback runs and the loop starts. The pause(.1) is needed to get the text to change - if I don't include a pause, the loop initiates, but the text on the button does not change.
After this, no subsequent button pushes do anything. The button toggles on the GUI, but startBtn_Callback never gets called and the loop runs indefinitely. This is a problem because my end user will not have access to the MATLAB console.
To give a bit more information about my function: its a method that records audio for 5 seconds, does some processing, then outputs some graphs. I want this loop to repeat indefinitely until the user pushes stop.
I think that the issue is that MATLAB seems to only be able to run one function at a time, so when myFunction() is running, the callback can't be initiated. The reason it worked in the first example is because there was a pause between loop calls. I can't have this pause, because a requirement of the project is to record every possible second.
How can I make a reliable stop button for this process?
I am running MATLAB R2012b 32-bit.
In your code snippet
a=get(handles.startBtn,'Value')
while a
myFunction();
end
the value of a is assigned once, and never changes afterward. Thus, the while-loop will either never run, or it will loop forever.
while get(handles.startBtn,'Value')
myFunction();
end
will query the value of the button at every iteration, however, especially if myFunction doesn't take very long to execute, there will be lots and lots of java requests that may make your GUI sluggish.
This is why the example you followed uses the pause line, so that the loop only executes every .5 seconds or so.
If you don't want to have the query in the while-line, you can alternatively write
%# read inital value of a
a=get(handles.startBtn,'Value');
while a
myFunction();
%# update a
a=get(handles.startBtn,'Value');
end
drawnow() is the function I was looking for. Putting that after myFunction() forces Matlab to handle any stacked up GUI calls before proceeding with the loop.
This code creates a reliable start/stop toggle button for an indefinite and continuous process:
function startBtn_Callback(hObject, eventdata, handles)
if get(handles.startBtn,'Value')
set(handles.startBtn,'String','Stop');
drawnow();
else
set(handles.startBtn,'String','Start');
end
while get(handles.startBtn,'Value');
myFunction();
drawnow()
end

Matlab GUI using GUIDE : Want to dynamically update graphs

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
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.
You need to use a timer object. Set the callback to be the function that updates the plots.
Take a look at Making Graphs Responsive with Data Linking
and the linkdata command.
If the same variable appears in plots in multiple figures, you can
link any of the plots to the variable. You can use linked plots in
concert with Marking Up Graphs with Data Brushing, but also on their
own. Linking plots lets you
Make graphs respond to changes in variables in the base workspace or within a function
Make graphs respond when you change variables in the Variable Editor and Command Line
Modify variables through data brushing that affect different graphical representations of them at once
Create graphical "watch windows" for debugging purposes
Watch windows are useful if you program in the MATLAB language. For
example, when refining a data processing algorithm to step through
your code, you can see graphs respond to changes in variables as a
function executes statements.
I made a quick and dirty test seen below and I am not sure how this will work in a GUI verses a function but may do the trick.
Note 1: I had to add a break point in my subroutine where it modifies the global y to actually see the plot auto-update. You may need some combination of drawnow, pause, or a timer if data is getting changed rapidly.
function testLinking()
global x y
%Links failed if the global did not also exist in the base workspace
evalin('base','global x y');
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
h = plot(x,y,'ydatasource','y','xdatasource','x');
linkdata on
testSub
function testSub()
%Test to see if a sub can make a linked global refresh
global x y
for i = 1:10
%This should automatically update the plot.
y = sin(x+i/10);
end
Edit: there may be ways around the use of globals depending on how your functions are structured ... but I don't have time to dig into it to much.
You can add a callback on the serial object that executes a plotting function. You must attach the callback to the 'BytesAvailableFcn' event on the object (see this for more details on the properties of the com object).
Essentially, when there are bytes available on the com port, you instruct matlab to run a specific function. In your case, it will be the function updating the GUI. If you need to process the incoming data first, then your callback function will first do the signal processing and then do the plotting commands.