How to remove data from a plot when box in checkbox is deselected
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
I have created a figure with 5 checkboxes and have created functions such that when each box is checked, the respective data is added to the plot
fig = figure; %creates checkbox with the currency selections
checkbox_USD = uicontrol(fig,'Style','Checkbox','String','USD','Position',[10 105 100 15],...
'Callback', @Selected_USD); %callback allows a function to operate when box is selected
checkbox_EUR = uicontrol(fig,'Style','Checkbox','String','EUR','Position',[10 85 100 15],...
'Callback', @Selected_EUR);
checkbox_AUD = uicontrol(fig,'Style','Checkbox','String','AUD','Position',[10 65 100 15],...
'Callback', @Selected_AUD);
checkbox_CAD = uicontrol(fig,'Style','Checkbox','String','CAD','Position',[10 45 100 15],...
'Callback', @Selected_CAD);
checkbox_HKD = uicontrol(fig,'Style','Checkbox','String','HKD','Position',[10 25 100 15],...
'Callback', @Selected_HKD);
function Selected_USD (h,~)%callback for 'USD' selection
checked_USD = get(h,'Value');
if checked_USD == 1
graph_function_USD
hold on
end
end
function Selected_EUR (h,~) %callback for 'EUR' selection
checked_EUR = get(h,'Value');
if checked_EUR == 1
graph_function_EUR
hold on
end
end
function Selected_AUD (h,~) %callback for 'AUD' selection
checked_AUD = get(h,'Value');
if checked_AUD == 1
graph_function_AUD
hold on
end
end
function Selected_CAD (h,~) %callback for 'CAD' selection
checked_CAD = get(h,'Value');
if checked_CAD == 1
graph_function_CAD
hold on
end
end
function Selected_HKD (h,~) %callback for 'HKD' selection
checked_HKD = get(h,'Value');
if checked_HKD == 1
graph_function_HKD
hold on
end
end
my question is as follows,
how do i make it so that when the box is deselected, the data is removed from the plot?
any help would be appreciated :)
Accepted Answer
Max Murphy
on 8 Dec 2019
Edited: Max Murphy
on 8 Dec 2019
Edit: After getting the graph_function, removing the old suggestions for clarity.
% These two lines are most likely to change, put them at the top
currency_type = {'USD','EUR','AUD','CAD','HKD'}
source_file = {'exchange_ratesUSD.xlsx','each other name here'} % has to be completed
fig = figure('Name','Currency Data by Type');
ax = axes(fig);
% fig_height = fig.Position(4); see 'Position' of checkbox_obj
line_obj = gobjects(1,numel(currency_type));
checkbox_obj = gobjects(1,numel(currency_type));
for i = 1:numel(line_obj)
line_obj(i) = line(ax,nan,nan); % Where i == 1 corresponds to USD, etc. etc.
set(line_obj(i),'UserData',struct('type',currency_type{i},'source',source_file{i})); % Associate type with the line object
checkbox_obj(i) = uicontrol(fig,...
'Style','Checkbox',...
'String',currency_type{i},...
'Position',[10 105-20*i 100 15],... % could use fig_height here instead of 105
'Callback', {@Selected_Callback,line_obj(i)});
end
% note, want to remove "currency_type" here:
function Selected_Callback (h,~,line_obj)
checked = get(h,'Value');
graph_function(checked,line_obj);
end
And for the function referenced by the callback function:
function graph_function(checked,line_obj)
% GRAPH_FUNCTION Graph data depending if checkbox is ticked and which checkbox it is
currency_type = line_obj.UserData.type; % Retrieve the thing we associated with l(i)
if ~checked
set(line_obj,'XData',nan,'YData',nan); % "turn off the line"
% note that this can be done using set(line_obj,'Visible','off');
% however, if you have a lot of data points, then it can be faster just to do it this way.
else
data = readtable(line_obj.UserData.source);
x = table2array(data(:,1));
y = table2array(data(:,3));
set(line_obj,'XData',x,'YData',y);
end
end
11 Comments
Nathanael Durham
on 8 Dec 2019
thanks for the response :)
with the generalised graph function, would i just use a switch statement that refers to the currency_type selection?
my original graph function is below
function graph_function_USD
USD = readtable('exchange_ratesUSD.xlsx'); %loads excel file for USD exchange rates
USD.Date = datenum(USD{:,1}); %converts dates from string to serial date number
USD_array = table2array(USD); %converts table to matrix
plot(USD_array(:,1),USD_array(:,3)); %plots date against exchange rate
title('GBP/USD Exchange Rate');
xlabel('Date');
ylabel('Comparative Exchange Rate');
yearly_tick =datenum(1999:1:2019,1,1); %set ticks to occur in yearly intervals
set(gca,'xtick',yearly_tick);
datetick('x','mmm/yyyy','keepticks');
xtickangle(90); %rotate x-axis labels to prevent cluttering
set(gca,'XMinorTick','on');
set(gcf,'visible','on');
legend('USD')
end
and i've tried using a switch statement like this:
function graph_function
switch currency_type
case 1
USD = readtable('exchange_ratesUSD.xlsx'); %loads excel file for USD exchange rates
USD.Date = datenum(USD{:,1}); %converts dates from string to serial date number
USD_array = table2array(USD); %converts table to matrix
plot(USD_array(:,1),USD_array(:,3)); %plots date against exchange rate
title('GBP Exchange Rate');
xlabel('Date');
ylabel('Comparative Exchange Rate');
yearly_tick =datenum(1999:1:2019,1,1); %set ticks to occur in yearly intervals
set(gca,'xtick',yearly_tick);
datetick('x','mmm/yyyy','keepticks');
xtickangle(90); %rotate x-axis labels to prevent cluttering
set(gca,'XMinorTick','on');
set(gcf,'visible','on');
legend('USD')
% case 2 etc...
is that correct?
Nathanael Durham
on 8 Dec 2019
Also what is the purpose of this line?
graph_function(checked,currency_type,line_obj);
Max Murphy
on 8 Dec 2019
OK so if you just have a list of xlsx files you want to read from for each different checkbox, then I would use those as your 'UserData' as follows:
% These two lines are most likely to change, put them at the top
currency_type = {'USD','EUR','AUD','CAD','HKD'}
source_file = {'exchange_ratesUSD.xlsx','each other name here'} % has to be completed
fig = figure('Name','Currency Data by Type');
ax = axes(fig);
% fig_height = fig.Position(4); see 'Position' of checkbox_obj
line_obj = gobjects(1,numel(currency_type));
checkbox_obj = gobjects(1,numel(currency_type));
for i = 1:numel(line_obj)
line_obj(i) = line(ax,nan,nan); % Where i == 1 corresponds to USD, etc. etc.
set(line_obj(i),'UserData',struct('type',currency_type{i},'source',source_file{i})); % Associate type with the line object
checkbox_obj(i) = uicontrol(fig,...
'Style','Checkbox',...
'String',currency_type{i},...
'Position',[10 105-20*i 100 15],... % could use fig_height here instead of 105
'Callback', {@Selected_Callback,l(i)});
end
% note, want to remove "currency_type" here:
function Selected_Callback (h,~,line_obj)
checked = get(h,'Value');
graph_function(checked,line_obj);
end
And in the callback function:
function graph_function(checked,line_obj)
% GRAPH_FUNCTION Graph data depending if checkbox is ticked and which checkbox it is
currency_type = line_obj.UserData.type; % Retrieve the thing we associated with l(i)
if ~checked
set(line_obj,'XData',nan,'YData',nan); % "turn off the line"
% note that this can be done using set(line_obj,'Visible','off');
% however, if you have a lot of data points, then it can be faster just to do it this way.
else
data = readtable(line_obj.UserData.source);
x = table2array(data(:,1));
y = table2array(data(:,3));
set(line_obj,'XData',x,'YData',y);
end
end
Nathanael Durham
on 8 Dec 2019
I'm getting an error:
Error using checkbox_test3>Selected_Callback
Too many input arguments.
Error while evaluating UIControl Callback.
Max Murphy
on 8 Dec 2019
Check on line 17:
'Callback', {@Selected_Callback,l(i)});
Should be changed to
'Callback', {@Selected_Callback,line_obj(i)});
Sorry about that.
Also at the top, if you're running this as a script you may want to call clear at the beginning if you don't need to keep things in workspace memory.
Max Murphy
on 8 Dec 2019
Error using checkbox_test3>Selected_Callback
Too many input arguments.
Error while evaluating UIControl Callback.
This means that you created a checkbox uicontrol called checkbox_test3. You assigned its Callback property the function handle Selected_Callback. When you assign a callback function handle to a Matlab uicontrol such as a checkbox, the checkbox automatically gets two other input arguments first: source which is the h from your original Selected_Callback and it references the uicontrol object itself, and event, which is an "EventData" object that has a few fields with different information depending on the type of uicontrol, the type of interaction (e.g. Callback or SelectionChangedFcn, etc) and that is all dependent upon the type of event that is issued during the interaction. My guess is that your new Selected_Callback function doesn't account for both of these automatically-added inputs. If you don't use one or both of them, then you can set the corresponding argument to Selected_Callback as ~. You can also specify that you do not want to use them during the assignment of the Callback property, for example by setting
checkbox_test3.Callback = @(source,~,line_obj)Selected_Callback(line_obj(i));
Nathanael Durham
on 8 Dec 2019
Now when i try run the code i end up with this
>> checkbox_test3.Callback = @(source,~,line_obj)Selected_Callback(line_obj(i));
>> checkbox_test3
checkbox_test3 =
struct with fields:
Callback: @(source,~,line_obj)Selected_Callback(line_obj(i))
sorry I'm not entirely sure i've done it correctly i am fairly new to MATLAB
Max Murphy
on 8 Dec 2019
Edited: Max Murphy
on 8 Dec 2019
No problem. Wherever you are making checkbox_test3, you will want to initialize it first, before assigning the Callback. If you start out by assigning the property before the object exists, then Matlab will just interpret checkbox_test3 as a struct with the field Callback, as opposed to a graphics object.
You can initialize the object with the Callback that you want by assigning the property during construction of the object, such as:
checkbox_test3 = uicontrol(fig,...
'Style','Checkbox',...
'String',currency_type{3},...
'Position',[10 105-20*3 100 15],... % could use fig_height here instead of 105
'Callback', {@Selected_Callback,line_obj(3)});
Notice that in this example I am using the "hard-coded" index 3 where I had been using i in the loop previously. For this object to be created successfully, you will need to have a cell array currency_type, whose third element ( currency_type{3} ) corresponds to the char array you want. line_obj(3) should correspond to some line object, so it doesn't have to be from an array it could be whatever line you have initialized previously.
Nathanael Durham
on 8 Dec 2019
so would i have to manually create the cell array containing the different currency types?
Also when i try to use that checkbox code it say's
unable to define variable 'checkbox_test3' because it has the same name as the script
Max Murphy
on 8 Dec 2019
I'd suggest naming the script something else, such as currencyType_checkboxTest or something that fits your name convention.
Yes, the cell arrays currency_type and source_file in the code from the top-level comment would need to be manually defined by you. Each element of source_file should match the corresponding element of currency_type.
source_file should be the names of the xlsx source files. You can also parse their names dynamically if you have them all in one folder by calling the dir command on that folder, but I think you just want to get the test example working so I wouldn't worry about that for now.
Nathanael Durham
on 8 Dec 2019
What should the currency array look like?
More Answers (0)
Categories
Find more on Spreadsheets in Help Center and File Exchange
See Also
on 7 Dec 2019
on 8 Dec 2019
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- 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)