Let me start from your second issue: add a the legend.
In the checkbox callback
you add / remove the lines according to the status
(checked / unchecked) of the checkbox.
To add an item in the legend is quite easy, you just have to insert the desired string (in you case cb_id
) into a cellarray
and set it as input parameter to the legend
function.
To remove an item from the legend when you unckeck a checkbox while leaving the other could be a little bit more difficult.
Considering the you seem not having so many lines to plot, the easiest (even if not the "optimal") approach coul be to change the way the checkbox callbak
works.
Yuo can code it so that each time it is called, it:
- delete all the previously plotted lines
- delete the current legend
- plot (in a loop) all the lines according to the checkbox status
- create the proper legend
in the following, you can find an updated version of that callback uin which this approach has been implented.
In order to exchange the data (e. g. the handles of the checkbox) you can assign them to the figure's userdata
property.
It might be used, for example, as a struct, so you can assign the data to its fields.
As an example, you have in the main function, ii
checkbox handles; with the following code, you can assign the number of checkbox and their handles:
figure_data.n_cb=ii;
figure_data.cb_handles=handles.check;
set(handles.fig,'userdata',figure_data)
I've used this aprroach across all the function you can find below.
With respect to the first issue: a pushbutton
to extract the (x,y) values.
You can add the pushbutton uicontrol
in the main function (as per the checkboxes).
The pushbutton
is:
- disabled at the beginning (in main GUI function)
- enabled when at leat one checkbox is checked (in the checkbox callback)
- disabled otherwise (in the checkbox callback)
There are several way to get the (x,y) values, two of then are:
- you can assign them to a variable in the checkbox callback (in this case you do not actually need to have a pushbutton)
- you can exploit the fact that the data of each line plotted in the axes are also stored in the properties xdata
and ydata
in the plot's handle.
From the axes uicontrol
you can access to them through the children
property: it returs the handles of each element plotted in the axes therefore you can write a loop going through these handles and get the data.
Since, in principle, your data might not have the same size (the plot associated to checkbox_1 might have more data than the one of checkbox_2) you should not use a matrix to hold all of them.
It would be better to use a cellarray
or an array of struct
In the following you can find the updated version of the main function in which the pushbuton
ha been added and the pushbutton callback
.
Main GUI function
N=500;
M=300;
% Added ",'toolbar','figure'" to show the figure toolbar (zoom, rotate,
% ...)
handles.fig=figure('Units', 'Pixels','Position',[100 100 N M],'toolbar','figure');
handles.axes=axes('Units', 'Pixels','tag','axes_tag','Position',[25 25 N-200 M-50]);
for ii=1:4; %input exemple
% Changed definition of "handles.check" from "cellarray" to "array"
% Added setting of each checkbox "userdata" to the value of loop index (a
% way to automatically identify the checkboxes)
%
% handles.check{ii}=uicontrol('style','checkbox','string', ...
handles.check(ii)=uicontrol('style','checkbox','string', ...
['Display_file_' num2str(ii)],'tag',['c_b_' num2str(ii)], ...
'position',[N-150 M/2-ii*20 100 25],'userdata',ii, ...
'callback','plot_sel_cb(handles.axes)');
end
% Add the pushbutton (it is disabled at creation), it will be enabled by
% the checkbox callback if any checkbox set
handles.button=uicontrol('style','pushbutton','string','Export data', ...
'enable','off','position',[N-150 M/2+50 100 25], ...
'callback','export_data');
%
% Store info into figure "userdata"
% number of checkboxes
% status of the checkboxes (all unchecked at the beginning)
% pushbuton handle
figure_data.n_cb=ii;
figure_data.selected_cb=zeros(1,ii);
figure_data.cb_handles=handles.check;
figure_data.button=handles.button;
%
set(handles.fig,'userdata',figure_data)
Updated checkbox callback
function plot_sel_cb(ax_h)
% Get the checkbox id
cb_id=get(gcbo,'userdata');
% Check if current checkbox has been checked (val=1) or unchecked (val=0)
val=get(gcbo,'value');
% Get the number of checkbox in the GUI
figure_data=get(gcf,'userdata');
n_cb=figure_data.n_cb;
cb_handles=figure_data.cb_handles;
% path=get(gcbo,'userdata');
axes(ax_h);
% Clear axes (delete plot) and delete the legend
p_h=get(gca,'children');
if(~isempty(p_h))
delete(p_h);
delete(figure_data.leg_h)
end
hold on
% Update current checkbox status in the checkbox info
figure_data.selected_cb(cb_id)=val;
% Initialize legend string, counter and plot handles array
legend_str={};
cnt=0;
p_h=[];
% Loop throught the checkbox to plot
for i=1:n_cb
if(figure_data.selected_cb(i))
cnt=cnt+1;
x=1:10;
% Get checkbox position (to generate exmple data to plot)
cb_pos=get(cb_handles(i),'position');
% Get checkbox id
curr_cb=get(cb_handles(i),'userdata');
y=[1:10].*cb_pos(2)/100;
% Plot and store plot handle
p_h(cnt)=plot(x,y,'color',[rand(1) rand(1) rand(1)],'linewidth',2);
% Set the plot tag to the index of the checkbox (it will be used in
% the pushbutton callback as index of the cellarray in which to store
% the data plottd
set(p_h(cnt),'userdata',curr_cb)
% Get the string of the current chceckbox
cb_string=get(cb_handles(i),'string');
% Replace "_" with "_-" for the correct visualization
cb_string=strrep(cb_string,'_','_-');
% Build the legend's string
legend_str{cnt}=cb_string;
end
end
% Add the updated legend and store its handle in figure_data
if(~isempty(legend_str))
figure_data.leg_h=legend(p_h,legend_str);
end
% Manage "Export data" pushbutton enabling
if(any(figure_data.selected_cb))
set(figure_data.button,'enable','on')
else
set(figure_data.button,'enable','off')
end
% Update figure data
set(gcf,'userdata',figure_data);
Pushbutton callback
function export_data
% Get plotted data and set store them into a variable
% the vaaible can be either a "cellarray" or an array of "struct"
% The data of each line plotted are stored in the "xdata" and "ydata"
% property of each "children" of the axis
p_h=get(gca,'children');
n_plot=length(p_h);
% Loop through the children to retreive the data
for i=1:n_plot
cb_id=get(p_h(i),'userdata');
x_data=get(p_h(i),'xdata');
y_data=get(p_h(i),'ydata');
% Create the cellarray "exported_data_cell_array"
exported_data_cell_array{cb_id}=[x_data;y_data];
% Create the struct "exported_data_struct"
exported_data_struct(cb_id).checkbox_id=cb_id;
exported_data_struct(cb_id).x_data=y_data;
exported_data_struct(cb_id).y_data=y_data;
end
% Store the extractged data into th e figure_data
figure_data=get(gcf,'userdata');
figure_data.exported_data_cell_array=exported_data_cell_array;
figure_data.exported_data_struct=exported_data_struct;
set(gcf,'userdata',figure_data);

Hope this helps.