How do I use the "ButtonDownFcn" for a plot in App Designer?

244 views (last 30 days)

How do I use the "ButtonDownFcn" for a plot in App Designer? I am not sure how or, more importantly, where to define the callback function. I tried changing the "ButtonDownFcn" property for the axis, but the UIAxes in App Designer does not have any callbacks.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 21 Nov 2019
You are correct that there is no "ButtonDownFcn" for a UIAxes. Thus, stick to using the "ButtonDownFcn" with your plot object.
To start, create a plot in your app's StartupFcn and define the plot's "ButtonDownFcn" with an associated callback function:
The key here is _where _you define this callback function. If you simply add a new public/private function in Code View, the plot object will be unable to find the function when the callback is triggered, and you will get an error. This is because your app is set up as a class in App Designer, and thus, your callback will be defined as a class method, not an ordinary function.
The easiest alternative is to define your callback function as a nested function, located inside the StartupFcn. Check out the example below, in which I plot a parabola. If a user clicks on the parabola, a nested callback will be triggered that adds the x- and y-coordinates to a UITable, which lists the coordinates of all points that have been clicked so far.
function startupFcn(app)
% create plot with line object
x = linspace(-5,5);
y = -1 * x.^2;
plot(app.UIAxes,x,y,'ButtonDownFcn',@mouse_click);
% define callback as nested func
function mouse_click(~,eventData)
% get coordinates of click
coords = eventData.IntersectionPoint;
% do something with the coordinates (e.g. add coordinates to table)
app.UITable.Data(end+1,:) = [coords(1),coords(2)];
end
end
To create run this example yourself, simply add a UIAxes and a UITable to your figure in the Design View of App Designer. Then add the code above to a StartupFcn.
Also, for an alternative method of getting clicked points, see this related MATLAB Answers post:
  2 Comments
Bernd Limburg
Bernd Limburg on 16 Dec 2020
Thanks, helped me to get mouse coordinates on an image object shown in the UIAxes. The callback function doesn't necessarily need to be a nested function. It can be a simple m file, too.
Creating the image anywhere in the app code:
image(app.myUIAxes, myImg, 'ButtonDownFcn', @ext_ImageButtonDown)
ext_ButtonDownFcn.m =>
function ext_ButtonDownFcn(app, event)
% get coordinates etc.
event.Button
event.IntersectionPoint
end

Sign in to comment.

More Answers (2)

Anders Skovlund Hansen
Anders Skovlund Hansen on 8 Oct 2020
Edited: Anders Skovlund Hansen on 8 Oct 2020
Hi,
Just an update to this post:
The "ButtonDownFcn" has now been added to UIAxes in the latest version R2020B.
I have just applied it in App Designer and it works fine.
Regards Anders.
  3 Comments
Luca Nagel
Luca Nagel on 14 Feb 2022
I have the same issue, it seems to not be fixed. I also noticed that the property ButtonDownFcn is empty after plotting.

Sign in to comment.


Cris LaPierre
Cris LaPierre on 19 Nov 2021
@Kyle: For images, you need to set the image object HitTest property to 'off' so the clicks can pass through the image to the axis, where the callback function has been added.
@Benjamin Gansemer: Like image objects, lines also have a HitTest property. If your callback is working fine except for when you click on the line, try setting the line's HitTest property to 'off'.
  1 Comment
Luca Nagel
Luca Nagel on 14 Feb 2022
In the description of HitTest property it says "If the PickableParts property is set to 'none' or if the HitTest property is set to 'off', then this callback does not execute. "
so does the ButtondownFcn excecute when HitTest is off or when it's on? This is kind of confusion. Also when plotting on an UIAxes, the ButtonDownFcn is cleared, is this normal?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!