Plotting in a GUI
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
0 개 추천
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
Rik
2020년 11월 9일
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
2020년 11월 10일
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.
채택된 답변
Cris LaPierre
2020년 11월 9일
1 개 추천
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
Paul Rogers
2020년 11월 9일
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
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
2020년 11월 9일
thanks, it works, but I don't know why I had to delete the two "end".
Paul Rogers
2020년 11월 9일
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
2020년 11월 9일
편집: Cris LaPierre
2020년 11월 9일
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
2020년 11월 9일
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
2020년 11월 9일
편집: Cris LaPierre
2020년 11월 9일
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
2020년 11월 9일
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
2020년 11월 10일
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
2020년 11월 10일
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
2020년 11월 10일
Paul Rogers
2020년 11월 10일
편집: Paul Rogers
2020년 11월 10일
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:
- why axes4-6-7 don't show the grid and the grid minor.
- 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
- 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
2020년 11월 10일
편집: Cris LaPierre
2020년 11월 10일
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
2020년 11월 12일
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)

추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Creating, Deleting, and Querying Graphics Objects에 대해 자세히 알아보기
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
