You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
compiled app can not run mfiles in a folder
1 view (last 30 days)
Show older comments
Hi Al
Due to app designer limitations with saving a figure (version 2017b). I came up with the idea to write the savefig command in an mfile via app(create the mfile via my application) and save that mfile in my desired directory and run it via my app ( actually with matlab) by calling it from my application.
this was working untill I had my app open in MATLAB and not compiled because it was actually MATLAB who was running that mfile. Now after compiling, I noticed this trick does not work ! Any advices ? I have tried the other tricks like creating invisible fig un UIaxes but it did not work. at least for me
I do this in my app :
txt=['saveas(f,filename,''jpg'')'];
% edit file.m
FID=fopen('filem.txt','w');
fprintf(FID, '%s', txt);
fclose(FID);
% Rename File to Create M File
movefile('filem.txt','filem.m', 'f')
filem
I am not sure if doing so would solve the problem :
run('filem.m')
3 Comments
Mohammad Sami
on 2 Apr 2020
What is f. Is it a stanalone figure window ?
What were the limitations you were running into ?
I doubt a compiled app can run arbitrary code that you generate at runtime.
Mohammad Sami
on 2 Apr 2020
See Adam's answer if your limitation was with UIAxes.
farzad
on 2 Apr 2020
f is :
f = figure('visible', 'off');
I have tried another answer where it was suggeting to use hidden UIAXES and it did not work. are you sure the above answer will work after compiliing ?
I have a UIAxes panel in my app but it's for another purpose. will these two interfere ?I have also rainflow function to save
Accepted Answer
Walter Roberson
on 2 Apr 2020
You will never be able to generate a function or a script inside a compiled app and run it inside the compiled app.
Never
This is a deliberate design decision. You are permitted to compile code and run it without a MATLAB license under the restriction that the code to be executed cannot be changed. If you need the code to be executed to be changed, then you need a full MATLAB license to run it.
25 Comments
farzad
on 2 Apr 2020
dear Walter, thank you very much, but the best help for me : Is a Solution eventually ! there are several guides on other questions on how saving a figure via compiled application. But I have tried one of them and it did not work.
Could you please show me a solution that works guarantied to save a figure on a compiled application
Walter Roberson
on 2 Apr 2020
No, I cannot show you a solution that is guaranteed to save a uifigure on a compiled application.
App Designer is an evolving program that is still missing functionality. When I investigated briefly about two weeks ago, it appeared to me that there is currently no support in App Designer to save graphics from a uifigure into an image.
File Exchange contributions such as CopyUIAxes work around the problem by attempting to recreate plots into a traditional figure() and then using appropriate functions such as saveas() on the graphics that had been transfered into a traditional figure.
Walter Roberson
on 2 Apr 2020
I said clearly that I cannot show you any solution that is guaranteed
I also said that CopyUIAxes attempts to recreate plots; I did not say that it always succeeds. In fact, you can be certain that it will fail for all new graphics objects between the time of a MATLAB release and the time the author investigates and makes appropriate changes.
As someone who has written my own program that tries to deal with all possible graphics objects just for traditional figures, I can tell you that keeping up with the changes every release is a fair bit of work, and that large portions of the graphics implementation are not documented for users. There are functions inside some of the Toolboxes that actually change the representation of key graphics objects, and if you didn't happen to run those functions with the combination of options that provoke the behavior, then you would never know that it was even possible for there to be differences in the fields or datatypes of objects.
If Mathworks documented every graphics control structure, and made "interface contracts" about what could change and what could not, and what it could change to then maybe someone would be willing to guarantee something could work. But it certainly will not be me that makes such promises, precisely because I have an idea of how messy the graphics system really is.
farzad
on 2 Apr 2020
dear Walter ! your help which were steps taken way ahead of me by you, and allowing me to know them, as helped me a lot so far to write up and finish the backend of my code. for now I am only left a little perplexed.
for proper using of the CopyUIAxes function. shall you help me with it ?
in the example it goes as far as defining h=copyuiaxes(uiax)
but then, how do I save the figure ?
Walter Roberson
on 2 Apr 2020
As far as I know, after you CopyUIAxes, you can saveas() or print() the resulting traditional figure.
Adam Danz
on 2 Apr 2020
Edited: Adam Danz
on 2 Apr 2020
Hi all, I'm downloading 2020a right now, coincidentally, and will eventually test my FEX submissions.
@farzad, the idea of copyUIAxes, as Walter described, is to copy the content of a UIAxes to a regular axes within a regular figure that can then be saved. The basic workflow would look like this:
h = copyUIAxes(uiAxesHandle);
savefig(h.figure)
I haven't run this from a compiled app so I don't know if there will be any problems. Give it a shot and if there are any problems I can have a look.
Adam Danz
on 2 Apr 2020
Edited: Adam Danz
on 2 Apr 2020
As the file exchange page indicates, copyUIAxes has been tested and is compatible with R2016a and should be OK with any release following that (again, I haven't tested it with 20a yet).
farzad
on 2 Apr 2020
for handling subplots it's getting harder , where should I use the copyuiaxes command ?
in the first bulk of the code there is the example
fh = uifigure();
uiax = uiaxes(fh);
hold(uiax,'on')
grid(uiax,'on')
x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);
ph = scatter(uiax,x,y,25,linspace(1,10,200),'filled');
lh = plot(uiax, x, smooth(x,y), 'k-');
title(uiax,'copyUIaxes Demo','FontSize',18)
xlabel(uiax,'x axis')
ylabel(uiax,'y axis')
zlabel(uiax,'z axis')
cb = colorbar(uiax);
cb.Ticks = -2:2:12;
caxis(uiax,[-2,12])
ylabel(cb,'cb ylabel')
lh = legend(uiax,[ph,lh],{'Raw','lowess'},'Location','NorthEast');
drawnow()% all graphics to catch up before copying
% Ex 1: Copy axis to another figure
h = copyUIAxes(uiax);
here is my code, how should I nest these lines above ? regardless of variables
subplot(611);
plot(motion6t(:,1),motion6t(:,2));
grid;
ylabel('Tz (mm)');
subplot(612);
plot(motion6t(:,1),motion6t(:,3));
grid;
ylabel('Ty (mm)');
Adam Danz
on 2 Apr 2020
Edited: Adam Danz
on 2 Apr 2020
Downloading the function and testing it would take much less time than we're spending speculating whether it would work.
The function copies axes, not figures. So each subplot would need to be copied indpendently. But you can still preserve the subplot layout by creating the copy-figure and subplots ahead of time and specifying which axes to copy to. Here's an example.
% Create copy-figure
fig = figure();
% Create empty subplots
sp(1) = subplot(1,3,1);
sp(2) = subplot(1,3,2);
sp(3) = subplot(1,3,3);
% Copy each uiaxes subplot to the regular axes subplots
copyUIAxes(uiaxes1, sp(1))
copyUIAxes(uiaxes2, sp(2))
copyUIAxes(uiaxes3, sp(3))
Note that you'll need the handles to your UIAxes subplots.
Yes, copyUIAxes recreates the legend as the file description indicates.
I don't see the purpose in spending more time speculating whether it would work. Try it out, read the documentation at the top of the function and do your best to apply it to your needs. If you come accross problems, then we can continue the discussion.
farzad
on 2 Apr 2020
Sorry I am not speculating, I have merely problem in reconstructing it for my intention.
If I should have multiple uiaxes, as you have written now, I should also create multiple figures given that :
fh = uifigure();
uiax = uiaxes(fh);
but if I create multiple fh, then it won't be a subplot.
then, I also have to set the limits of my subplots so that all of them have the same vertical limits , so I do :
for kk =1:6
subplot(6,1,kk)
ylim([minlim, maxlim]);
end
with this , I don't know how to place my code and the uiaxes etc variables
Adam Danz
on 2 Apr 2020
"... I should also create multiple figures ..."
No, this is not correct. Please see my previous comment. The first few lines produce a figure with 3 empty subplots. The last 3 lines copy 3 UIAxes to the 3 empty subplots. If that is causing any problems, I'd by happy to know.
Example #2 in the copyUIAxes file also provides another relevant example.
I didn't understand your 2nd question about the axis limits. If the axis limits are set in your UIAxes, I believe they will be set in the copied axes as well. If you need to adjust the axes limits after you do all of the copying, you could use linkaxes(subHandles, 'y') where subHandles is a vector of subplot handles.
farzad
on 2 Apr 2020
Edited: farzad
on 4 Apr 2020
thank you , I think you have responded my second question. But still I am confused about the first. since if I start with your previous comment, I will have one empty figure and 3 subplots, but where do I define the 3 ( in my case actually 6) uiaxis handles ?
Adam Danz
on 2 Apr 2020
For this syntax,
copyUIAxes(uiaxes1, sp(1))
uiaxes1 is the handle to the UIAxes that you're copying.
If you're copying a UIAxes from appdesigner, that handle will often look like app.UIAxes1.
If you're creating the UIAxes using,
uiax = uiaxes()
then uiax is the handle.
If you're using subplot() to create the axes, then those are not UIAxes and you should be using Matlab's copyobj() to copy those axes to a new figure.
farzad
on 2 Apr 2020
I am confused again.
so should I do :
fh = figure();
app.uiax1 = uiaxes(fh);
uiax= app.uuiax1
then what should be h ?
h = copyUIAxes(uiax);
how many h's if I have 6 subplots ?
I did not understand your guide because I can't connect the first and second part of your comment. I mean if we have to
uiax=uiaxes()
then how do we relate it to
app.UIAxes1
Adam Danz
on 2 Apr 2020
Edited: Adam Danz
on 3 Apr 2020
Are you creating these subplots within your app code or do the subplots already exist as part of your app?
If you're creating the subplots in your app code, instead of using UIAxes, use regular axes produced by subplot() in an external figure. Then there's no need to copy anything.
If you're copying UIAxes that are embedded in your app, then please tell me what their handles are so I can provide an example using your variable names.
farzad
on 3 Apr 2020
The subplots are created exactly in these lines and it's one single figure. They should not be depicted in the embedded UIAxes app. they should only be saved.
but if there is no need to copy anything. why after compiling, no figure is opening and no figure is being saved ? how should I save the figures then ?
Mohammad Sami
on 3 Apr 2020
Since you are creating a new figure, perhaps use axes instead of uiaxes.
farzad
on 3 Apr 2020
Actually with figure visibility on, I can see the figure and with the function above I can save the figure only if the app is not compiled. shall you help me with this case ? how to save the figure without the need to create an mfile ? the savefig apparently does not work
f = figure('visible', 'on');
Adam Danz
on 3 Apr 2020
As you found, figure('visible', 'off') is the reason you couldn't see the figure. This problem has nothing to do with UIAxes; it has nothing to do with copying axes. A mini lesson to be learned here is to take time to understand the problem before trying random solutions.
"If I had only one hour to save the world, I would spend fifty-five minutes defining the problem, and only five minutes finding the solution." -Albert Einstein
First, get rid of the copyUIAxes stuff... it's completely irrelevant.
Second, to save your figure, use your figure handle, f:
savefig(f,'myFigure.fig')
More Answers (0)
See Also
Categories
Find more on Subplots 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!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)