Problem with quiver plot function

I am working on some code which I have been trying to tidy up into functions as I have several versions of it and it's quite repetitive. One of the tasks is a quiver plot, which I have written this function (Qplot) for:
function Qplot( space, lat, lon, u, v, size, thick )
%UNTITLED6 Summary of this function goes here
% Detailed explanation goes here
hold on
r = 1:str2double(space):length(lat);
r1 = lat(r);
s = 1:str2double(space):length(lon);
s1 = lon(s);
us = u(r, s);
vs = v(r, s);
q = quiver(s1,r1,us,vs);
q.AutoScaleFactor = str2double(size);
q.LineWidth = str2double(thick);
q.Color = 'k';
hold off
end
This works fine on most versions of the code except one. I have had to take out the Qplot bit out (it's there commented out) and replace it with the content of the function in full, like this:
function pushbutton23_Callback(hObject, eventdata, handles) %#ok<*INUSL>
h = guidata(gcbo);
axes(handles.axes2)
% Qplot(handles.edit22.String, h.latf, h.lonf, h.uf. h.vf, handles.edit21.String, handles.edit23.String)
hold on
r = 1:str2double(handles.edit22.String):length(h.latf);
r1 = h.latf(r);
s = 1:str2double(handles.edit22.String):length(h.lonf);
s1 = h.lonf(s);
us = h.uf(r, s);
vs = h.vf(r, s);
q = quiver(s1,r1,us,vs);
q.AutoScaleFactor = str2double(handles.edit21.String);
q.LineWidth = str2double(handles.edit23.String);
q.Color = 'k';
hold off
If I use the Qplot function in that one version only, I get this error message, but in no others where I'm doing exactly the same thing:
Struct contents reference from a non-struct array object.
Error in guiglobal>pushbutton23_Callback (line 280)
Qplot(handles.edit22.String, h.latf, h.lonf, h.uf. h.vf, handles.edit21.String, handles.edit23.String)
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in guiglobal (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)guiglobal('pushbutton23_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
Any ideas?

10 Comments

Immediately before your Qplot call, add these lines of code and show us what it displays in the situation where you receive the error.
whos
fieldnames(h)
fieldnames(handles)
Name Size Bytes Class Attributes
eventdata 1x1 112 matlab.ui.eventdata.ActionData
h 1x1 468330720 struct
hObject 1x1 112 matlab.ui.control.UIControl
handles 1x1 468330720 struct
ans =
'figure1'
'pushbutton52'
'uipanel12'
'uipanel6'
'uipanel8'
'uipanel5'
'uipanel4'
'uipanel2'
'uipanel1'
'text1'
'text28'
'text27'
'axes2'
'axes1'
'text86'
'text85'
'edit28'
'edit27'
'pushbutton50'
'pushbutton49'
'pushbutton21'
'edit6'
'edit3'
'edit5'
'edit2'
'text34'
'text33'
'text25'
'text24'
'edit23'
'text55'
'edit22'
'text54'
'pushbutton23'
'edit21'
'text53'
'text39'
'text38'
'text36'
'text35'
'text32'
'text31'
'text22'
'text21'
'pushbutton19'
'edit1'
'pushbutton20'
'text2'
'pushbutton43'
'text79'
'pushbutton25'
'text57'
'pushbutton12'
'pushbutton11'
'pushbutton8'
'pushbutton7'
'text14'
'text13'
'text10'
'text9'
'pushbutton42'
'text78'
'pushbutton24'
'text56'
'pushbutton6'
'pushbutton5'
'pushbutton2'
'pushbutton1'
'text8'
'text7'
'text4'
'text3'
'output'
'ufa'
'imAlpha'
'vfa'
'data'
'uf'
'vf'
'lonf'
'latf'
'flon'
'flat'
'imAlpha2'
ans =
'figure1'
'pushbutton52'
'uipanel12'
'uipanel6'
'uipanel8'
'uipanel5'
'uipanel4'
'uipanel2'
'uipanel1'
'text1'
'text28'
'text27'
'axes2'
'axes1'
'text86'
'text85'
'edit28'
'edit27'
'pushbutton50'
'pushbutton49'
'pushbutton21'
'edit6'
'edit3'
'edit5'
'edit2'
'text34'
'text33'
'text25'
'text24'
'edit23'
'text55'
'edit22'
'text54'
'pushbutton23'
'edit21'
'text53'
'text39'
'text38'
'text36'
'text35'
'text32'
'text31'
'text22'
'text21'
'pushbutton19'
'edit1'
'pushbutton20'
'text2'
'pushbutton43'
'text79'
'pushbutton25'
'text57'
'pushbutton12'
'pushbutton11'
'pushbutton8'
'pushbutton7'
'text14'
'text13'
'text10'
'text9'
'pushbutton42'
'text78'
'pushbutton24'
'text56'
'pushbutton6'
'pushbutton5'
'pushbutton2'
'pushbutton1'
'text8'
'text7'
'text4'
'text3'
'output'
'ufa'
'imAlpha'
'vfa'
'data'
'uf'
'vf'
'lonf'
'latf'
'flon'
'flat'
'imAlpha2'
For future reference, do yourself a huge favour and start changing the 'Tag' property of your buttons and other UI elements to something meaningful, e.g. pbOk or pushbuttonOk or checkboxPlotType or whatever it may be. It makes it far easier for you to understand your own code than having to deal with 'edit22' and 'pushbutton43'
That's not the case. As a result of keeping the code well organised and commented, I've been able to keep track of edit boxes and buttons with no problems. If you're finding it hard to follow in order to help debug my code, can you be more specific about what you're having trouble following so I can explain it to you more clearly?
Michael: What exactly do you mean by show it? It's inputted from an editable text box which is the arrow spacing. It still says handles.edit22.string in the version where I didn't use the function and that works fine.
Output from command line:
ans =
UIControl (edit22) with properties:
Style: 'edit'
String: '40'
BackgroundColor: [1 1 1]
Callback: @(hObject,eventdata)guiglobal('edit22_Callback',hObject,eventdata,guidata(hObject))
Value: 0
Position: [0.5849 0.4321 0.1761 0.2099]
Units: 'normalized'
The point is that a numbered name is meaningless and needs comments to be understood, while a name should already have enough information in it to be understood so that any comment is a bonus. This was good faith advice, not a personal attack.
I agree with the advice of having your variable names carry a bit more meaning that edit22, just as you did yourself with the Qplot function. You could also improve that function by explicitly describing what the variables should be, so you have a record of what your function expects. You could implement some input checking, but if you only use the function yourself, you can check the input during writing, which then saves time during execution.
I can't see any logical reason why calling a function in that case would yield that error while using the exact same variables and fields in place does not.
There are some oddities about the code that make it more likely for bugs to creep in, but these should not cause what you are seeing, e.g.
h = guidata(gcbo);
is totally un-necessary. This is exactly what 'handles' is at this point in the code.
axes(handles.axes2)
% Qplot(handles.edit22.String, h.latf, h.lonf, h.uf. h.vf, handles.edit21.String, handles.edit23.String)
hold on
You should get used to always passing axes handles to plotting instructions such as hold rather than relying on the fact the changing the active axes and then plotting or calling hold will always work exactly as expected.
Passing the axes handle to Qplot and then calling
quiver( hAxes,... )
and
hold( hAxes, 'on' )
is more robust.
I don't see why either of these issues should cause the code not to work in this case though.
You should be able to see the problem with a breakpoint though when you get the error. Look at each of the arguments to the Qplot function in turn on the command line and one of them should throw the error you get. Again though I see no logical reason why this would be the case while calling Qplot, but not when using the pasted code.
Handles only covers the axes, that line is needed because I also need to access variables in the h. structure to tell it what to plot.
What might it not do as expected? Turns out that's not the problem here, there was a typo as spotted below, but I am interested in what that does which my current code does not. It seems to robustly always plot to the correct axes regardless of what else I've been doing.
h = guidata(gcbo);
gives you the handles struct. The exact same one that you get passed into the function as 'handles'.
Generally code using
axes( obj.hAxes )
followed by a load of plot related instructions will work fine, but from time to time you will find a case where the 'current axes' changed without you realising between you calling axes and actually plotting data. I have had numerous occasions when I forgot to give explicit axes handles when I suddenly get an axes appearing in a figure I wasn't expecting it.
So sure, it may work in all cases you have had so far, but it is just good practice to give explicit handles to plot instructions rather than just hope that nothing unexpectedly changes the current axes before you plot (e.g. a user clicking on a different axes will change the current axes too).

Sign in to comment.

 Accepted Answer

You got a typo:
Qplot(handles.edit22.String, h.latf, h.lonf, h.uf. h.vf, handles.edit21.String, handles.edit23.String)
^^ this should be a ,

More Answers (0)

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Tags

Asked:

on 21 Sep 2018

Commented:

on 24 Sep 2018

Community Treasure Hunt

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

Start Hunting!