Wait for user to delete points in a plot and then continue with rest of code

I am trying to write a piece of code that plots points, lets a user delete certain points (right now I am doing it through brushing and clicking "Remove Brushed"), and then updates the source data to later be used for further execution (using linkdata). However, functions like uiwait and waitfor stall the whole execution and do not allow the user to use "Remove Brushed." Here, removing extraneous points is crucial for the transformation function in step 3.
It seems like "Removed Brushed" only works after code execution is totally complete. I could simply have users run two scripts/functions, or ask them to run steps 2 and 3 as different sections, but I want this to be as easy as possible for users.
Is there something I am missing? Are there other (visual) ways for users to delete points and update the data (or save as another variable)? Any help would be greatly appreciated.
% STEP 1: Import (example) data
exported_centers = [5,10; 5,7];
image_centers = [6,10; 6,7; 10,4];
% STEP 2: Clean up unpaired image_centers not associated with a exported_center
fig = figure; hold on
ax = gca;
ax.XLim(1) = 0; ax.XLim(2) = 15;
ax.YLim(1) = 0; ax.YLim(2) = 15;
% reference image in blue, exported particles red
scatter(image_centers(:,1),image_centers(:,2),40,'filled','o','MarkerFaceColor','b')
scatter(exported_centers(:,1),exported_centers(:,2),40,'filled','o','MarkerFaceColor','r')
message = sprintf('Drag left click around blue points that do not look to have a red dot associated with it. \nThen, right click on the gray point and select Remove Brushed');
msgbox(message)
linkdata on
b = brush;
b.Enable = 'on';
b.Color = [0.5 0.5 0.5]; % gray
% waitfor(msgbox(message)) nope
% waitfor(fig) nope
% uiwait(fig) nope
% uiwait(msgbox(message)) nope
% while ~waitforbuttonpress
% end nope
% input('Press Enter to continue...') nope
% pause; nope
% return; yes, but defeats the purpose of continuing onto step 3
% STEP 3: Transform! - breaks if users not allowed to delete extraneous points
tform = fitgeotrans(exported_centers,image_centers,'affine');
[tX,tY] = transformPointsForward(tform,exported_centers(:,1),exported_centers(:,2));
newPos = horzcat(tX,tY); % newPos is updated particle positions

 Accepted Answer

dpb
dpb on 5 Mar 2026 at 17:03
Moved: dpb on 5 Mar 2026 at 17:03
That's what ginput is good for...

2 Comments

ginput works - it doesn't automatically snap to the scatter points in the figure, which is okay (points can be deleted based on how close they are to the ginput output).
However, I am using brushing because it's a nice visual for a user to watch "in real time" their selected points get deleted. While ginput is fine, it would be ideal for users to see the scatterplot get updated as they delete points (and then continue onto the next bits of code). Would this even be possible?
Yes. Put the |ginput(1) call in a loop and check key return to terminate if empty or return.
To find the point use something like
% Get (x,y) coordinates for all points
hAx=gca; % the axes handle of the plot
[x,y,button] = ginput(1);
[dmin,ixmin] = pdist2([hAx.XData hAx.YData],[x y],'euclidean','Smallest',1);
hAx.XData(ixmin)=[];
hAx.YData(ixmin)=[];
You can also check that the minimum distance must be within some magnitude as well rather than just choosing the minimum.
You could update the selected point by adding a marker at that specific point or somesuch to show the user which point is selected one. I'm not sure if one has the facility to be able to put the cursor itself at the point.
An alternative approach might be able to be constructed using datatip aothough I've not really investigated it other than just watching the builtin display.

Sign in to comment.

More Answers (0)

Categories

Asked:

on 5 Mar 2026 at 16:48

Edited:

dpb
on 5 Mar 2026 at 22:46

Community Treasure Hunt

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

Start Hunting!