Hi, I am new to GUI, I did my first program but now I am stuck in plotting the results.
I'd like to plot the results I get from the function I inserted.
I've prevviously run this on a simple Matlab file, and I'd like to plot:
y(:,1)
y(:,2)
versus time. So basically I used to write:
plot(time,phi)
or
plot(time,psi)
I put in attached the file I did. The problem is at line 494 where I commented

2 commentaires

Rik
Rik le 9 Nov 2020
If you are new to GUIs, you should probably avoid GUIDE for anything that you work with for more than an hour or so.
For general advice and examples for how to create a GUI (and avoid using GUIDE), have look at this thread.
The end problem you/Cris encountered is because GUIDE is ancient and uses the old convention of not closing functions with end. In R13 (a release that is old enough to drink in many countries) you even get a warning if you do close functions with end. With the introduction of nested functions in R14 there was a specific need to match functions with an end to be able to find out if a function was a nested function or an outer function. The importance of closing functions with end has increased even more with the possibility of having functions inside script files (introduced in R2016b). It wouldn't surprise me if at some point in the future the closing keyword will be mandatory. That will be the day that finally all GUIDE-generated GUIs will break.
Cris LaPierre
Cris LaPierre le 10 Nov 2020
I was going to recommend app designer, but saw the OP is using R2012b. If updating is a possibility, I strongly recommend it. If not, you an still definitely get this working in guide.

Connectez-vous pour commenter.

 Réponse acceptée

Cris LaPierre
Cris LaPierre le 9 Nov 2020

1 vote

You will need to specify the axes handles as part of the plot command. You command should look something like this (untested):
plot(handles.axes1,time,phi)

14 commentaires

Paul Rogers
Paul Rogers le 9 Nov 2020
yeah I tried, the problem that is messin me up is that the evaluation cames from a call to a function and I don't know how to handle this thing
Cris LaPierre
Cris LaPierre le 9 Nov 2020
You have included your definition of your plotting variables, along with your plot code inside the function containing your differencetial equation. Try moving this to the callback that runs your odesolver (pushbutton1). Also, be sure to terminate each function with 'end'.
% --- 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)
...
[t,y]=ode113(@greitzer,[t0,tf],init,options); %I found ode113 is way more efficient
%% MOVE PLOTTING CODE HERE
%% Here is where I got lost
phi = y(:,1);
% phi = y(:,2);
time = t
plot(handles.axes1,time,phi)
% plot(time,phi)
% plot(phi,psi)
end
function [ dy ] = greitzer( t,y )
load main_parameters.mat
psi_c_y = psi_c0+H*(1+(3/2)*((y(1)/W)-1)-(1/2)*(((y(1)/W)-1).^3)); % compressor map's
gamma_T = @(t) A*sin(w*t)+b % valve's function
dy = [ B*(psi_c_y-y(2));
(1/B.*(y(1)-gamma_T(t).*(y(2).^0.5))) ];
end
Paul Rogers
Paul Rogers le 9 Nov 2020
thanks, it works, but I don't know why I had to delete the two "end".
Paul Rogers
Paul Rogers le 9 Nov 2020
now it's very strange, it's partially working without the two "end" but I noticed i forgot
load main_parameters.mat
from the previously function, so instead of evaluating the parametrs I put, it uses the old one already loaded.
If I try to remove that line, it doesn't work.
% 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)
a0 = str2double(get(handles.speed_of_sound,'string'));
U = str2double(get(handles.impeller_tip_velocity,'string'));
Vp = str2double(get(handles.plenum_volume,'string'));
Lc = str2double(get(handles.lenght_compressor_dutch,'string'));
Ac = str2double(get(handles.cross_section_area,'string'));
H = str2double(get(handles.semi_high,'string'));
W = str2double(get(handles.semi_width,'string'));
psi_c0 = str2double(get(handles.shut_off_value,'string'));
wh = a0*(Ac/Vp*Lc)^0.5; %Helmotz's frequency
B = U/(2*wh*Lc); %Greitzer's parameter
gamma_T = str2double(get(handles.throttle_aperture,'string'));
Delta_gamma_T = str2double(get(handles.delta_gamma,'string'));
gamma_T_max = gamma_T+(Delta_gamma_T/2); %maximum aperture
gamma_T_min = gamma_T-(Delta_gamma_T/2); %minimum aperture
A = (gamma_T_max - gamma_T_min)/2; %amplitude
b = (gamma_T_max + gamma_T_min)/2;
engine_frequency = str2double(get(handles.engine_hz,'string'));
w = engine_frequency*2*pi;
t0 = str2double(get(handles.first_count,'string'));
tf = str2double(get(handles.last_count,'string'));
y1 = str2double(get(handles.phi0,'string'));
y2 = str2double(get(handles.psi0,'string'));
init = [y1 y2]'; %initial conditions vector
sample_frequency = str2double(get(handles.samp_freq,'string'));
maximum_time_step = 1/sample_frequency;
options= odeset('MaxStep',maximum_time_step); %maximum time-step size
[t,y]=ode113(@greitzer,[t0,tf],init,options); %I found ode113 is way more efficient
%% MOVE PLOTTING CODE HERE
phi = y(:,1);
psi = y(:,2);
time = t
% plot(handles.axes4,time,psi)
plot(handles.axes4,t,y(:,2))
function [ dy ] = greitzer( t,y )
load main_parameters.mat
psi_c_y = psi_c0+H*(1+(3/2)*((y(1)/W)-1)-(1/2)*(((y(1)/W)-1).^3)); % compressor map's
gamma_T = @(t) A*sin(w*t)+b % valve's function
dy = [ B*(psi_c_y-y(2));
(1/B.*(y(1)-gamma_T(t).*(y(2).^0.5))) ];
Cris LaPierre
Cris LaPierre le 9 Nov 2020
Modifié(e) : Cris LaPierre le 9 Nov 2020
I can't even run your m-file to test. I'd need the mat and fig files in order to do more. You'll either need to provide a lot more detail, or share your files.
Paul Rogers
Paul Rogers le 9 Nov 2020
thanks, I put the files in attached, I also added main which is the code that basically I am trying to do as a GUI.
Cris LaPierre
Cris LaPierre le 9 Nov 2020
Modifié(e) : Cris LaPierre le 9 Nov 2020
Ok, with some redesign I was able to get your gui to run. The main issue I had was your gui edit fields had text in it instead of numbers. I elected to hard code the numbers just to test things out. i also set up your pushbutton callback to calculate all the parameters and pass them as inputs to your ode function rather than trying to load the parameters from a saved mat file. Doing that circumvents any values the user might enter in the gui anyway.
Also, sorry about the confusion about 'end'. Forgot that guis don't do it that way.
Here's what I converted your code to to make it run. Ntoice I commented out any values you are getting from the fig window and hard coded the values. With everything running you should be able to convert them back to values obtained from the gui, but you'll want to update the fields to either be empty, or contain default values like those used below.
You should also be able to add your other plots now.
% --- 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)
% a0 = str2double(get(handles.speed_of_sound,'string'));
% U = str2double(get(handles.impeller_tip_velocity,'string'));
% Vp = str2double(get(handles.plenum_volume,'string'));
% Lc = str2double(get(handles.lenght_compressor_dutch,'string'));
% Ac = str2double(get(handles.cross_section_area,'string'));
% H = str2double(get(handles.semi_high,'string'));
% W = str2double(get(handles.semi_width,'string'));
% psi_c0 = str2double(get(handles.shut_off_value,'string'));
%
% wh = a0*(Ac/Vp*Lc)^0.5; %Helmotz's frequency
% B = U/(2*wh*Lc); %Greitzer's parameter
%
% gamma_T = str2double(get(handles.throttle_aperture,'string'));
% Delta_gamma_T = str2double(get(handles.delta_gamma,'string'));
%
% gamma_T_max = gamma_T+(Delta_gamma_T/2); %maximum aperture
% gamma_T_min = gamma_T-(Delta_gamma_T/2); %minimum aperture
% A = (gamma_T_max - gamma_T_min)/2; %amplitude
% b = (gamma_T_max + gamma_T_min)/2;
%
% engine_frequency = str2double(get(handles.engine_hz,'string'));
% w = engine_frequency*2*pi;
%
% t0 = str2double(get(handles.first_count,'string'));
% tf = str2double(get(handles.last_count,'string'));
% y1 = str2double(get(handles.phi0,'string'));
% y2 = str2double(get(handles.psi0,'string'));
%
% init = [y1 y2]'; %initial conditions vector
%
% sample_frequency = str2double(get(handles.samp_freq,'string'));
%% Ambiental parameters
a0 = 340; %speed of sound [m/s]
%% Compressor Parameters
U = 68; %[m/s]
Vp = 0.1; %[m^3]
Lc = 0.41; %[m]
Ac = 0.0038; %[m^2]
H = 0.18; %semi high
W = 0.25; %semi width
psi_c0 = 0.352; %shut off value
wh = a0*(Ac/Vp*Lc)^0.5; %Helmotz's frequency
B = U/(2*wh*Lc); %Greitzer's parameter
%% Throttle valve's parameters
gamma_T = .9; %throttle valve aperture
Delta_gamma_T = .3; %range between your gamma_T_max e gamma_T_min
gamma_T_max = gamma_T+(Delta_gamma_T/2); %maximum aperture
gamma_T_min = gamma_T-(Delta_gamma_T/2); %minimum aperture
A = (gamma_T_max - gamma_T_min)/2; %amplitude
b = (gamma_T_max + gamma_T_min)/2;
%% Engine's parameters (only frequency)
engine_frequency = 10; %engine's frequency [Hz]
w = engine_frequency*2*pi; %engine's frequency [radiants/s]
%% Ode's parameters
t0 = 0; %simulation's start [s]
tf = 20; %simulation's finish [s]
y1 = 0; %initial condition 1
y2 = 0; %initial condition 2
init = [y1 y2]'; %initial conditions vector
sample_frequency = 120;
maximum_time_step = 1/sample_frequency;
options= odeset('MaxStep',maximum_time_step); %maximum time-step size
[t,y]=ode113(@greitzer,[t0,tf],init,options,psi_c0,H,W,A,w,b,B); %I found ode113 is way more efficient
%% MOVE PLOTTING CODE HERE
phi = y(:,1);
psi = y(:,2);
time = t;
% plot(handles.axes4,time,psi)
plot(handles.axes4,t,y(:,2))
function [ dy ] = greitzer( t,y,psi_c0,H,W,A,w,b,B )
% load main_parameters.mat
psi_c_y = psi_c0+H*(1+(3/2)*((y(1)/W)-1)-(1/2)*(((y(1)/W)-1).^3)); % compressor map's
gamma_T = @(t) A*sin(w*t)+b; % valve's function
dy = [ B*(psi_c_y-y(2));
(1/B.*(y(1)-gamma_T(t).*(y(2).^0.5))) ];
Paul Rogers
Paul Rogers le 9 Nov 2020
finally, it's getting better.
What I don't understand now is why when I plot axes7 and then I change just a value, let's say from engine's frequency from 10hz to 1Hz i.e., it doesn't refresh but it keeps the old plot and plots the new one on the old one.
Cris LaPierre
Cris LaPierre le 10 Nov 2020
Because you never turn hold off. Best practice is to always pair a hold on with a hold off.
plot(handles.axes7,y(:,1),(psi_c0+H*(1+(3/2)*((y(:,1)/W)-1)-(1/2)*(((y(:,1)/W)-1).^3))))
hold on
plot(y(:,1),y(:,2))
hold off
grid on
grid minor
xlabel('t [s]')
ylabel('\Psi')
title('Pressure oscillations')
Rik
Rik le 10 Nov 2020
You can also store the output from both plot calls. The you can modify the XData and YData properties of the line objects directly. That has the benefit of being much faster.
It is also best practice to use explicit handles for every graphics call in a GUI. That way you never rely on the relevant figure or axes being the current figure or axes.
Cris LaPierre
Cris LaPierre le 10 Nov 2020
Agreed. See this post for more details.
Paul Rogers
Paul Rogers le 10 Nov 2020
Modifié(e) : Paul Rogers le 10 Nov 2020
here I am, I almost completed my first GUI, it all works well, I mean, it does the job.
Anyway, there are some things I don.t understand:
  1. why axes4-6-7 don't show the grid and the grid minor.
  2. why in the small panel (left bottom corner "panel") if I click on the static textbox and look for the "view callback" menu, it doesn't show the "callback" voice, only createffcn, deletefcn and buttondownfcn
  3. Is there a way, for example, when I delete an axes, or a static textbox, or whatever, to automatically delete even the code generated with them?
thanks a lot, and sorry foor asking, but all the tutorials on youtube are about random calculator.
Cris LaPierre
Cris LaPierre le 10 Nov 2020
Modifié(e) : Cris LaPierre le 10 Nov 2020
1. With your grid commands, you have to tell it which axes to apply the command to. Try something like this.
plot(handles.axes4,t,y(:,1))
grid(handles.axes4,'on')
grid(handles.axes4,'minor')
...
2. Static text boxes are, well, static. There is no callback because they cannot be changed. Use an Edit Text component in order to get a callback.
3. No. You have to manually delete the code. I suggest before deleting, rt clicking and going to the callback and create functions first, deleting them, then deleting the component.
Paul Rogers
Paul Rogers le 12 Nov 2020
thanks Cris LaPierre,
sorry for asking a lot but I couldn't find anything online for the GUI.
I post a snapshoot of the semi-final model (I'd like to make some adjstment in the next weeks)

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Creating, Deleting, and Querying Graphics Objects dans Centre d'aide et File Exchange

Produits

Version

R2012b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by