- Test that user is using r2020b or later; if not, throw error.
- Save current state of the app figure handle visibility.
- Change the app figure handle visibility so that it's accessible to the callback function.
- Make app figure current
- Call ginput
- Return the original figure handle visibility state.
How can I use ginput in app designer?
210 views (last 30 days)
I would like to select a range of points from one particular UIAxes in my app.
I have tried to use ginput ([x,y=ginput]), but the applications prompts an additional empty plot to select the range of points. How can I point an specific UIAxes?
Adam Danz on 4 Oct 2020
Edited: Adam Danz on 4 Oct 2020
ginput is now supported in AppDesigner starting in r2020b
We still don't have an option to specify the target figure handle in ginput so you have to make the App's figure handle visible so ginput doesn't land on the wrong figure or create a new figure.
The example below is a callback function that responds to a button press and does the following:
% Button pushed function: Button
function ButtonPushed(app, event)
% Check Matlab version, throw error if prior to r2020b
assert(~verLessThan('Matlab', '9.9'), 'ginput not supported prior to Matlab r2020b.')
% Set up figure handle visibility, run ginput, and return state
fhv = app.UIFigure.HandleVisibility; % Current status
app.UIFigure.HandleVisibility = 'callback'; % Temp change (or, 'on')
set(0, 'CurrentFigure', app.UIFigure) % Make fig current
[x,y,b] = ginput(1); % run ginput
app.UIFigure.HandleVisibility = fhv; % return original state
More Answers (6)
Jon Nykiel on 18 Jun 2019
Unfortunately, ginput is not supported within appdesigner. However, as of R2019A, the CurrentPoint property can be used within a WindowButtonDown function to get the coordinates of a button click within UIAxes.
function UIFigureWindowButtonDown(app, event)
temp = app.UIAxes.CurrentPoint; % Returns 2x3 array of points
loc = [temp(1,1) temp(1,2)]; % Gets the (x,y) coordinates
HM on 31 Aug 2018
I found this thread because I was looking for the same thing. We definitely need a 'ginput' function that works within a UIFigure.
However, I did find a workaround: invoke a new 'normal' matlab figure with 'figure' (e.g. MyFigure = figure;) plot on that figure any plots/graphics that you have plotted on your UIFigure (any relevant graphics that you need on there to be able to click relative to). Note, use the traditional plot() command, rather than the plot(app.UIFigure, ) command. Then use the ginput function with that figure. (e.g. MyPoints = ginput;) then delete the figure, and use the recorded values as desired. (e.g. delete(MyFigure); )
This actually worked well for me, as the 'pop-up' figure is larger than my UIFigure, allowing for more accurate mouse clicking.
Hope that helps. Cheers, Hugh.
chrisw23 on 18 Jan 2019
Edited: chrisw23 on 18 Jan 2019
You can define a ButtonDownFcn callback that delivers 'Hit' event data for axes, which has an IntersectionPoint property. This is also valid for lines, but not for ie. the MainFigure (MouseData event only).
This works fine although the AppDesigner doesn't support callback properties for Axes ( tested with SubPlot with Panel Parent in R2018b ).
app.myAx = subplot(2,1,1,'Parent',app.Panel); % create plot
app.myAx.ButtonDownFcn = createCallbackFcn(app, @app.getMousePosition, true);
% Properties: Btn/IntersectionPoint/Src/Evnt
posData = event.IntersectionPoint; % to be used for calc
% Properties: Src/EvntName
Hope it helps
Richard Saumarez on 18 Jun 2019
I agree about the comments on appDesigner
After a lot of work, and bending one's foot round one's ear, one can write a GUI that has most of the functionality written in Visual stdio or Fortran. But it seems counterintuitive and everything that one would like to do, and would think is being easy, is "not supported".
There is no doubt in my mind that appDesigner needs more functionality if one is going to write an artistic, commercially useful, GUI that is not simply knobs and sliders. Apart from the difficulty in getting the mouse position, one desperately needs to be able to draw on the uppermost layer of the GUI, not in a plot, but in the container itself.
I may be being unfair, and this may be possible, but finding one's way around Matlab documentation, apart from the most basic aspects, is really difficult.
Birdman on 4 Apr 2018
You can't. If you check the documentation of ginput, you will see it can not take a predefined axes as an input argument:
There might be custom written functions for that though, you just have to google it.
Vlad Atanasiu on 2 Oct 2020
Here is an illustration of how to simulate ginput with uifigures (App Designer, R2020b).
% Get coordinates of clicked point on image in uifigure and uiaxes.
% Remove datatips by pressing "Escape".
% Create uifigure
fig = uifigure;
fig.WindowKeyPressFcn = @onKeyPress;
% Create uiaxes
ax = uiaxes(fig);
ax.PickableParts = 'visible';
ax.HitTest = 'on';
% Display classic image in uiaxes
I = imread('membrane.png'); % 100 x 86 px
im = imshow(I,'Parent',ax);
im.ButtonDownFcn = @onClickImage;
% Capture clicks on uiaxes
function [x, y] = onClickImage(~,~)
% Set the image to allow clicks to pass through it
im.PickableParts = 'none';
im.HitTest = 'off';
% Get coordinates of clicked point from uiaxes
x = ax.CurrentPoint(1);
y = ax.CurrentPoint(3);
% Revert above changes to image properties
im.PickableParts = 'visible';
im.HitTest = 'on';
% Compute integer pixel coordinates
if x < 1
% Correct a location error of one pixel
% between axes and image coordinates
x = 1;
x = floor(x);
if y < 1
y = 1;
y = ceil(y);
% Delete previous datatips, if any
dt = findall(fig,'Type','datatip');
% Display pixel coordinates on datatip
% (The origin is at the top left of the image)
message = ['x ',num2str(x),', y ',num2str(y)];
im.DataTipTemplate.DataTipRows(1).Label = message;
im.DataTipTemplate.DataTipRows(1).Value = [x,y];
im.DataTipTemplate.DataTipRows(2).Label = '';
im.DataTipTemplate.DataTipRows(2).Value = '';
% Capture key presses
function onKeyPress(~, event)
% Which kwy was pressed?
clickType = event.Key;
% remove datatip
dt = findall(fig,'Type','datatip');