I am not sure if I'm going about this the right way, but I want to have a function that when called, essentially resets 4 plots. I store the plots as handles.distplot1
, handles.distplot2
and so on in hopes of having a drop down to select which plot is shown on the axis. I will need reset these plots after a few different events, so naturally I want to toss them in a function and avoid code redundancy. I hope a function like
function setupDistPlots(hObject, eventdata, handles)
% filler data for surfc
x = [1 2];
z = zeros(2);
% setup blank plots for funtion to work with
a = figure(1); set(a, 'Visible', 'off')
handles.distplot1 = surfc(x, x, z);
b = figure(2); set(b, 'Visible', 'off');
handles.distplot2 = bar(NaN);
c = figure(3); set(c, 'Visible', 'off')
handles.distplot3 = surfc(x, x, z);
d = figure(4); set(d, 'Visible', 'off')
handles.distplot4 = bar(NaN);
guidata(hObject, handles);
Which I believe should work as intended, but I have no idea how to call it. In the opening function I try setupDistPlots(hObject, eventdata, handles)
but receive the following error when I try to access handles.distplot1
later on:
Reference to non-existent field 'distplot1'.
Error in tabbedGUI>distanceToggle_Callback (line 212)
distribution(hObject,
handles.distplot1, ...
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in tabbedGUI (line 45)
gui_mainfcn(gui_State, varargin{:});
Error in
@(hObject,eventdata)tabbedGUI('distanceToggle_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
edit: Also please point out everything I could improve. Everything I do in Matlab feels hackish like there must be a better way.
edit2: The problem with the opening function was calling setupDistPlots
before the guidata(hObject, handles)
call of the opening function. However now when when I call `setupDistPlots' again on a button press I get the following error:
Error using matlab.graphics.primitive.Data/set
Invalid or deleted object.
Error in andrewDistribution (line 45)
set(hplot1, 'xData', x1, 'yData', y1, 'zData', zeros(length(x1)))
Error in tabbedGUI>distanceToggle_Callback (line 200)
distribution(hObject, handles.distplot1, ...
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in tabbedGUI (line 45)
gui_mainfcn(gui_State, varargin{:});
Error in @(hObject,eventdata)tabbedGUI('distanceToggle_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
I'm assuming your initial attempt looked like this:
% --- Executes just before testgui is made visible.
function testgui_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for testgui
handles.output = hObject;
setupDistPlots(hObject, eventdata, handles)
% Update handles structure
guidata(hObject, handles);
As talked to in the comments, your changes to the handles
structure saved to the GUI by setupDistPlots
using guidata
are being overwritten by the GUIDE's subsequent guidata
call. The short answer is to put setupDistPlots
after guidata
to make everything function as written.
Now the longer answer. I'm going to guess that you're familiar mostly working with MATLAB scripts rather than MATLAB functions. Where scripts share a base workspace, functions each have their own separate workspace in memory. As written there is no way for your OpeningFcn
to know that you have changed the handles
structure, so it happily overwrites your changes using the value of handles
that was passed to setupDistPlots
. To get around this, you need to include some way for the OpeningFcn
to know that you have made changes.
One approach is to specify an output for setupDistPlots
:
function handles = setupDistPlots(hObject, eventdata, handles)
% filler data for surfc
x = [1 2];
z = zeros(2);
% setup blank plots for funtion to work with
a = figure(1); set(a, 'Visible', 'off')
handles.distplot1 = surfc(x, x, z);
b = figure(2); set(b, 'Visible', 'off');
handles.distplot2 = bar(NaN);
c = figure(3); set(c, 'Visible', 'off')
handles.distplot3 = surfc(x, x, z);
d = figure(4); set(d, 'Visible', 'off')
handles.distplot4 = bar(NaN);
Placing setupDistPlots
before the guidata
call in your GUIDE code:
% --- Executes just before testgui is made visible.
function testgui_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for testgui
handles.output = hObject;
handles = setupDistPlots(hObject, eventdata, handles);
% Update handles structure
guidata(hObject, handles);