Selecting figure data interactively with rectangle or point

16 visualizzazioni (ultimi 30 giorni)
Dirk
Dirk il 8 Dic 2025 alle 20:36
Commentato: Dirk il 9 Dic 2025 alle 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

Risposta accettata

Taylor
Taylor il 8 Dic 2025 alle 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.

Più risposte (0)

Categorie

Scopri di più su Migrate GUIDE Apps in Help Center e File Exchange

Prodotti


Release

R2025b

Community Treasure Hunt

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

Start Hunting!

Translated by