This example shows how to create a GUIDE UI that accepts input parameters and plots data in two axes. The parameters define a time-varying and frequency-varying signal. One plot displays the data in the time domain, and the other plot displays the data in the frequency domain.
To get and view the example code:
Copy the example FIG-file and code file to your current (writeable) folder and open the FIG-file in GUIDE:
copyfile(fullfile(docroot, 'techdoc','creating_guis',... 'examples','two_axes*.*')), fileattrib('two_axes*.*', '+w') guide two_axes.fig
From the GUIDE Layout Editor, click the Editor button .
two_axes.m code displays in the MATLAB® Editor.
If you run the
two_axes program and click
the Plot button, the UI appears as shown in
the preceding figure. The code evaluates the expression displayed
at the top of the UI using parameters that you enter in the f1, f2,
and t fields. The upper line graph displays
a Fourier transform of the computed signal displayed in the lower
This UI plots two graphs depicting three input values:
Frequency one (
Frequency two (
A time vector (
When you click the Plot button, the program puts these values into a MATLAB expression that is the sum of two sine functions:
x = sin(2*pi*f1*t) + sin(2*pi*f2*t)
Then, the program calculates the FFT (fast Fourier transform)
x and plots the data in the frequency domain
and the time domain in separate axes.
The program provides default values for the three inputs. This enables you to click the Plot button and see a result as soon as you run the program. The defaults indicate typical values.
The default values are created by setting
String property of the edit text. The following
figure shows how the value was set for the time vector.
Since there are two axes in this UI, you must specify which
one you want to target when plotting data. Use the
to access the target axes in your code. All fields in the
are named according to each object's
value. In this case,
the top axes, and the
the bottom axes.
When you UI displays, you can type parameters into three edit text fields as strings of text. If you type an invalid value, the graphs can fail to inform or even to generate. Preventing bad inputs from being processed is an important function of almost any UI that performs computations. This UI code validates these inputs:
Ensure all three inputs are positive or negative real numbers
Ensures that the
t (time) input
is a vector that increases monotonically and is not too long to display
In this example, each edit text control callback validates its
input. If the input fails validation, the callback disables the Plot button,
String to indicate the type of problem
encountered, and restores focus to the edit text control, highlighting
the erroneous input. When you enter a valid value, the Plot button
reenables with its
String set back to
This approach prevents plotting errors and avoids the need for an
error dialog box.
validates most cases, returning
NaN (Not a Number)
for nonnumeric or nonscalar string expressions. An additional test
isreal function makes sure that a text
edit field does not contain a complex number, such as
f1_input_Callback contains the following
code to validate input for
function f1_input_Callback(hObject, eventdata, handles) % Validate that the text in the f1 field converts to a real number f1 = str2double(get(hObject,'String')); if isnan(f1) || ~isreal(f1) % isdouble returns NaN for non-numbers and f1 cannot be complex % Disable the Plot button and change its string to say why set(handles.plot_button,'String','Cannot plot f1') set(handles.plot_button,'Enable','off') % Give the edit text box focus so user can correct the error uicontrol(hObject) else % Enable the Plot button with its original name set(handles.plot_button,'String','Plot') set(handles.plot_button,'Enable','on') end
f2_input_Callbackcode validates the
The time vector input,
t, is more complicated
to validate. As the
str2double function does
not operate on vectors, the
is called to convert the input string into a MATLAB expression.
Because you can type many things that
handle, the first task is to make sure that
try, catch blocks to do
eval with the
eval succeeds, perform additional
tests within the
eval generates an error, pass
control to the
In that block, the callback disables the Plot button
and changes its
The remaining code in the
makes sure that the variable
t returned from
a monotonically increasing vector of numbers with no more than 1000
t passes all these tests, the callback
enables Plot button and sets its
If it fails any of the tests, the callback disables the Plot button
and changes its
String to an appropriate short
message. Here are the
from the callback:
function t_input_Callback(hObject, eventdata, handles) % Disable the Plot button ... until proven innocent set(handles.plot_button,'Enable','off') try t = eval(get(handles.t_input,'String')); if ~isnumeric(t) % t is not a number set(handles.plot_button,'String','t is not numeric') elseif length(t) < 2 % t is not a vector set(handles.plot_button,'String','t must be vector') elseif length(t) > 1000 % t is too long a vector to plot clearly set(handles.plot_button,'String','t is too long') elseif min(diff(t)) < 0 % t is not monotonically increasing set(handles.plot_button,'String','t must increase') else % All OK; Enable the Plot button with its original name set(handles.plot_button,'String','Plot') set(handles.plot_button,'Enable','on') return end % Found an input error other than a bad expression % Give the edit text box focus so user can correct the error uicontrol(hObject) catch EM % Cannot evaluate expression user typed set(handles.plot_button,'String','Cannot plot t') % Give the edit text box focus so user can correct the error uicontrol(hObject) end
For example, here is the response to input of a time vector,
2 6 4 5 7 9], that does not monotonically increase.
In this figure, the two
plots reflect the last successful set of inputs,
f1 = 31.41,
= 120, and
t = [1 2 3 4 5 7 9]. The time
[1 2 6 4 5 7 9] appears highlighted so that
you can enter a new, valid, value. The highlighting results from executing
uicontrol(hObject) in the preceding
When you click the Plot button, the
three basic tasks: it gets input from the edit text components, calculates
data, and creates the two plots.
The first task for the
to read the input values. This involves:
Reading the current values in the three edit text
boxes using the
handles structure to access the
edit text handles.
Converting the two frequency values (
from strings to doubles using
Evaluating the time string using
eval to produce a vector
which the callback used to evaluate the mathematical expression.
The following code shows how the
% Get user input f1 = str2double(get(handles.f1_input,'String')); f2 = str2double(get(handles.f2_input,'String')); t = eval(get(handles.t_input,'String'));
After constructing the string input parameters to numeric form
and assigning them to local variables, the next step is to calculate
data for the two graphs. The
the time domain data using an expression of sines:
x = sin(2*pi*f1*t) + sin(2*pi*f2*t);
y = fft(x,512);
The final task for the
to generate two plots. This involves:
Targeting plots to the appropriate axes. For example, this code directs a graph to the time axes:
Providing the appropriate data to the
Turning on the axes grid, which the
automatically turns off
Performing the last step is necessary because many plotting
In the following code listing, notice how the
provides access to the handle of the axes, when needed.
function plot_button_Callback(hObject, eventdata, handles, varargin) % hObject handle to plot_button (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get user input f1 = str2double(get(handles.f1_input,'String')); f2 = str2double(get(handles.f2_input,'String')); t = eval(get(handles.t_input,'String')); % Calculate data x = sin(2*pi*f1*t) + sin(2*pi*f2*t); y = fft(x,512); m = y.*conj(y)/512; f = 1000*(0:256)/512; % Create frequency plot in proper axes plot(handles.frequency_axes,f,m(1:257)) set(handles.frequency_axes,'XMinorTick','on') grid on % Create time plot in proper axes plot(handles.time_axes,t,x) set(handles.time_axes,'XMinorTick','on') grid on
Select Tools > GUI Options to set these options in your UI:
Resize behavior: Proportional
Selecting Proportional as the resize behavior enables you to resize the UI window. Using this option setting, when you resize the UI, everything expands or shrinks proportionately, except text.
Command-line accessibility: Callback
When UIs include axes, their handles should be visible from other objects' callbacks. This enables you to use plotting commands like you would on the command line. Callback is the default setting for command-line accessibility.
For more information, see GUIDE Options.