Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exporting uifigure #261

Closed
MarvinILA opened this issue Nov 15, 2018 · 14 comments
Closed

Exporting uifigure #261

MarvinILA opened this issue Nov 15, 2018 · 14 comments

Comments

@MarvinILA
Copy link

MarvinILA commented Nov 15, 2018

Hi,

I am trying to use the export_fig code within the Matlab App Designer. I am trying to export the figure with the following code:

export_fig(figureHandle, path2file, '-pdf', '-png', '-m1.5');

However, as I execute the code the following error is shown:

Error using matlab.ui.Figure/set
Functionality not supported with figures created with the uifigure function. For more information,
see Graphics Support in App Designer.

Error in export_fig (line 397)
        set(fig, 'InvertHardcopy', 'off');

How can I run export_fig with uifigures?

Thanks a lot!

@altmany
Copy link
Owner

altmany commented Nov 18, 2018

Figures created using App Designer or the uifigure command are not supported by export_fig, as long as Matlab does not support the built-in print function with such figures. This is still the case as of R2018b:
https://www.mathworks.com/help/releases/R2018b/matlab/creating_guis/graphics-support-in-app-designer.html

There is no possible solution or workaround for uifigures until this changes.

altmany added a commit that referenced this issue Nov 18, 2018
@apiccirilli
Copy link

apiccirilli commented Dec 12, 2018

I think this last commit may have broken the ability to specify an individual axes to plot: with a new install of export_fig, you can run this to recreate:

f = figure();
ax = axes();
plot(ax, 1:10, sin(1:10));
export_fig(ax, 'test.png')

which gives you the error:

Undefined function or variable 'jf'.

Error in export_fig (line 298)
        if isempty(jf)

This seems to happen because there is no JavaFrame property for axes, and is fixed by either checking for the existence of jf on line 298 (if exist('jf', 'var') && isempty(jf)) or by adding some logic/assignment to your catch clause there.

Hope that helps, and thanks for maintaining such a great library.
Aaron

altmany added a commit that referenced this issue Dec 13, 2018
@altmany
Copy link
Owner

altmany commented Dec 13, 2018

Fixed, please recheck

@altmany altmany closed this as completed Dec 13, 2018
@apiccirilli
Copy link

All good - thanks!

@ghost
Copy link

ghost commented Jan 18, 2019

Thanks for the alert.
Does export_fig work with appDesigner in version 2018a?

@altmany
Copy link
Owner

altmany commented Jan 19, 2019

On Nov 18, 2018 above I wrote "This is still the case as of R2018b", so why are you asking about 2018a?!

export_fig does not work with uifigures (created by AppDesigner or the uifigure command), in any Matlab release. When this will change (if ever), I will post an update.

@MarvinILA
Copy link
Author

What you can do, however, is to copy your uifigure into a "standard" figure-window in the background. Use the "copy object" command to copy the uifigure's children into the new figure. Export that copied figure as usual. Maybe some formatting is still required.

@ghost
Copy link

ghost commented Jan 21, 2019

I

On Nov 18, 2018 above I wrote "This is still the case as of R2018b", so why are you asking about 2018a?!

export_fig does not work with uifigures (created by AppDesigner or the uifigure command), in any Matlab release. When this will change (if ever), I will let post an update.

I also found that "annotation" does not work. Very frustration after following the AppDesigner route.

@alfredoqt
Copy link

@MarvinILA how do yo do that?

@MarvinILA
Copy link
Author

MarvinILA commented Oct 30, 2019

@alfredoqt that's pretty easy. Please find below my code. Of course you might have to do some adjustments for your case.

% Convert UIFigure to normal figure
fig = figure('Units', app.YourPlot.Units, 'Position', app.YourPlot.Position, 'InnerPosition', app.YourPlot.InnerPosition, 'OuterPosition', app.YourPlot.OuterPosition);

% Set figure to be invisible
set(fig, 'MenuBar', 'none', 'ToolBar', 'none', 'Visible', 'off');

% Get figure axes
figAxes = axes(fig);

% Get all the children from the UIFigure
allChildren = app.YourPlot.Children;

% Copy all children to the new figure
copyobj(allChildren, figAxes)

% Set axes limits
figAxes.XLim = app.YourPlot.XLim;
figAxes.YLim = app.YourPlot.YLim;
figAxes.ZLim = app.YourPlot.ZLim;

% Modify the legend
lgndName = app.YourPlot.Legend.String;
lgd = legend(YourPlotsToAppearInTheLegend, lgndName);
lgd.Box = app.YourPlot.Legend.Box;
lgd.Location = app.YourPlot.Legend.Location;
lgd.FontSize = app.YourPlot.Legend.FontSize;

% Set axes labels
figAxes.YLabel.String = app.YourPlot.YLabel.String;
figAxes.YLabel.FontSize = app.YourPlot.YLabel.FontSize;
figAxes.XLabel.String = app.YourPlot.XLabel.String;
figAxes.XLabel.FontSize = app.YourPlot.XLabel.FontSize;

% Set title
figAxes.Title.String = app.YourPlot.Title.String;
figAxes.Title.FontSize = app.YourPlot.Title.FontSize;

% Honestly, I don't remeber why I set that color
fig.Color = [1 1 1];

% Export figure
export_fig(fig, biplotFNfull, '-pdf', '-png', '-eps', '-m5');

% Clean up
delete(fig)

Note the following:

  • replace YourPlot with the UIFigure/Axes element name you chose in your app.
  • replace YourPlotsToAppearInTheLegend with a vector of the plot elements, e.g. lines, you want a legend string to be displayed.

Good luck coding!

@altmany
Copy link
Owner

altmany commented Oct 30, 2019

@MarvinILA - that's a great idea. I'm sorry that I missed it when you first posted it earlier this year. I'll integrate it into export_fig later today/tomorrow.

@altmany altmany reopened this Oct 30, 2019
@altmany
Copy link
Owner

altmany commented Oct 30, 2019

Fixed.

There are still a few limitations, but I expect them to affect only a very small percentage of users:

  1. only uifigure and uiaxes handles can be specified, but not panel handles as in legacy figures
  2. only a single handle at a time can be exported - not an array of handles as with legacy figures
  3. exporting a combination of uifigure and legacy figure handles is not supported
  4. uicontrols within the uifigures are not exported

Thanks again, @MarvinILA !

Enjoy!

@Dev-iL
Copy link

Dev-iL commented Nov 20, 2019

Yair, might I suggest you add a note about the partial support for uifigure to the main README.md? I think your previous reply regarding the print function shouldn't be hidden within some closed bug report.

BTW, I'm experimenting with exporting those figures via webpage-to-pdf JS libraries (like https://github.com/niklasvh/html2canvas and https://github.com/MrRio/jsPDF), but I'm struggling with the limitations TMW keeps imposing on custom JS libraries (despite supposedly allowing them through uihtml).

At the moment one can use hWebWin.executeJS('print()'); if they're fine with dealing with the OS print dialog.

@altmany
Copy link
Owner

altmany commented Nov 30, 2019

@Dev-iL - done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants