MATLAB Answers

How can I save a figure within app designer?

702 views (last 30 days)
J. Webster
J. Webster on 27 Apr 2016
Edited: Adam Danz on 21 Dec 2020
I've developed an application using the new App Designer. I'd like to have users be able to click a button and save a figure to a .fig file, or some other image format.
function ButtonSaveFigureButtonPushed(app)
newfigure = figure;
copyobj(app.UIAxesAP, newfigure);
hgsave(newfigure, 'testFIgure.fig');
end
But that gave me the error...
Error using matlab.ui.control.UIAxes/copyElement (line 1219)
Functionality not supported with UIAxes. For more information, see Graphics Support in App Designer.
What's the best way to go about this?

  2 Comments

Devin Crawford
Devin Crawford on 4 Oct 2017
Based on the number of recent views this is still an open issue. I have the same problem/question using R2017a.
Eric Sargent
Eric Sargent on 9 Dec 2020
As of R2020b copyobj supports copying a UIAxes object.

Sign in to comment.

Accepted Answer

David
David on 4 Apr 2018
Edited: David on 4 Apr 2018
I spent some time on this for my own purposes. The trick is to save the individual values from the figure into local variables to be used in a figure as follows:
h = figure;
h.Visible = 'off';
x = UIAxes.XAxis.Parent.Children.XData;
y = UIAxes.XAxis.Parent.Children.YData;
plot(x,y)
lgndName1 = UIAxes.Legend.String{1};
lgd = legend(lgndName1);
lgd.Box = UIAxes.Legend.Box;
lgd.Location = UIAxes.Legend.Location;
h.CurrentAxes.YLabel.String = UIAxes.YLabel.String;
h.CurrentAxes.YLabel.FontSize = UIAxes.YLabel.FontSize;
h.CurrentAxes.XLabel.String = UIAxes.XLabel.String;
h.CurrentAxes.XLabel.FontSize = UIAxes.XLabel.FontSize;
h.CurrentAxes.Title.String = UIAxes.Title.String;
h.CurrentAxes.Title.FontSize = UIAxes.Title.FontSize;
h.CurrentAxes.XLim = [0 max(x)];
h.CurrentAxes.XLim = [0 max(y)+1];
saveas(h,SaveName,'jpg')
savefig(h,SaveName)
delete(h)
Notice I have the visibility off, because I don't want the user to see this going in the background.
Note: You will have to change "UIAxes" to whatever you've named your UI figure
You could also add more properties, but you will have to go into your figure and find the object name to use.
I hope this helps.
Edit: I should also mention that to get this to work as function, I had to make it a call function in a separate .m file. I made a function SaveFigures(UIAxes, SaveName) that is called when ButtonSaveFigureButtonPushed. I have multiple possible plots, which is why I allow the UIAxes to vary. (I use a switch case to make sure I save the correct plot.)

  7 Comments

Show 4 older comments
David
David on 15 Oct 2018
Eric, it might be easier to see your code. (Sorry for the delay, I did not get an email update on your comment.)
NE
NE on 5 Mar 2019
Just a quick remark on otherwise very useful reply:
h.CurrentAxes.XLim = [0 max(y)+1];
Shouldn't that be
h.CurrentAxes.YLim = [0 max(y)+1];
Eric Sargent
Eric Sargent on 9 Dec 2020
As of R2020b copyobj supports copying a UIAxes object.

Sign in to comment.

More Answers (14)

Joost
Joost on 2 Oct 2018
Edited: Joost on 3 Oct 2018
Inspired by David's answer , I came up with this solution which I believe is more generic. My UIAxes contains a lot of graphics objects (mostly patch objects) which are all copied to a temporary figure and then saved. I took over some UIAxes properties (axes limits and data aspect ratio), but you can add any other property you need there. Specify fileName yourself. I put a button called 'Snapshot' in the app with a callback that contains the code below. Matlab R2018a was used.
% Create a temporary figure with axes.
fig = figure;
fig.Visible = 'off';
figAxes = axes(fig);
% Copy all UIAxes children, take over axes limits and aspect ratio.
allChildren = app.UIAxes.XAxis.Parent.Children;
copyobj(allChildren, figAxes)
figAxes.XLim = app.UIAxes.XLim;
figAxes.YLim = app.UIAxes.YLim;
figAxes.ZLim = app.UIAxes.ZLim;
figAxes.DataAspectRatio = app.UIAxes.DataAspectRatio;
% Save as png and fig files.
saveas(fig, fileName, 'png');
savefig(fig, fileName);
% Delete the temporary figure.
delete(fig);

  12 Comments

Show 9 older comments
Joost
Joost on 23 Oct 2019
Thank you Steven.
Ans thanks for the praise Jichen.
Adam, nice work! Good that we can learn from each other and keep improving in this community.
jichen guo
jichen guo on 23 Oct 2019
Hi Stevan,
Okay, I understand and sorry for the trouble.

Sign in to comment.


Adam Danz
Adam Danz on 24 Mar 2019
Edited: Adam Danz on 21 Dec 2020
How can I save a figure within app designer?
Matlab r2016a or later
copyUIAxes(handle,parent) from the file exchange copies the content of uiaxes, and the legend and colorbar if requested, to a new figure. It's a substitute for Matlab's copyobj() which does not support uiaxes prior to r2020b.
% Example
fig = figure();
h = copyUIAxes(app.UIAxes, fig);
Alternatively, use a 3rd party app for screenshots.
Matlab r2020a or later
exportgraphics(obj,filename) stores a snapshot of a graphics object (axes or figure) to an image file (jpg,png,tiff,pdf,emf,eps,+more).
% Example
exportgraphics(app.UIFigure,'C:\Users\name\Documents\Matlab\AppImage.png')
copygraphics(obj) copies a snapshot of a graphics object (axes or figure) to the system's clipboard for each copy-paste.
Matlab r2020b or later
Options (see this Community Highlight for a review)
copyobj(handle,parent) copies a graphics handle, including uiaxes in r2020b+, to a parent.
% Example
fig = figure();
copiedAxes = copyobj(app.UIAxes, fig);
exportapp(fig,filename) exports a UIFigure to a an image file (JPEG, PNG, TIFF, or PDF).
% Example
exportapp(app.UIFigure, 'C:\Users\name\Documents\Matlab\AppImage.png')
F = getframe(ax) or F = getframe(fig) captures the axes or figure as it appears on the screen as a movie frame. getframe() has been around for a long time but its support for uifigures started in r2020b.
% Example
F = getframe(app.UIFigure);
fig = figure();
imshow(F.cdata,'Parent',fig)
This answer has been updated. The original answer is in a comment below.

  6 Comments

Show 3 older comments
Adam Danz
Adam Danz on 24 Oct 2019
@jichen guo, If you're using the approach from my answer, I suggest using the copyUIAxes() function I created which is an improved version of my answer. I'd be glad to get your feedback.
Ramu Pradip
Ramu Pradip on 21 Apr 2020
copyUIAxes was doing the trick! Thanks, but with 2 Y axes only one is copied to the new figure.
Adam Danz
Adam Danz on 21 Apr 2020
Thanks for the feedback, Ramu Pradip. I'll think about implementing yyaxis functionality in copyUIAxes.
In the mean time, here's a simple way to use copyUIAxes with yyaxis plots. It copies the left and right axes individually (creating two axes on top of eachother).
% Create yyaxis plot within uiaxes
fig = uifigure();
ax = uiaxes(fig);
yyaxis(ax, 'left')
plot(ax, 1:5, rand(1,5), '-')
ylabel(ax, 'left')
yyaxis(ax, 'right')
plot(ax, 1:.2:5, rand(1,21), 'o')
ylabel(ax, 'right')
xlabel(ax, 'x axis')
title(ax, 'Title')
% Copy left and right axes to the same figure
newFig = figure;
yyaxis(ax, 'left')
axLeft = copyUIAxes(ax, newFig);
yyaxis(ax, 'right')
axRight = copyUIAxes(ax, newFig);
% Make some changes to the right axes
axRight.axes.Color = 'none'; % make transparent
axRight.axes.XTick = []; % remove duplicate x-ticks
axRight.axes.XLabel = []; % remove duplicate x-label
axRight.axes.Title = []; % remove duplicate title

Sign in to comment.


Guilherme Salgado Braga
Guilherme Salgado Braga on 24 Feb 2018
According to the R2017b documentation on: https://www.mathworks.com/help/matlab/creating_guis/graphics-support-in-app-designer.html
Functions saveas and savefig are not yet supported.

  0 Comments

Sign in to comment.


Dharmendra Sharma
Dharmendra Sharma on 15 Jun 2018
Edited: Dharmendra Sharma on 15 Jun 2018
This is the one potential solution which works for me. First, plot the figure/figures in normal way without using uifigure for example see code below. Visibility is on in the following example-
figure('Name','Acc','NumberTitle','off','units','normalized','outerposition',[0 0 1 1])
Then create a separate matlab function file (and call that matlab function from matlab ui). the function may include code to extract figure properties and save the figures as png file. The following link explains the saving all the figures and the code as well-- see the link--
It just need some modifications and I included these in follwoing code-
function [] = handleFigures()
result = isfolder('figures');
if result==0
mkdir figures;
else
delete('figures/*.*')
end
FolderName = 'figures'; % Your destination folder
FigList = findobj(allchild(0), 'flat', 'Type', 'figure');
for iFig = 1:length(FigList)-1
FigHandle = FigList(iFig);
FigName = get(FigHandle, 'Name');
saveas(FigHandle, fullfile(FolderName, [FigName, '.png']))
end
disp('closing figures');
close all
end

  0 Comments

Sign in to comment.


Chao Gong
Chao Gong on 19 Jun 2019
Hello David:
I am using the same method answer by you David on 4 Apr 2018. However, I tried to open the saved .fig files afterwards using Matlab, but it doesn't open or respond. The .png files are saved nicely.
Do you encounter similar problem? Is there any possible reason why the saved .fig can't be open?
Thanks

  0 Comments

Sign in to comment.


Chao Gong
Chao Gong on 19 Jun 2019
Hi,
Found the issue of this problem. it's because the 'Visible' property is set 'off'. A workaroudn is as below.
--------
This is not currently possible in MATLAB.
As a workaround, please specify 'visible' option when calling 'openfig' to open the figure after it has been saved.
You can also set the "CreateFcn" property of the figure to a function which sets the "Visible" property to on. This allows you to save the figure when invisible but always make it visible when opening it later.
hFig = figure('Visible', 'off');
plot(1:10)
% Set CreateFcn callback
set(hFig, 'CreateFcn', 'set(gcbo,''Visible'',''on'')');
% Save Fig file
savefig(hFig, 'savedFigure.fig')

  0 Comments

Sign in to comment.


J. Webster
J. Webster on 28 Apr 2016
anybody??

  1 Comment

Tausif
Tausif on 10 Mar 2017
did u get a solution yet? I was looking to do the same

Sign in to comment.


Tobias Daßler
Tobias Daßler on 20 Dec 2017
I used a workaround:
saveas(gca,uiputfile({'*.png'; '*.fig'; '*.jpg'}));
close Plot;
Maybe you could adapt this for your problem.

  2 Comments

Adam Danz
Adam Danz on 24 Mar 2019
Functionality not supported with figures created with the uifigure function. So, this doesn't work with axes created in app designer.

Sign in to comment.


Craig Pearson
Craig Pearson on 8 Jan 2018
I'm having a similar problem and would like a solution. I was trying to use the print function to copy a figure to the clipboard.
Annoyingly, if I use debugging mode, once the figure is created I can quit debugging mode then use
print -dmeta
from the command window and it proceeds fine - I can then paste this into Excel from the command line (which is what I'm aiming to do from within the app).
Why can this not be achieved from within the App?

  0 Comments

Sign in to comment.


Blanca Larraga
Blanca Larraga on 4 Jun 2018
Is there a solution for saving the axes plot in a .jpeg format or not yet? I am trying to insert what I got un an axes figure within a report automatically in app designer but I don't manage to do so. Thanks.

  0 Comments

Sign in to comment.


Jyothi Karri
Jyothi Karri on 20 Jul 2018
I have the same issue. Cannot export a UIAxes from gui created from app designer. copyobj did not work either.

  1 Comment

Udo Schröder
Udo Schröder on 13 Aug 2018
I have the same issue. It would help if there would be a nice option just to map an UIAxes element into a normal (pop-up) figure. Then the figure could be saved with the common tools.

Sign in to comment.


Paramjeet Panwar
Paramjeet Panwar on 15 Oct 2018
My current workaround is identifying the pixel position of the UIFigure and UIAxes on the screen and taking a snapshot using Java libraries.
Refer to these links -
2 Using Java library for screenshot - this link

  0 Comments

Sign in to comment.


Eric Sargent
Eric Sargent on 9 Dec 2020
As of R2020b copyobj supports copying a UIAxes object.

  0 Comments

Sign in to comment.


Thamer Al-Zuriqat
Thamer Al-Zuriqat on 20 Dec 2020
Improved answer inspired by David and Joost , which is technically a combination of both solutions.
fig = figure;
fig.Visible = 'off';
figAxes = axes(fig);
% Copy all UIAxes children, take over axes limits and aspect ratio.
allChildren = app.UIAxes.XAxis.Parent.Children;
copyobj(allChildren, figAxes)
figAxes.XLim = app.UIAxes.XLim;
figAxes.YLim = app.UIAxes.YLim;
figAxes.ZLim = app.UIAxes.ZLim;
figAxes.DataAspectRatio = app.UIAxes.DataAspectRatio;
lgndName1 = app.UIAxes.Legend.String{1};
lgd = legend(lgndName1);
lgd.Box = app.UIAxes.Legend.Box;
lgd.Location = app.UIAxes.Legend.Location;
fig.CurrentAxes.YLabel.String = app.UIAxes.YLabel.String;
fig.CurrentAxes.YLabel.FontSize = app.UIAxes.YLabel.FontSize;
fig.CurrentAxes.XLabel.String = app.UIAxes.XLabel.String;
fig.CurrentAxes.XLabel.FontSize = app.UIAxes.XLabel.FontSize;
fig.CurrentAxes.Title.String = app.UIAxes.Title.String;
fig.CurrentAxes.Title.FontSize = app.UIAxes.Title.FontSize;
% Save as png and fig files.
saveas(fig, fileName, 'png');
savefig(fig, fileName);
% Delete the temporary figure.
delete(fig);

  0 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!