Selecting figure data interactively with rectangle or point

조회 수: 18 (최근 30일)
Dirk
Dirk 2025년 12월 8일 20:36
댓글: Dirk 2025년 12월 9일 15:05
I am trying to augment my working point selection tool with a rectangle/box selection option. The tool allows me to select points one by one, optionally adding these to a list of flagged indexes for the data. The UI works for points (ginput, button1 'UserData'=1), but when I use the box selection (drawrectangle, button0 'UserData'=1), the button0 'UserData' is never 1, so the data are not flagged.
close all
clear
fh = figure;
x1=300:10:1000;
y1(1,:) = ones(1,length(x1));
y1(2,:) = 2*y1(1,:);
y1(3,:) = 3*y1(1,:);
plot(x1,y1)
hold on
ylim([0 4])
flag = zeros(1,size(y1,1));
disp('Manual Screening')
disp('Zoom to y1 of interest and hit Box or Point select.')
disp('Accept to save and move on. Reject to ignore last.')
button0 = uicontrol(fh,'Style', 'pushbutton', 'String', 'Box select',...
'Position', [5 200 60 25], 'Callback', @buttonCallBack);
button1 = uicontrol(fh,'Style', 'pushbutton', 'String', 'Point select',...
'Position', [5 150 60 25], 'Callback', @buttonCallBack);
button2 = uicontrol('Style', 'pushbutton', 'String', 'Accept',...
'Position', [5 100 50 25], 'Callback', @buttonCallBack);
button3 = uicontrol('Style', 'pushbutton', 'String', 'Reject',...
'Position', [5 50 50 25], 'Callback', @buttonCallBack);
button4 = uicontrol('Style', 'pushbutton', 'String', 'Exit',...
'Position', [5 5 50 25], 'Callback', @buttonCallBack);
while 1
disp('Zoom to data of interest and choose selector.')
uiwait(fh)
if get(button4,'userdata') == 1
disp('Exitting')
break
end
if get(button1,'userdata') == 1
[x,y] = ginput(1);
[~,windex] = find_nearest(x,x1);
spectrumX = y1(:,windex);
[~,Rindex] = find_nearest(y,spectrumX);
plot(x1(windex),y1(Rindex,windex),'*k')
elseif get(button0,'userdata') == 1
h=drawrectangle;
pos = h.Position;
xmin = pos(1);
ymin = pos(2);
xmax = pos(1) + pos(3);
ymax = pos(2) + pos(4);
indexOfInterest = (x1 >= xmin) & (x1 <= xmax) & (y1 >= ymin) & (y1 <= ymax);
for i=1:size(y1,1)
plot(x1(1,indexOfInterest(i,:)),y1(i,indexOfInterest(i,:)),'*k')
end
end
set(button0,'userdata',0)
set(button1,'userdata',0)
set(button2,'userdata',0)
set(button3,'userdata',0)
set(button4,'userdata',0)
uiwait
if get(button0,'userdata') == 1 || get(button1,'userdata') == 1 || get(button3,'userdata') == 1
set(button0,'userdata',0)
set(button1,'userdata',0)
set(button2,'userdata',0)
set(button3,'userdata',0)
set(button4,'userdata',0)
continue
elseif get(button2,'userdata') == 1
if get(button1,'userdata') == 1
% This works
[~,windex] = find_nearest(x,x1);
spectrumX = y1(:,windex);
[~,Rindex] = find_nearest(y,spectrumX);
elseif get(button0,'userdata') == 1
% This does not work
Rindex = find(any(indexOfInterest,2));
end
plot(x1,y1(Rindex,:),'k','LineWidth',3)
flag(Rindex) = 1;
fprintf('Index of selected y1: %d\n',Rindex)
set(button0,'userdata',0)
set(button1,'userdata',0)
set(button2,'userdata',0)
set(button3,'userdata',0)
set(button4,'userdata',0)
elseif get(button4,'userdata') == 1
disp('Exitting and saving')
break
end
end
%%
function buttonCallBack(hObject,~)
set(hObject,'UserData',1)
uiresume
end
%%
function [near_scalar, index] = find_nearest(scalar,list)
diff = abs(list - scalar);
[~, index_a] = min(diff);
index = index_a(1); % Pick the first if equidistant
near_scalar = list(index);
end

채택된 답변

Taylor
Taylor 2025년 12월 8일 22:38
You're running into a state management bug: you’re using the buttons’ UserData both as an event trigger (to uiresume) and as persistent state (to remember whether the last selection was point or box). You reset the UserData to 0 right after the selection step, so when you press Accept, your elseif get(button0,'userdata') == 1 never fires for the rectangle path.
I would recommend switching to App Designer to build this app. There is even a free course to get you started.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Migrate GUIDE Apps에 대해 자세히 알아보기

제품


릴리스

R2025b

Community Treasure Hunt

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

Start Hunting!

Translated by