Selecting figure data interactively with rectangle or point

16 ビュー (過去 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.
  1 件のコメント
Dirk
Dirk 2025 年 12 月 9 日 15:05
Understood. Thank you for the recommendation.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMigrate GUIDE Apps についてさらに検索

製品


リリース

R2025b

Community Treasure Hunt

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

Start Hunting!

Translated by