Позвольте мне начать со второй проблемы: добавьте легенду.
В checkbox callback
вы добавляете/удаляете строки в соответствии с status
(отмечено/не отмечено) флажка.
Добавить элемент в легенду довольно просто, вам просто нужно вставить нужную строку (в вашем случае cb_id
) в cellarray
и установить ее в качестве входного параметра для функции legend
.
Удалить элемент из легенды, когда вы снимаете флажок, оставляя другой, может быть немного сложнее.
Учитывая, что у вас, похоже, не так много линий для построения, самым простым (даже если не «оптимальным») подходом может быть изменение способа работы checkbox callbak
.
Юо может закодировать его так, чтобы каждый раз, когда он вызывается, он:
- удалить все ранее нанесенные линии
- удалить текущую легенду
- построить (в цикле) все строки в соответствии со статусом флажка
- создать правильную легенду
далее вы можете найти обновленную версию этого обратного вызова, в котором был реализован этот подход.
Чтобы обмениваться данными (например, ручками флажка), вы можете назначить их свойству userdata
фигуры.
Его можно использовать, например, как структуру, чтобы вы могли назначать данные его полям.
Например, в основной функции у вас есть ii
флажков; с помощью следующего кода вы можете назначить количество флажков и их дескрипторов:
figure_data.n_cb=ii;
figure_data.cb_handles=handles.check;
set(handles.fig,'userdata',figure_data)
Я использовал этот подход во всех функциях, которые вы можете найти ниже.
Что касается первой проблемы: pushbutton
для извлечения значений (x, y).
Вы можете добавить pushbutton uicontrol
в основную функцию (согласно флажкам).
pushbutton
это:
- отключено в начале (в основной функции графического интерфейса)
- включен, когда установлен хотя бы один флажок (в обратном вызове флажка)
- в противном случае отключено (в обратном вызове флажка)
Есть несколько способов получить значения (x,y), два из них: - вы можете присвоить их переменной в обратном вызове флажка (в этом случае вам фактически не нужна кнопка) - вы можете использовать тот факт, что данные каждой линии, нанесенной на оси, также хранятся в свойствах xdata
и ydata
в дескрипторе графика.
Из axes uicontrol
вы можете получить к ним доступ через свойство children
: оно возвращает дескрипторы каждого элемента, нанесенного на оси, поэтому вы можете написать цикл, проходящий по этим дескрипторам и получить данные.
Поскольку, в принципе, ваши данные могут иметь разный размер (график, связанный с флажком_1, может иметь больше данных, чем график с флажком_2), вы не должны использовать матрицу для хранения всех из них.
Было бы лучше использовать cellarray
или массив struct
Далее вы можете найти обновленную версию основной функции, в которой добавлены pushbuton
ha и pushbutton callback
.
Основная функция графического интерфейса
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)
Обновлено 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);
Обратный вызов с помощью кнопки
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);
Надеюсь это поможет.
person
il_raffa
schedule
24.10.2015