Problem plotting function in GUI

5 visualizzazioni (ultimi 30 giorni)
Diego Guisasola Plejo
Diego Guisasola Plejo il 28 Giu 2018
Commentato: Rik il 4 Lug 2018
Hello everyone, this is the first time I post here so if I sound like a newbie is because I am. I have a problem when trying to plot a function in GUI so I decided to do some tests in order to figure it out. I'm creating a non-linear equation solver using Newton-Raphson Method and this is how the UI looks (is in Spanish but is quite intuitive):
Funcion = The function the user wants to solve. Stored in the variable 'funcion' and then I use the inline() function in order to get a function that I can use in order to compute values (stored in the variable f). When he clicks on "Click aqui para mostrar la derivada", the program derivates the function the user wants to solve in order to use it in the formula. Valor inicial = Initial value. "Elija el metodo" = The user can choose one of two methods, fixed number of iterations or tolerance (hope this is clear). "Calcular" = The method executes and finds the value wanted.
I haven't implemented the table yet so I see the answer in the command window. Until this point, everything works smoothly, the root is stored in the variable 'x1'. The problem begins when I click the push button called "Graficar respuesta". What it does is to plot the function and a circle around the point 'x1' which represents one root of the function, at least that's what is supposed to do. The code is:
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
global x1;
global funcion;
global f;
if x1==0
x1=x1+1;
elseif x1<0
x1=-x1;
end
% axes(handles.axes2);
%Imagen
figure (1);
x=-5*x1:0.001:5*x1;
plot(x,funcion,'Color','red'), title('Grafica de la funcion'), xlabel('Eje X'), ylabel('Eje Y'), grid;
hold on;
scatter(x1,f(x1));
But I get the next error:
Error using plot
Error in color/linetype argument.
Error in newton>pushbutton3_Callback (line
196)
plot(x,funcion,'Color','red'), title('Grafica
de la funcion'), xlabel('Eje X'), ylabel('Eje
Y'), grid;
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in newton (line 18)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)newton('pushbutton3_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback.
What am I doing wrong? I would really appreciate any help, please. Thanks in advance.
  6 Commenti
Diego Guisasola Plejo
Diego Guisasola Plejo il 30 Giu 2018
You are totally right. I should learn good practices from the beginning. Could you give me some site where I could learn all about that with examples, please? Thanks in advance!
Stephen23
Stephen23 il 1 Lug 2018
Avoid using global variables, evalin, and assignin. For callback functions use guidata (for GUIDE) or nested functions (if you are writing your own code). For non-GUI code pass variables as input/output arguments.
You will find plenty of simple examples on this forum, e.g.:
Using guidata is very simple:
function foobar(hObject, eventdata, handles)
...
... handles.X ... % access field X
handles.Y = ... % define field Y
...
guidata(hObject,handles) % save any new data

Accedi per commentare.

Risposte (1)

Rik
Rik il 29 Giu 2018
Using the handles struct is very easy. It may seem hard to learn good practices, but it is much harder to unlearn bad practices. The code below works on my system (R2018a). You should really pay attention to the m-lint warnings. Replacing an old function like inline with anonymous functions is a good place to start. In your call to that figure 1, I would add a clf(1), especially since you have hold turned on.
function funcion_Callback(hObject, ~, handles)
syms x;
funcion=get(handles.funcion,'string');
f=str2func(['@(x)' funcion]);
df=symfun(diff(f,x),x)
set(handles.derivada,'string',char(df));
handles.funcion=funcion;
handles.df=df;
handles.f=f;
guidata(hObject,handles)
function pushbutton3_Callback(hObject, ~, handles)
x1=handles.x1;%global x1;
%funcion=handles.funcion;%global funcion;
f=handles.f;%global f;
if x1==0
x1=x1+1;
elseif x1<0
x1=-x1;
end
% axes(handles.axes2);
%Imagen
figure (1);
x=-5*x1:0.001:5*x1;
plot(x,f(x),'Color','red'), title('Grafica de la funcion'), xlabel('Eje X'), ylabel('Eje Y'), grid;
hold on;
scatter(x1,f(x1));
  6 Commenti
Diego Guisasola Plejo
Diego Guisasola Plejo il 4 Lug 2018
Modificato: Diego Guisasola Plejo il 4 Lug 2018
Thanks for your comment! I debugged the code and convert x1 to a double using double(x1) and creating a new variable in order to use it with this new value but I get the next error:
Error using ^
One argument must be a square matrix and the other must be a scalar. Use
POWER (.^) for elementwise power.
Error in newton>@(x)x^3+10
Error in newton>pushbutton3_Callback (line 187)
plot(x,f(x),'Color','red'), title('Grafica de la funcion'), xlabel('Eje X'),
ylabel('Eje Y'), grid;
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in newton (line 18)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)newton('pushbutton3_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback.
Now the question is, how can I go around this? Because the user inputs x^3+10 but the code needs it to be like this: x.^3+10
Any ideas? Thanks in advance!
Edit 1: It only happens when I use exponents because when I plug a linear function, the program works flawlessly. Except when I plug in a trigonometric function, then it takes way to long... (I'm not sure how long because it has been running for more than 5 minutes and nothing has appeared).
Edit 2: I was able to find a workaround to the trigonometric function's error and it was using the matlabFunction like this:
df1=handles.df;
df=matlabFunction(df1);
Now it's working properly.
The only problem I have is when using functions like x^3 because, in order to plot it, the code needs it in the form x.^3.
Any help would be much appreciated.
Rik
Rik il 4 Lug 2018
You could replace
plot(x,f(x),'Color','red')
by
plot(x,arrayfun(f,x),'Color','red')
%untested, you might need to add 'UniformOutput',0 to arrayfun
That way the function is applied to each element separately, which makes it slower, but will prevent odd errors in cases of powers, multiplications, and divisions.

Accedi per commentare.

Community Treasure Hunt

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

Start Hunting!

Translated by