MATLAB uicontrol 回调 return 矩阵
MATLAB uicontrol callback return matrix
原文post:
我的问题现在有了第二部分。
和以前一样,我正在绘制一个 19*1000*134 矩阵,这要归功于 Aero Engy 在上一个 post.
上的出色回答
我想在我的工作区中创建一个名为 clean 的向量,其长度为 134。
默认情况下,clean(i)(i 在 1 到 134 之间)的值将为 1——但是,如果我在 UI 界面上按下按钮,该值必须变为 0 .
我的代码如下,只是不要给我任何输出。该按钮似乎可以使用,但是当我关闭图形时,我没有清理矢量。
function cleanData(data);
% data = rand(19,1000,134);
global clean
clean = ones(1,size(data,3));
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a = axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s = uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l = uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,clean,s});
stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];
changeChannel(l,[],a,s,data)
function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500; %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position
function sliderChange(s,evtData,a)
viewI = round(s.Value);
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])
function notClean(c,evtData,clean,s)
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
我做错了什么?
奖金:如果
就好了
- 当我按下按钮 "Not clean" 时,滑块改变值并增加(目前,我必须按下按钮,然后滑块的右箭头转到下一个 2 秒的数据) .
- 一旦我检查了一个通道(矩阵的 19 行之一)的 "Clean" 或 "not clean",对于下一个通道,它将跳过 "not clean" 数据(即在与纪元号对应的干净矩阵中有一个 0)。
感谢您的帮助,我是 MATLAB 的新手,即使我提高很快,我也远未完全理解这段代码。
在 notClean 回调中,我将 clean
作为全局调用。我也将它作为输入删除了...因为它是全局的,所以没有必要将它传入。
我还添加了每次按下按钮时滑块前进 1 的代码。
关闭 GUI 后在您的工作区中查看您标记的内容,您只需在命令行执行以下操作即可访问您的 clean
数组。 (数字是我标记为不干净的随机内容。
我现在必须离开,所以我无法解决关于更改频道和跳过 ~clean elementr 的第二个要点……但这应该不是很难。我会在几个小时后回到这里。
>> global clean
>> find(~clean)
ans =
3 4 11 19
修改后的代码:
编辑:在跳过频道的边缘添加了代码保护。
function cleanData(data)
% data = rand(19,1000,134);
global clean
clean = ones(1,size(data,3));
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a = axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s = uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l = uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,s,a});
stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];
changeChannel(l,[],a,s,data)
function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500; %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position
function sliderChange(s,evtData,a)
global clean
persistent prevI
if isempty(prevI)
prevI = 1;
end
viewI = round(s.Value);
sDir = sign(viewI - prevI); %-1 if going backwards +1 if going forward
prevI = viewI;
if clean(viewI) == 0
newPos = viewI + sDir;
if newPos < 1 || newPos > s.Max
return
end
s.Value = newPos;
sliderChange(s,[],a)
else
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])
end
function notClean(c,evtData,s,a)
global clean %Call the global
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
%Advance to the next slider position.
if num+1 < s.Max
s.Value = num+1;
sliderChange(s,[],a)
end
将第二部分的代码修改为:
function cleanData(data);
% data = rand(19,1000,134);
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a = axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s = uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l = uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,s,a});
stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];
changeChannel(l,[],a,s,data)
function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500; %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position
function sliderChange(s,evtData,a)
global clean
viewI = round(s.Value);
if clean(viewI) == 0
s.Value = s.Value+1;
sliderChange(s,[],a)
else
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])
end
function notClean(c,evtData,s,a)
global clean %Call the global
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
%Advance to the next slider position.
s.Value = num+1;
sliderChange(s,[],a)
原文post:
我的问题现在有了第二部分。 和以前一样,我正在绘制一个 19*1000*134 矩阵,这要归功于 Aero Engy 在上一个 post.
上的出色回答我想在我的工作区中创建一个名为 clean 的向量,其长度为 134。
默认情况下,clean(i)(i 在 1 到 134 之间)的值将为 1——但是,如果我在 UI 界面上按下按钮,该值必须变为 0 .
我的代码如下,只是不要给我任何输出。该按钮似乎可以使用,但是当我关闭图形时,我没有清理矢量。
function cleanData(data);
% data = rand(19,1000,134);
global clean
clean = ones(1,size(data,3));
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a = axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s = uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l = uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,clean,s});
stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];
changeChannel(l,[],a,s,data)
function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500; %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position
function sliderChange(s,evtData,a)
viewI = round(s.Value);
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])
function notClean(c,evtData,clean,s)
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
我做错了什么?
奖金:如果
就好了- 当我按下按钮 "Not clean" 时,滑块改变值并增加(目前,我必须按下按钮,然后滑块的右箭头转到下一个 2 秒的数据) .
- 一旦我检查了一个通道(矩阵的 19 行之一)的 "Clean" 或 "not clean",对于下一个通道,它将跳过 "not clean" 数据(即在与纪元号对应的干净矩阵中有一个 0)。
感谢您的帮助,我是 MATLAB 的新手,即使我提高很快,我也远未完全理解这段代码。
在 notClean 回调中,我将 clean
作为全局调用。我也将它作为输入删除了...因为它是全局的,所以没有必要将它传入。
我还添加了每次按下按钮时滑块前进 1 的代码。
关闭 GUI 后在您的工作区中查看您标记的内容,您只需在命令行执行以下操作即可访问您的 clean
数组。 (数字是我标记为不干净的随机内容。
我现在必须离开,所以我无法解决关于更改频道和跳过 ~clean elementr 的第二个要点……但这应该不是很难。我会在几个小时后回到这里。
>> global clean
>> find(~clean)
ans =
3 4 11 19
修改后的代码: 编辑:在跳过频道的边缘添加了代码保护。
function cleanData(data)
% data = rand(19,1000,134);
global clean
clean = ones(1,size(data,3));
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a = axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s = uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l = uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,s,a});
stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];
changeChannel(l,[],a,s,data)
function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500; %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position
function sliderChange(s,evtData,a)
global clean
persistent prevI
if isempty(prevI)
prevI = 1;
end
viewI = round(s.Value);
sDir = sign(viewI - prevI); %-1 if going backwards +1 if going forward
prevI = viewI;
if clean(viewI) == 0
newPos = viewI + sDir;
if newPos < 1 || newPos > s.Max
return
end
s.Value = newPos;
sliderChange(s,[],a)
else
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])
end
function notClean(c,evtData,s,a)
global clean %Call the global
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
%Advance to the next slider position.
if num+1 < s.Max
s.Value = num+1;
sliderChange(s,[],a)
end
将第二部分的代码修改为:
function cleanData(data);
% data = rand(19,1000,134);
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a = axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s = uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l = uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,s,a});
stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];
changeChannel(l,[],a,s,data)
function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500; %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position
function sliderChange(s,evtData,a)
global clean
viewI = round(s.Value);
if clean(viewI) == 0
s.Value = s.Value+1;
sliderChange(s,[],a)
else
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])
end
function notClean(c,evtData,s,a)
global clean %Call the global
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
%Advance to the next slider position.
s.Value = num+1;
sliderChange(s,[],a)