Getting data from the figure in appdesigner

22 views (last 30 days)
Arash
Arash on 4 Feb 2020
Commented: Arash on 10 Feb 2020
Hi.
In my app, there is a section that lets user to select multiple points from a figure and later these points will be used to show some results. when I run this app in the matlab appdesigner space, everything works fine, However, when I complie the app by deploytool and create a standalone application,after installing the app and checking it, it doesn't save the selected points. in the picture, the top part is for when running the app within appdedesigner space and the bottom part is when I run it from the windows (after compiling and installing it on my compute). I am using the below code for getting information from a figure.
dcm_obj = datacursormode(fig);
set(dcm_obj,'DisplayStyle','datatip',...
'SnapToDataVertex','off','Enable','on')
pause
c_info = getCursorInfo(dcm_obj)
close gcf
I would really appreciate if anyone can tell me what should I do?
Picture1.jpg
  7 Comments
Arash
Arash on 7 Feb 2020
Actually it is my fiirst time to work with appdesigner, it's good thing for students to see the results without getting confuse with coding. That is why I insisted to make a standalone software. But again now the difference is just that they have to open the matlab and go to apps tab and run the app. I am sure, I am not doing things 100% in a professional way. But to answer your question, Yes I break my main code to different functions that each of them does seperate things. when a button is pushed, the function is activated. I hope in future to do it in like Object-oriented way but for now on everything is in functions and the function regarding selecting point is this:
I appreciate your time and suggestions in advance.
function [x,y]=ManuallySelect(Displ,Force);
fig = figure('units','normalized','outerposition',[0 0 1 1]);
plot([0 0],[-max(abs(Force)) max(abs(Force))],'k',[-max(abs(Displ)) max(abs(Displ))],[0 0],'k');hold on;
plot( Displ,Force,'LineWidth',1.1);grid on
dcm_obj = datacursormode(fig);
set(dcm_obj,'DisplayStyle','datatip',...
'SnapToDataVertex','off','Enable','on')
pause
c_info = getCursorInfo(dcm_obj)
close gcf
x=zeros(length(c_info),1);
y=zeros(length(c_info),1);
for i=1:length(c_info);
x(i,:)=c_info(i).Position(1);
y(i,:)=c_info(i).Position(2);
end
end
% The call back in the app:
% Callback function
function ClickMePositiveButtonPushed(app, event)
%Getting the global variable displacement and force
y1=app.Displ;
y2=app.Force;
[x,y]=ManuallySelect(y1,y2);
%saving it in the global propertise of the pp (DbackP and FbackP) to use it later
app.DbackP=x;
app.FbackP=y;
end
J. Alex Lee
J. Alex Lee on 7 Feb 2020
I don't see anything wrong structurally, so I was wrong in my assumption.
Admittedly I don't know the getcursorinfo function, as it is in a toolbox I don't have, but I bet the problem is that nothing after calling "ManuallySelect()" is executing within your callback, either because of getCursorInfo itself, or how you are relying on pause().
I'm not sure if there's a better way using debug tools, but you can output something to console like
function ClickMePositiveButtonPushed(app, event)
%Getting the global variable displacement and force
y1=app.Displ;
y2=app.Force;
[x,y]=ManuallySelect(y1,y2);
disp('hi, checking if this executes!')
%saving it in the global propertise of the pp (DbackP and FbackP) to use it later
app.DbackP=x;
app.FbackP=y;
end
and try to catch it in your deployed app by running it via command line.
But yes, it would probably be cleaner to set up a way to respond to click callback's on the plotted object.

Sign in to comment.

Answers (1)

J. Alex Lee
J. Alex Lee on 8 Feb 2020
Here's an example where I used the data cursor's update function itself to collect the coordinates and feed directly into your app's DbackP and FbackP properties.
I think it should be easy enough to plug and play into your app.
Does it work?
  3 Comments
J. Alex Lee
J. Alex Lee on 10 Feb 2020
It looks like the offending line was "xline" and "yline", but you were actually able to open/run in your version of app designer otherwise. But I exported to .m as well. Does this work?
The important parts that we have been discussing are to pass the app to the ManuallySelect function so that it has direct access to the DbackP and FbackP properties
function results = ManuallySelect(app,xIn,yIn)
% clear the saved data?
app.DbackP = [];
app.FbackP = [];
app.UITable.Data = {};
app.DataFig = figure(); %'units','normalized','outerposition',[0 0 1 1]);
app.DataFig.CloseRequestFcn = @(src,evnt)CloseDataFig(app,src,evnt);
ax = axes(app.DataFig,'NextPlot','add','XGrid','on','YGrid','on'); % hold on
% if your matlab version supports
try
xline(0);
yline(0);
catch
% better than
plot([0 0],[-max(abs(Force)) max(abs(Force))],'k',[-max(abs(Displ)) max(abs(Displ))],[0 0],'k');
end
plot(ax,xIn,yIn,'LineWidth',1.1);
dcm_obj = datacursormode(app.DataFig);
set(dcm_obj,'DisplayStyle','datatip',...
'SnapToDataVertex','off','Enable','on')
dcm_obj.UpdateFcn = @(src,evnt)dateTipUpdateFcn(app,src,evnt);
end
And in define a new UpdateFcn for the dcm_obj that also has access to the app; in its callback function, keep appending new points and define the tooltip text
function txt = dateTipUpdateFcn(app,src,evnt)
app.DbackP = [app.DbackP;evnt.Position(1)];
app.FbackP = [app.FbackP;evnt.Position(2)];
txt = sprintf('saved point: (%g,%g)',evnt.Position);
app.UITable.Data = num2cell([app.DbackP,app.FbackP]);
end
Just for demo, I also had a uitable that was displaying all of the chosen data in real time.
Arash
Arash on 10 Feb 2020
Now everything is fine Alex. Thank you for all your suggestions.

Sign in to comment.

Categories

Find more on Develop Apps Using App Designer in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!