MATLAB GUI clear plot1 but not plot2 and vice-versa

1 view (last 30 days)
I have a gui which has 2 push buttons, and 3 listboxes.
Button 1 is to load in the data (select the directory to load data from), listbox1 is the location the user selects in which they want to look at, and then listbox2 and listbox3 are further sub-variables (let's say temperature, dewpoint, wind speed, etc.) in which the user can plot two variables together at the same time. Button 2 clears the graph.
The way my current code for the gui works is the user clicks on button 1 to load the data which is displayed in listbox1. Then, the user selects a locations from listbox1, then a variable from listbox2, and then finally a second variable from listbox3 (if desired) is plotted on top of the variable from listbox2. If the user clicks on any different variable from listbox2, the graph automatically clears to plot and displays the correct data (the only visible data). If the user selects one option from listbox3, that is plotted ontop of listbox2. However, say the user accidentally clicked the wrong item in listbox3, and proceeds to click another option in listbox3. The problem is now there are 3 variables plotted instead of the option from listbox2 and the new option from listbox3.
Therefore, my question is: how do I clear the most recently plotted item while using one axes handler? Below is the code (it is probably messy to a professional, so any tips / help would also be appreciated to clean it up).
function varargout = gui1(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @gui1_OpeningFcn, ...
'gui_OutputFcn', @gui1_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before gui1 is made visible.
function gui1_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for gui1
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
HWvars = [{'Temp'}; {'Dewpoint'}; {'Speed'}];
set(handles.listbox2,'String',HWvars)
set(handles.listbox3,'String',HWvars)
% --- Outputs from this function are returned to the command line.
function varargout = gui1_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% Get the folder
folder_name = uigetdir;
% Get what is inside the folder
Infolder = dir(folder_name);
% Initialize the cell of string that will update the list box
handles.filename = [];
% Loop on every element in the folder and update the list
handles.files = fullfile(folder_name,{Infolder(~[Infolder.isdir]).name});
handles.filename = {Infolder(~[Infolder.isdir]).name};
% Update the listbox with the result
set(handles.listbox1,'String',handles.filename)
guidata(hObject, handles);
% --- Executes on selection change in listbox1.
function listbox1_Callback(hObject, eventdata, handles)
handles.output = hObject;
[data,datee] = HWdata(hObject, eventdata, handles);
HWnum1 = listbox2_Callback(hObject, eventdata, handles);
axes(handles.axes1);
plot(data(:,HWnum1));
guidata(hObject, handles);
% --- Executes during object creation, after setting all properties.
function listbox1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in listbox2.
function HWnum1 = listbox2_Callback(hObject, eventdata, handles)
HWnum1 = get(handles.listbox2,'value');
[data,datee] = HWdata(hObject, eventdata, handles);
axes(handles.axes1);
plot(data(:,HWnum1));
hold on
xtickangle(45);
xspacing = floor(length(datee)/8);
xticks([1 xspacing xspacing*2 xspacing*3 xspacing*4 xspacing*5 xspacing*6 xspacing*7 xspacing*8])
xticklabels([datee{1};datee{(xspacing)};datee{(xspacing*2)};datee{(xspacing*3)};datee{(xspacing*4)};datee{(xspacing*5)};datee{(xspacing*6)};datee{(xspacing*7)};datee{end}]);
hold off
guidata(hObject, handles);
% --- Executes during object creation, after setting all properties.
function listbox2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on selection change in listbox3.
function HWnum2 = listbox3_Callback(hObject, eventdata, handles)
HWnum2 = get(handles.listbox3,'value');
[data,datee] = HWdata(hObject, eventdata, handles);
axes(handles.axes1);
hold on
yyaxis right
plot(data(:,HWnum2));
hold off
guidata(hObject, handles);
% --- Executes during object creation, after setting all properties.
function listbox3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% User created functions
function [data,datee] = HWdata(hObject, eventdata, handles)
% code here to read in some data from a textfile
end
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
cla reset
guidata(hObject, handles);

Answers (1)

Adam Danz
Adam Danz on 14 Sep 2018
my question is: how do I clear the most recently plotted item while using one axes handle?
Option 1 This option may or may not work with your data but it worked with a simple demo I wrote to test it. Use the axis handle to get the handles to all of the children plotted on the axis.
axh.Children %where axh is the handle to your axis (gca)
The most recent item plotted should be listed first so just delete the first item like this
delete(axh.Children(1))
You'll need to create an 'undo' button in your GUI that simply calls the line above.
Option 2 Create a 'plot now' button in your GUI and require the user to press this button to update the plot rather than the plot updating automatically.
  4 Comments
Simpson
Simpson on 14 Sep 2018
I agree this would be the easier option. However, I tried something along the lines of changing
axes(handles.axes1);
to
plot1 = axes(handles.axes1);
But nothing seemed to change - I still get the multiple plots. Could you provide a brief example as I am obviously missing something trivial.
Adam Danz
Adam Danz on 14 Sep 2018
Edited: Adam Danz on 14 Sep 2018
First some cleanup. Currently you have 3 callback functions that are plotting on the same axis which leads to redundancy. Also each callback function does not have access to data from other callback functions so that makes it difficult to share handles. To avoid this, make an additional function whose sole job is to update and manage the plot. Each of those 3 callback functions will merely send data to your new function.
Secondly, you can store the plot handle within that new function and make it a persistent variable so every time this function is called it has access to the handle of the most recently plotted object. Create an 'undo' button that also calls this function and sends a flag that indicates you'd like to delete the most recently plotted object.
Here's a simplified example:
function updateplot(axisHandle, newdata, undoFlag, clearFlag)
% axisHandle: the handle to your axis
% newdata: the data you'd like to plot
% undoFlag: true/false; when true, the most recent object is removed
% clearFlag: true/false; when true, the axis is cleared
persistant ph
if clearFlag
cla(axisHandle)
return
end
if undoFlag && ~isempty(ph)
delete(ph)
return
end
ph = plot(axisHandle, newdata)
You can adapt that watered-down version to your code.

Sign in to comment.

Categories

Find more on Graphics Object Programming in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!