Changeset 24460 for issm/trunk-jpl/externalpackages/export_fig/export_fig.m
- Timestamp:
- 12/08/19 19:39:55 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/externalpackages/export_fig/export_fig.m
r21671 r24460 1 function [imageData, alpha] = export_fig(varargin) 1 function [imageData, alpha] = export_fig(varargin) %#ok<*STRCL1> 2 2 %EXPORT_FIG Exports figures in a publication-quality format 3 3 % … … 25 25 % export_fig ... -update 26 26 % export_fig ... -nofontswap 27 % export_fig ... -font_space <char> 27 28 % export_fig ... -linecaps 29 % export_fig ... -noinvert 30 % export_fig ... -preserve_size 31 % export_fig ... -options <optionsStruct> 28 32 % export_fig(..., handle) 29 33 % … … 38 42 % - Render images at native resolution (optional for bitmap formats) 39 43 % - Transparent background supported (pdf, eps, png, tif) 40 % - Semi-transparent patch objects supported (png & tif only)41 % - RGB, CMYK or grayscale output (CMYK only with pdf, eps, tif f)44 % - Semi-transparent patch objects supported (png, tif) 45 % - RGB, CMYK or grayscale output (CMYK only with pdf, eps, tif) 42 46 % - Variable image compression, including lossless (pdf, eps, jpg) 43 % - Optional ly append to file (pdf, tiff)44 % - Vector formats: pdf, eps45 % - Bitmap formats: png, tiff, jpg, bmp, export to workspace46 % - Rounded line-caps (optional; pdf & eps only)47 % - Optional rounded line-caps (pdf, eps) 48 % - Optionally append to file (pdf, tif) 49 % - Vector formats: pdf, eps, svg 50 % - Bitmap formats: png, tif, jpg, bmp, export to workspace 47 51 % 48 52 % This function is especially suited to exporting figures for use in … … 58 62 % background; only TIF & PNG formats support transparency of patch objects. 59 63 % 60 % The choice of renderer (opengl , zbuffer or painters) has a large impact61 % o n the quality of output. The default value (opengl for bitmaps, painters62 % for vector formats) generally gives good results, but if you aren't63 % satisfied then try another renderer. Notes: 1) For vector formats (EPS,64 % PDF), only painters generates vector graphics. 2) For bitmaps, only65 % opengl can render transparent patch objects correctly. 3) For bitmaps,66 % only painters will correctly scale line dash and dot lengths when67 % magnifying or anti-aliasing. 4) Fonts may be substitued with Courier when68 % using painters.64 % The choice of renderer (opengl/zbuffer/painters) has a large impact on the 65 % output quality. The default value (opengl for bitmaps, painters for vector 66 % formats) generally gives good results, but if you aren't satisfied 67 % then try another renderer. Notes: 68 % 1) For vector formats (EPS,PDF), only painters generates vector graphics 69 % 2) For bitmap formats, only opengl correctly renders transparent patches 70 % 3) For bitmap formats, only painters correctly scales line dash and dot 71 % lengths when magnifying or anti-aliasing 72 % 4) Fonts may be substitued with Courier when using painters 69 73 % 70 74 % When exporting to vector format (PDF & EPS) and bitmap format using the … … 72 76 % on your system. You can download this from: 73 77 % http://www.ghostscript.com 74 % When exporting to eps it additionally requires pdftops, from the Xpdf 75 % suite of functions. You can download this from: 76 % http://www.foolabs.com/xpdf 78 % When exporting to EPS it additionally requires pdftops, from the Xpdf 79 % suite of functions. You can download this from: http://xpdfreader.com 80 % 81 % SVG output uses the fig2svg (https://github.com/kupiqu/fig2svg) or plot2svg 82 % (https://github.com/jschwizer99/plot2svg) utilities, or Matlab's built-in 83 % SVG export if neither of these utilities are available on Matlab's path. 84 % Note: cropping/padding are not supported in export_fig's SVG output. 77 85 % 78 86 % Inputs: 79 87 % filename - string containing the name (optionally including full or 80 % relative path) of the file the figure is to be saved as. If 81 % a path is not specified, the figure is saved in the current 82 % directory. If no name and no output arguments are specified, 83 % the default name, 'export_fig_out', is used. If neither a 84 % file extension nor a format are specified, a ".png" is added 85 % and the figure saved in that format. 86 % -format1, -format2, etc. - strings containing the extensions of the 87 % file formats the figure is to be saved as. 88 % Valid options are: '-pdf', '-eps', '-png', 89 % '-tif', '-jpg' and '-bmp'. All combinations 90 % of formats are valid. 91 % -nocrop - option indicating that the borders of the output are not to 92 % be cropped. 88 % relative path) of the file the figure is to be saved as. If 89 % a path is not specified, the figure is saved in the current 90 % directory. If no name and no output arguments are specified, 91 % the default name, 'export_fig_out', is used. If neither a 92 % file extension nor a format are specified, a ".png" is added 93 % and the figure saved in that format. 94 % -<format> - string(s) containing the output file extension(s). Options: 95 % '-pdf', '-eps', '-svg', '-png', '-tif', '-jpg' and '-bmp'. 96 % Multiple formats can be specified, without restriction. 97 % For example: export_fig('-jpg', '-pdf', '-png', ...) 98 % Either '-tif','-tiff' can be specified, and either '-jpg','-jpeg'. 99 % -nocrop - option indicating that empty margins should not be cropped. 93 100 % -c[<val>,<val>,<val>,<val>] - option indicating crop amounts. Must be 94 101 % a 4-element vector of numeric values: [top,right,bottom,left] 95 102 % where NaN/Inf indicate auto-cropping, 0 means no cropping, 96 103 % and any other value mean cropping in pixel amounts. 97 % -transparent - option indicating that the figure background is to be 98 % made transparent (png, pdf, tif and eps output only).104 % -transparent - option indicating that the figure background is to be made 105 % transparent (PNG,PDF,TIF,EPS formats only). Implies -noinvert. 99 106 % -m<val> - option where val indicates the factor to magnify the 100 107 % on-screen figure pixel dimensions by when generating bitmap … … 116 123 % effects on image quality (disable with the -a1 option). 117 124 % -a1, -a2, -a3, -a4 - option indicating the amount of anti-aliasing to 118 % use for bitmap outputs. '-a1' means no anti-119 % aliasing;'-a4' is the maximum amount (default).125 % use for bitmap outputs. '-a1' means no anti-aliasing; 126 % '-a4' is the maximum amount (default). 120 127 % -<renderer> - option to force a particular renderer (painters, opengl or 121 % 122 % 123 % 128 % zbuffer). Default value: opengl for bitmap formats or 129 % figures with patches and/or transparent annotations; 130 % painters for vector formats without patches/transparencies. 124 131 % -<colorspace> - option indicating which colorspace color figures should 125 % be saved in: RGB (default), CMYK or gray. CMYK is only 126 % supported in pdf, eps and tiff output. 127 % -q<val> - option to vary bitmap image quality (in pdf, eps and jpg 128 % files only). Larger val, in the range 0-100, gives higher 129 % quality/lower compression. val > 100 gives lossless 130 % compression. Default: '-q95' for jpg, ghostscript prepress 131 % default for pdf & eps. Note: lossless compression can 132 % sometimes give a smaller file size than the default lossy 133 % compression, depending on the type of images. 132 % be saved in: RGB (default), CMYK or gray. Usage example: '-gray'. 133 % Note: CMYK is only supported in PDF, EPS and TIF formats. 134 % -q<val> - option to vary bitmap image quality (PDF, EPS, JPG formats only). 135 % A larger val, in the range 0-100, produces higher quality and 136 % lower compression. val > 100 results in lossless compression. 137 % Default: '-q95' for JPG, ghostscript prepress default for PDF,EPS. 138 % Note: lossless compression can sometimes give a smaller file size 139 % than the default lossy compression, depending on the image type. 134 140 % -p<val> - option to pad a border of width val to exported files, where 135 141 % val is either a relative size with respect to cropped image … … 139 145 % If used, the -nocrop flag will be ignored, i.e. the image will 140 146 % always be cropped and then padded. Default: 0 (i.e. no padding). 141 % -append - option indicating that if the file (pdfs only) already142 % exists, the figure is to be appended as a new page, instead143 % of being overwritten (default).147 % -append - option indicating that if the file already exists the figure is to 148 % be appended as a new page, instead of being overwritten (default). 149 % PDF & TIF output formats only. 144 150 % -bookmark - option to indicate that a bookmark with the name of the 145 % figure is to be created in the output file (pdfonly).151 % figure is to be created in the output file (PDF format only). 146 152 % -clipboard - option to save output as an image on the system clipboard. 147 % 153 % Note: background transparency is not preserved in clipboard 148 154 % -d<gs_option> - option to indicate a ghostscript setting. For example, 149 % 155 % -dMaxBitmap=0 or -dNoOutputFonts (Ghostscript 9.15+). 150 156 % -depsc - option to use EPS level-3 rather than the default level-2 print 151 157 % device. This solves some bugs with Matlab's default -depsc2 device … … 155 161 % done in vector formats (only): 11 standard Matlab fonts are 156 162 % replaced by the original figure fonts. This option prevents this. 163 % -font_space <char> - option to set a spacer character for font-names that 164 % contain spaces, used by EPS/PDF. Default: '' 157 165 % -linecaps - option to create rounded line-caps (vector formats only). 166 % -noinvert - option to avoid setting figure's InvertHardcopy property to 167 % 'off' during output (this solves some problems of empty outputs). 168 % -preserve_size - option to preserve the figure's PaperSize property in output 169 % file (PDF/EPS formats only; default is to not preserve it). 170 % -options <optionsStruct> - format-specific parameters as defined in Matlab's 171 % documentation of the imwrite function, contained in a struct under 172 % the format name. For example to specify the JPG Comment parameter, 173 % pass a struct such as this: options.JPG.Comment='abc'. Similarly, 174 % options.PNG.BitDepth=4. Valid only for PNG,TIF,JPG output formats. 158 175 % handle - The handle of the figure, axes or uipanels (can be an array of 159 % handles, but the objects must be in the same figure) to be160 % saved. Default: gcf.176 % handles, but the objects must be in the same figure) which is 177 % to be saved. Default: gcf (handle of current figure). 161 178 % 162 179 % Outputs: … … 248 265 % 22/03/17: Fixed issue #187: only set manual ticks when no exponent is present 249 266 % 09/04/17: Added -linecaps option (idea by Baron Finer, issue #192) 267 % 15/09/17: Fixed issue #205: incorrect tick-labels when Ticks number don't match the TickLabels number 268 % 15/09/17: Fixed issue #210: initialize alpha map to ones instead of zeros when -transparent is not used 269 % 18/09/17: Added -font_space option to replace font-name spaces in EPS/PDF (workaround for issue #194) 270 % 18/09/17: Added -noinvert option to solve some export problems with some graphic cards (workaround for issue #197) 271 % 08/11/17: Fixed issue #220: axes exponent is removed in HG1 when TickMode is 'manual' (internal Matlab bug) 272 % 08/11/17: Fixed issue #221: alert if the requested folder does not exist 273 % 19/11/17: Workaround for issue #207: alert when trying to use transparent bgcolor with -opengl 274 % 29/11/17: Workaround for issue #206: warn if exporting PDF/EPS for a figure that contains an image 275 % 11/12/17: Fixed issue #230: use OpenGL renderer when exported image contains transparency (also see issue #206) 276 % 30/01/18: Updated SVG message to point to https://github.com/kupiqu/plot2svg and display user-selected filename if available 277 % 27/02/18: Fixed issue #236: axes exponent cropped from output if on right-hand axes 278 % 29/05/18: Fixed issue #245: process "string" inputs just like 'char' inputs 279 % 13/08/18: Fixed issue #249: correct black axes color to off-black to avoid extra cropping with -transparent 280 % 27/08/18: Added a possible file-open reason in EPS/PDF write-error message (suggested by "craq" on FEX page) 281 % 22/09/18: Xpdf website changed to xpdfreader.com 282 % 23/09/18: Fixed issue #243: only set non-bold font (workaround for issue #69) in R2015b or earlier; warn if changing font 283 % 23/09/18: Workaround for issue #241: don't use -r864 in EPS/PDF outputs when -native is requested (solves black lines problem) 284 % 18/11/18: Issue #261: Added informative alert when trying to export a uifigure (which is not currently supported) 285 % 13/12/18: Issue #261: Fixed last commit for cases of specifying axes/panel handle as input, rather than a figure handle 286 % 13/01/19: Issue #72: Added basic SVG output support 287 % 04/02/19: Workaround for issues #207 and #267: -transparent implies -noinvert 288 % 08/03/19: Issue #269: Added ability to specify format-specific options for PNG,TIF,JPG outputs; fixed help section 289 % 21/03/19: Fixed the workaround for issues #207 and #267 from 4/2/19 (-transparent now does *NOT* imply -noinvert; -transparent output should now be ok in all formats) 290 % 12/06/19: Issue #277: Enabled preservation of figure's PaperSize in output PDF/EPS file 291 % 06/08/19: Remove warning message about obsolete JavaFrame in R2019b 292 % 30/10/19: Fixed issue #261: added support for exporting uifigures and uiaxes (thanks to idea by @MarvinILA) 250 293 %} 251 294 … … 266 309 % Ensure that we have a figure handle 267 310 if isequal(fig,-1) 268 return ;% silent bail-out311 return % silent bail-out 269 312 elseif isempty(fig) 270 313 error('No figure found'); 314 else 315 oldWarn = warning('off','MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame'); 316 warning off MATLAB:ui:javaframe:PropertyToBeRemoved 317 uifig = handle(ancestor(fig,'figure')); 318 try jf = get(uifig,'JavaFrame'); catch, jf=1; end 319 warning(oldWarn); 320 if isempty(jf) % this is a uifigure 321 %error('Figures created using the uifigure command or App Designer are not supported by export_fig. See <a href="https://github.com/altmany/export_fig/issues/261">issue #261</a> for details.'); 322 if numel(fig) > 1 323 error('export_fig:uifigure:multipleHandles', 'export_fig only supports exporting a single uifigure handle at a time; array of handles is not currently supported.') 324 elseif ~any(strcmpi(fig.Type,{'figure','axes'})) 325 error('export_fig:uifigure:notFigureOrAxes', 'export_fig only supports exporting a uifigure or uiaxes handle; other handles of a uifigure are not currently supported.') 326 end 327 % fig is either a uifigure or uiaxes handle 328 isUiaxes = strcmpi(fig.Type,'axes'); 329 if isUiaxes 330 % Label the specified axes so that we can find it in the legacy figure 331 oldUserData = fig.UserData; 332 tempStr = tempname; 333 fig.UserData = tempStr; 334 end 335 try 336 % Create an invisible legacy figure at the same position/size as the uifigure 337 hNewFig = figure('Units',uifig.Units, 'Position',uifig.Position, 'MenuBar','none', 'ToolBar','none', 'Visible','off'); 338 % Copy the uifigure contents onto the new invisible legacy figure 339 try 340 hChildren = allchild(uifig); %=uifig.Children; 341 copyobj(hChildren,hNewFig); 342 catch 343 warning('export_fig:uifigure:controls', 'Some uifigure controls cannot be exported by export_fig and will not appear in the generated output.'); 344 end 345 try fig.UserData = oldUserData; catch, end % restore axes UserData, if modified above 346 % Replace the uihandle in the input args with the legacy handle 347 if isUiaxes % uiaxes 348 % Locate the corresponding axes handle in the new legacy figure 349 hAxes = findall(hNewFig,'type','axes','UserData',tempStr); 350 if isempty(hAxes) % should never happen, check just in case 351 hNewHandle = hNewFig; % export the figure instead of the axes 352 else 353 hNewHandle = hAxes; % new axes handle found: use it instead of the uiaxes 354 end 355 else % uifigure 356 hNewHandle = hNewFig; 357 end 358 varargin(cellfun(@(c)isequal(c,fig),varargin)) = {hNewHandle}; 359 % Rerun export_fig on the legacy figure (with the replaced handle) 360 [imageData, alpha] = export_fig(varargin{:}); 361 % Delete the temp legacy figure and bail out 362 try delete(hNewFig); catch, end 363 return 364 catch err 365 % Clean up the temp legacy figure and report the error 366 try delete(hNewFig); catch, end 367 rethrow(err) 368 end 369 end 271 370 end 272 371 … … 337 436 % Set the FontWeight of axes labels/titles to 'normal' 338 437 % Fix issue #69: set non-bold font only if the string contains symbols (\beta etc.) 339 texLabels = findall(fig, 'type','text', 'FontWeight','bold'); 340 symbolIdx = ~cellfun('isempty',strfind({texLabels.String},'\')); 341 set(texLabels(symbolIdx), 'FontWeight','normal'); 438 % Issue #243: only set non-bold font (workaround for issue #69) in R2015b or earlier 439 try isPreR2016a = verLessThan('matlab','8.7'); catch, isPreR2016a = true; end 440 if isPreR2016a 441 texLabels = findall(fig, 'type','text', 'FontWeight','bold'); 442 symbolIdx = ~cellfun('isempty',strfind({texLabels.String},'\')); 443 if ~isempty(symbolIdx) 444 set(texLabels(symbolIdx), 'FontWeight','normal'); 445 warning('export_fig:BoldTexLabels', 'Bold labels with Tex symbols converted into non-bold in export_fig (fix for issue #69)'); 446 end 447 end 342 448 end 343 449 catch … … 365 471 366 472 % Set to print exactly what is there 367 set(fig, 'InvertHardcopy', 'off'); 473 if options.invert_hardcopy 474 try set(fig, 'InvertHardcopy', 'off'); catch, end % fail silently in uifigures 475 end 476 368 477 % Set the renderer 369 478 switch options.renderer … … 377 486 renderer = '-opengl'; % Default for bitmaps 378 487 end 488 489 hImages = findall(fig,'type','image'); 379 490 380 491 % Handle transparent patches … … 390 501 elseif ~options.png && ~options.tif % issue #168 391 502 warning('export_fig:transparency', '%s\nTo export the transparency correctly, try using the ScreenCapture utility on the Matlab File Exchange: http://bit.ly/1QFrBip', msg); 503 end 504 elseif ~isempty(hImages) 505 % Fix for issue #230: use OpenGL renderer when exported image contains transparency 506 for idx = 1 : numel(hImages) 507 cdata = get(hImages(idx),'CData'); 508 if any(isnan(cdata(:))) 509 hasTransparency = true; 510 break 511 end 392 512 end 393 513 end … … 428 548 set(hCB(yCol==0), 'YColor', [0 0 0]); 429 549 set(hCB(xCol==0), 'XColor', [0 0 0]); 550 % Correct black axes color to off-black (issue #249) 551 hAxes = findall(fig, 'Type','axes'); 552 hXs = fixBlackAxle(hAxes, 'XColor'); 553 hYs = fixBlackAxle(hAxes, 'YColor'); 554 hZs = fixBlackAxle(hAxes, 'ZColor'); 430 555 431 556 % The following code might cause out-of-memory errors … … 445 570 set(hCB(yCol==3), 'YColor', [1 1 1]); 446 571 set(hCB(xCol==3), 'XColor', [1 1 1]); 572 % Revert the black axes colors 573 set(hXs, 'XColor', [0,0,0]); 574 set(hYs, 'YColor', [0,0,0]); 575 set(hZs, 'ZColor', [0,0,0]); 447 576 448 577 % The following code might cause out-of-memory errors … … 487 616 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3; 488 617 % Save the png 489 imwrite(A, [options.name '.png'], 'Alpha', double(alpha), 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res); 618 [format_options, bitDepth] = getFormatOptions(options, 'png'); %Issue #269 619 if ~isempty(bitDepth) && bitDepth < 16 && size(A,3) == 3 620 % BitDepth specification requires using a color-map 621 [A, map] = rgb2ind(A, 256); 622 imwrite(A, map, [options.name '.png'], 'Alpha',double(alpha), 'ResolutionUnit','meter', 'XResolution',res, 'YResolution',res, format_options{:}); 623 else 624 imwrite(A, [options.name '.png'], 'Alpha',double(alpha), 'ResolutionUnit','meter', 'XResolution',res, 'YResolution',res, format_options{:}); 625 end 490 626 % Clear the png bit 491 627 options.png = false; … … 544 680 if options.alpha 545 681 imageData = A; 546 alpha = zeros(size(A, 1), size(A, 2), 'single');682 alpha = ones(size(A, 1), size(A, 2), 'single'); 547 683 end 548 684 end … … 550 686 if options.png 551 687 res = options.magnify * get(0, 'ScreenPixelsPerInch') / 25.4e-3; 552 imwrite(A, [options.name '.png'], 'ResolutionUnit', 'meter', 'XResolution', res, 'YResolution', res); 688 [format_options, bitDepth] = getFormatOptions(options, 'png'); %Issue #269 689 if ~isempty(bitDepth) && bitDepth < 16 && size(A,3) == 3 690 % BitDepth specification requires using a color-map 691 [A, map] = rgb2ind(A, 256); 692 imwrite(A, map, [options.name '.png'], 'ResolutionUnit','meter', 'XResolution',res, 'YResolution',res, format_options{:}); 693 else 694 imwrite(A, [options.name '.png'], 'ResolutionUnit','meter', 'XResolution',res, 'YResolution',res, format_options{:}); 695 end 553 696 end 554 697 if options.bmp … … 561 704 quality = 95; 562 705 end 706 format_options = getFormatOptions(options, 'jpg'); %Issue #269 563 707 if quality > 100 564 imwrite(A, [options.name '.jpg'], 'Mode', 'lossless');708 imwrite(A, [options.name '.jpg'], 'Mode','lossless', format_options{:}); 565 709 else 566 imwrite(A, [options.name '.jpg'], 'Quality', quality);710 imwrite(A, [options.name '.jpg'], 'Quality',quality, format_options{:}); 567 711 end 568 712 end … … 580 724 end 581 725 append_mode = {'overwrite', 'append'}; 582 imwrite(A, [options.name '.tif'], 'Resolution', options.magnify*get(0, 'ScreenPixelsPerInch'), 'WriteMode', append_mode{options.append+1}); 726 format_options = getFormatOptions(options, 'tif'); %Issue #269 727 imwrite(A, [options.name '.tif'], 'Resolution',options.magnify*get(0,'ScreenPixelsPerInch'), 'WriteMode',append_mode{options.append+1}, format_options{:}); 583 728 end 584 729 end … … 590 735 if hasTransparency || hasPatches 591 736 % This is *MUCH* slower, but more accurate for patches and transparent annotations (issue #39) 592 renderer = '- painters'; %ISSM fix737 renderer = '-opengl'; 593 738 else 594 739 renderer = '-painters'; … … 624 769 end 625 770 % Generate the options for print 626 p2eArgs = {renderer, sprintf('-r%d', options.resolution)}; 771 printArgs = {renderer}; 772 if ~isempty(options.resolution) % issue #241 773 printArgs{end+1} = sprintf('-r%d', options.resolution); 774 end 627 775 if options.colourspace == 1 % CMYK 628 776 % Issue #33: due to internal bugs in Matlab's print() function, we can't use its -cmyk option 629 %p 2eArgs{end+1} = '-cmyk';777 %printArgs{end+1} = '-cmyk'; 630 778 end 631 779 if ~options.crop 632 780 % Issue #56: due to internal bugs in Matlab's print() function, we can't use its internal cropping mechanism, 633 781 % therefore we always use '-loose' (in print2eps.m) and do our own cropping (in crop_borders) 634 %p 2eArgs{end+1} = '-loose';782 %printArgs{end+1} = '-loose'; 635 783 end 636 784 if any(strcmpi(varargin,'-depsc')) 637 785 % Issue #45: lines in image subplots are exported in invalid color. 638 786 % The workaround is to use the -depsc parameter instead of the default -depsc2 639 p 2eArgs{end+1} = '-depsc';787 printArgs{end+1} = '-depsc'; 640 788 end 641 789 try 790 % Remove background if requested (issue #207) 791 originalBgColor = get(fig, 'Color'); 792 [hXs, hYs, hZs] = deal([]); 793 if options.transparent %&& ~isequal(get(fig, 'Color'), 'none') 794 if options.renderer == 1 % OpenGL 795 warning('export_fig:openglTransparentBG', '-opengl sometimes fails to produce transparent backgrounds; in such a case, try to use -painters instead'); 796 end 797 798 % Fix for issue #207, #267 (corrected) 799 set(fig,'Color','none'); 800 801 % Correct black axes color to off-black (issue #249) 802 hAxes = findall(fig, 'Type','axes'); 803 hXs = fixBlackAxle(hAxes, 'XColor'); 804 hYs = fixBlackAxle(hAxes, 'YColor'); 805 hZs = fixBlackAxle(hAxes, 'ZColor'); 806 end 642 807 % Generate an eps 643 print2eps(tmp_nam, fig, options, p2eArgs{:}); 808 print2eps(tmp_nam, fig, options, printArgs{:}); 809 % { 644 810 % Remove the background, if desired 645 if options.transparent && ~isequal(get(fig, 'Color'), 'none')811 if options.transparent %&& ~isequal(get(fig, 'Color'), 'none') 646 812 eps_remove_background(tmp_nam, 1 + using_hg2(fig)); 647 end 813 814 % Revert the black axes colors 815 set(hXs, 'XColor', [0,0,0]); 816 set(hYs, 'YColor', [0,0,0]); 817 set(hZs, 'ZColor', [0,0,0]); 818 end 819 %} 820 % Restore the figure's previous background color (if modified) 821 try set(fig,'Color',originalBgColor); drawnow; catch, end 648 822 % Fix colorspace to CMYK, if requested (workaround for issue #33) 649 823 if options.colourspace == 1 % CMYK … … 671 845 % Alert in case of error creating output PDF/EPS file (issue #179) 672 846 if exist(pdf_nam_tmp, 'file') 673 error(['Could not create ' pdf_nam ' - perhaps the folder does not exist, or you do not have write permissions']); 847 errMsg = ['Could not create ' pdf_nam ' - perhaps the folder does not exist, or you do not have write permissions, or the file is open in another application']; 848 error(errMsg); 674 849 else 675 850 error('Could not generate the intermediary EPS file.'); … … 677 852 end 678 853 catch ex 854 % Restore the figure's previous background color (in case it was not already restored) 855 try set(fig,'Color',originalBgColor); drawnow; catch, end 679 856 % Delete the eps 680 857 delete(tmp_nam); 858 % Rethrow the EPS/PDF-generation error 681 859 rethrow(ex); 682 860 end … … 718 896 end 719 897 end 898 % Issue #206: warn if the figure contains an image 899 if ~isempty(hImages) && strcmpi(renderer,'-opengl') % see addendum to issue #206 900 warnMsg = ['exporting images to PDF/EPS may result in blurry images on some viewers. ' ... 901 'If so, try to change viewer, or increase the image''s CData resolution, or use -opengl renderer, or export via the print function. ' ... 902 'See <a href="matlab:web(''https://github.com/altmany/export_fig/issues/206'',''-browser'');">issue #206</a> for details.']; 903 warning('export_fig:pdf_eps:blurry_image', warnMsg); 904 end 905 end 906 907 % SVG format 908 if options.svg 909 oldUnits = get(fig,'Units'); 910 filename = [options.name '.svg']; 911 % Adapted from Dan Joshea's https://github.com/djoshea/matlab-save-figure : 912 try %if verLessThan('matlab', '8.4') 913 % Try using the fig2svg/plot2svg utilities 914 try 915 fig2svg(filename, fig); %https://github.com/kupiqu/fig2svg 916 catch 917 plot2svg(filename, fig); %https://github.com/jschwizer99/plot2svg 918 warning('export_fig:SVG:plot2svg', 'export_fig used the plot2svg utility for SVG output. Better results may be gotten via the fig2svg utility (https://github.com/kupiqu/fig2svg).'); 919 end 920 catch %else % (neither fig2svg nor plot2svg are available) 921 % Try Matlab's built-in svg engine (from Batik Graphics2D for java) 922 try 923 set(fig,'Units','pixels'); % All data in the svg-file is saved in pixels 924 printArgs = {renderer}; 925 if ~isempty(options.resolution) 926 printArgs{end+1} = sprintf('-r%d', options.resolution); 927 end 928 print(fig, '-dsvg', printArgs{:}, filename); 929 warning('export_fig:SVG:print', 'export_fig used Matlab''s built-in SVG output engine. Better results may be gotten via the fig2svg utility (https://github.com/kupiqu/fig2svg).'); 930 catch err % built-in print() failed - maybe an old Matlab release (no -dsvg) 931 set(fig,'Units',oldUnits); 932 filename = strrep(filename,'export_fig_out','filename'); 933 msg = ['SVG output is not supported for your figure: ' err.message '\n' ... 934 'Try one of the following alternatives:\n' ... 935 ' 1. saveas(gcf,''' filename ''')\n' ... 936 ' 2. fig2svg utility: https://github.com/kupiqu/fig2svg\n' ... % Note: replaced defunct https://github.com/jschwizer99/plot2svg with up-to-date fork on https://github.com/kupiqu/fig2svg 937 ' 3. export_fig to EPS/PDF, then convert to SVG using non-Matlab tools\n']; 938 error(sprintf(msg)); %#ok<SPERR> 939 end 940 end 941 % SVG output was successful if we reached this point 942 % Restore original figure units 943 set(fig,'Units',oldUnits); 944 % Add warning about unsupported export_fig options with SVG output 945 if any(~isnan(options.crop_amounts)) || any(options.bb_padding) 946 warning('export_fig:SVG:options', 'export_fig''s SVG output does not [currently] support cropping/padding.'); 947 end 720 948 end 721 949 … … 726 954 else 727 955 % Reset the hardcopy mode 728 set(fig, 'InvertHardcopy', old_mode);956 try set(fig, 'InvertHardcopy', old_mode); catch, end % fail silently in uifigures 729 957 % Reset the axes limit and tick modes 730 958 for a = 1:numel(Hlims) … … 775 1003 error(javachk('awt', 'export_fig -clipboard output')); 776 1004 catch 777 warning('export_fig -clipboard output failed: requires Java to work');1005 warning('export_fig:clipboardJava', 'export_fig -clipboard output failed: requires Java to work'); 778 1006 return; 779 1007 end … … 821 1049 cb.setContents(imSelection, []); 822 1050 catch 823 warning('export_fig -clipboard output failed: %s', lasterr); %#ok<LERR>1051 warning('export_fig:clipboardFailed', 'export_fig -clipboard output failed: %s', lasterr); %#ok<LERR> 824 1052 end 825 1053 end … … 835 1063 fprintf(2, 'Please ensure:\n'); 836 1064 fprintf(2, ' that you are using the <a href="https://github.com/altmany/export_fig/archive/master.zip">latest version</a> of export_fig\n'); 837 if ismac 838 fprintf(2, ' and that you have <a href="http://pages.uoregon.edu/koch">Ghostscript</a> installed\n'); 839 else 840 fprintf(2, ' and that you have <a href="http://www.ghostscript.com">Ghostscript</a> installed\n'); 1065 if isvector(options) 1066 if ismac 1067 fprintf(2, ' and that you have <a href="http://pages.uoregon.edu/koch">Ghostscript</a> installed\n'); 1068 else 1069 fprintf(2, ' and that you have <a href="http://www.ghostscript.com">Ghostscript</a> installed\n'); 1070 end 841 1071 end 842 1072 try 843 1073 if options.eps 844 fprintf(2, ' and that you have <a href="http:// www.foolabs.com/xpdf">pdftops</a> installed\n');1074 fprintf(2, ' and that you have <a href="http://xpdfreader.com/download.html">pdftops</a> installed\n'); 845 1075 end 846 1076 catch … … 866 1096 % Default options used by export_fig 867 1097 options = struct(... 868 'name', 'export_fig_out', ... 869 'crop', true, ... 870 'crop_amounts', nan(1,4), ... % auto-crop all 4 image sides 871 'transparent', false, ... 872 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters 873 'pdf', false, ... 874 'eps', false, ... 875 'png', false, ... 876 'tif', false, ... 877 'jpg', false, ... 878 'bmp', false, ... 879 'clipboard', false, ... 880 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray 881 'append', false, ... 882 'im', false, ... 883 'alpha', false, ... 884 'aa_factor', 0, ... 885 'bb_padding', 0, ... 886 'magnify', [], ... 887 'resolution', [], ... 888 'bookmark', false, ... 889 'closeFig', false, ... 890 'quality', [], ... 891 'update', false, ... 892 'fontswap', true, ... 893 'linecaps', false, ... 894 'gs_options', {{}}); 1098 'name', 'export_fig_out', ... 1099 'crop', true, ... 1100 'crop_amounts', nan(1,4), ... % auto-crop all 4 image sides 1101 'transparent', false, ... 1102 'renderer', 0, ... % 0: default, 1: OpenGL, 2: ZBuffer, 3: Painters 1103 'pdf', false, ... 1104 'eps', false, ... 1105 'svg', false, ... 1106 'png', false, ... 1107 'tif', false, ... 1108 'jpg', false, ... 1109 'bmp', false, ... 1110 'clipboard', false, ... 1111 'colourspace', 0, ... % 0: RGB/gray, 1: CMYK, 2: gray 1112 'append', false, ... 1113 'im', false, ... 1114 'alpha', false, ... 1115 'aa_factor', 0, ... 1116 'bb_padding', 0, ... 1117 'magnify', [], ... 1118 'resolution', [], ... 1119 'bookmark', false, ... 1120 'closeFig', false, ... 1121 'quality', [], ... 1122 'update', false, ... 1123 'fontswap', true, ... 1124 'font_space', '', ... 1125 'linecaps', false, ... 1126 'invert_hardcopy', true, ... 1127 'format_options', struct, ... 1128 'preserve_size', false, ... 1129 'gs_options', {{}}); 895 1130 end 896 1131 897 1132 function [fig, options] = parse_args(nout, fig, varargin) 898 1133 % Parse the input arguments 1134 1135 % Convert strings => chars 1136 varargin = cellfun(@str2char,varargin,'un',false); 899 1137 900 1138 % Set the defaults … … 931 1169 case 'eps' 932 1170 options.eps = true; 1171 case 'svg' 1172 options.svg = true; 933 1173 case 'png' 934 1174 options.png = true; … … 957 1197 options.im = true; 958 1198 options.alpha = true; 959 case 'svg'960 msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ...961 ' 1. saveas(gcf,''filename.svg'')\n' ...962 ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ...963 ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n'];964 error(sprintf(msg)); %#ok<SPERR>965 1199 case 'update' 966 1200 % Download the latest version of export_fig into the export_fig folder … … 969 1203 folderName = fileparts(which(mfilename('fullpath'))); 970 1204 targetFileName = fullfile(folderName, datestr(now,'yyyy-mm-dd.zip')); 971 urlwrite(zipFileName,targetFileName); 1205 urlwrite(zipFileName,targetFileName); %#ok<URLWR> 972 1206 catch 973 1207 error('Could not download %s into %s\n',zipFileName,targetFileName); … … 982 1216 case 'nofontswap' 983 1217 options.fontswap = false; 1218 case 'font_space' 1219 options.font_space = varargin{a+1}; 1220 skipNext = true; 984 1221 case 'linecaps' 985 1222 options.linecaps = true; 1223 case 'noinvert' 1224 options.invert_hardcopy = false; 1225 case 'preserve_size' 1226 options.preserve_size = true; 1227 case 'options' 1228 % Issue #269: format-specific options 1229 inputOptions = varargin{a+1}; 1230 %options.format_options = inputOptions; 1231 if isempty(inputOptions), continue, end 1232 formats = fieldnames(inputOptions(1)); 1233 for idx = 1 : numel(formats) 1234 optionsStruct = inputOptions.(formats{idx}); 1235 %optionsCells = [fieldnames(optionsStruct) struct2cell(optionsStruct)]'; 1236 formatName = regexprep(lower(formats{idx}),{'tiff','jpeg'},{'tif','jpg'}); 1237 options.format_options.(formatName) = optionsStruct; %=optionsCells(:)'; 1238 end 1239 skipNext = true; 986 1240 otherwise 987 1241 try … … 1044 1298 [p, options.name, ext] = fileparts(varargin{a}); 1045 1299 if ~isempty(p) 1300 % Issue #221: alert if the requested folder does not exist 1301 if ~exist(p,'dir'), error(['Folder ' p ' does not exist!']); end 1046 1302 options.name = [p filesep options.name]; 1047 1303 end … … 1072 1328 end 1073 1329 case '.svg' 1074 msg = ['SVG output is not supported by export_fig. Use one of the following alternatives:\n' ... 1075 ' 1. saveas(gcf,''filename.svg'')\n' ... 1076 ' 2. plot2svg utility: http://github.com/jschwizer99/plot2svg\n' ... 1077 ' 3. export_fig to EPS/PDF, then convert to SVG using generic (non-Matlab) tools\n']; 1078 error(sprintf(msg)); %#ok<SPERR> 1330 options.svg = true; 1079 1331 otherwise 1080 1332 options.name = varargin{a}; … … 1127 1379 % If requested, set the resolution to the native vertical resolution of the 1128 1380 % first suitable image found 1129 if native && isbitmap(options) 1130 % Find a suitable image 1131 list = findall(fig, 'Type','image', 'Tag','export_fig_native'); 1132 if isempty(list) 1133 list = findall(fig, 'Type','image', 'Visible','on'); 1134 end 1135 for hIm = list(:)' 1136 % Check height is >= 2 1137 height = size(get(hIm, 'CData'), 1); 1138 if height < 2 1139 continue 1140 end 1141 % Account for the image filling only part of the axes, or vice versa 1142 yl = get(hIm, 'YData'); 1143 if isscalar(yl) 1144 yl = [yl(1)-0.5 yl(1)+height+0.5]; 1145 else 1146 yl = [min(yl), max(yl)]; % fix issue #151 (case of yl containing more than 2 elements) 1147 if ~diff(yl) 1381 if native 1382 if isbitmap(options) 1383 % Find a suitable image 1384 list = findall(fig, 'Type','image', 'Tag','export_fig_native'); 1385 if isempty(list) 1386 list = findall(fig, 'Type','image', 'Visible','on'); 1387 end 1388 for hIm = list(:)' 1389 % Check height is >= 2 1390 height = size(get(hIm, 'CData'), 1); 1391 if height < 2 1148 1392 continue 1149 1393 end 1150 yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1)); 1151 end 1152 hAx = get(hIm, 'Parent'); 1153 yl2 = get(hAx, 'YLim'); 1154 % Find the pixel height of the axes 1155 oldUnits = get(hAx, 'Units'); 1156 set(hAx, 'Units', 'pixels'); 1157 pos = get(hAx, 'Position'); 1158 set(hAx, 'Units', oldUnits); 1159 if ~pos(4) 1160 continue 1161 end 1162 % Found a suitable image 1163 % Account for stretch-to-fill being disabled 1164 pbar = get(hAx, 'PlotBoxAspectRatio'); 1165 pos = min(pos(4), pbar(2)*pos(3)/pbar(1)); 1166 % Set the magnification to give native resolution 1167 options.magnify = abs((height * diff(yl2)) / (pos * diff(yl))); % magnification must never be negative: issue #103 1168 break 1169 end 1394 % Account for the image filling only part of the axes, or vice versa 1395 yl = get(hIm, 'YData'); 1396 if isscalar(yl) 1397 yl = [yl(1)-0.5 yl(1)+height+0.5]; 1398 else 1399 yl = [min(yl), max(yl)]; % fix issue #151 (case of yl containing more than 2 elements) 1400 if ~diff(yl) 1401 continue 1402 end 1403 yl = yl + [-0.5 0.5] * (diff(yl) / (height - 1)); 1404 end 1405 hAx = get(hIm, 'Parent'); 1406 yl2 = get(hAx, 'YLim'); 1407 % Find the pixel height of the axes 1408 oldUnits = get(hAx, 'Units'); 1409 set(hAx, 'Units', 'pixels'); 1410 pos = get(hAx, 'Position'); 1411 set(hAx, 'Units', oldUnits); 1412 if ~pos(4) 1413 continue 1414 end 1415 % Found a suitable image 1416 % Account for stretch-to-fill being disabled 1417 pbar = get(hAx, 'PlotBoxAspectRatio'); 1418 pos = min(pos(4), pbar(2)*pos(3)/pbar(1)); 1419 % Set the magnification to give native resolution 1420 options.magnify = abs((height * diff(yl2)) / (pos * diff(yl))); % magnification must never be negative: issue #103 1421 break 1422 end 1423 elseif options.resolution == 864 % don't use -r864 in vector mode if user asked for -native 1424 options.resolution = []; % issue #241 (internal Matlab bug produces black lines with -r864) 1425 end 1426 end 1427 end 1428 1429 % Convert a possible string => char (issue #245) 1430 function value = str2char(value) 1431 if isa(value,'string') 1432 value = char(value); 1170 1433 end 1171 1434 end … … 1304 1567 hAxes = Hlims(idx(idx2)); 1305 1568 props = {[ax 'TickMode'],'manual', [ax 'TickLabelMode'],'manual'}; 1306 if isempty(strtrim(hAxes.([ax 'Ruler']).SecondaryLabel.String)) 1307 set(hAxes, props{:}); % no exponent, so update moth ticks and tick labels to manual 1569 tickVals = get(hAxes,[ax 'Tick']); 1570 tickStrs = get(hAxes,[ax 'TickLabel']); 1571 try % Fix issue #236 1572 exponents = [hAxes.([ax 'Axis']).SecondaryLabel]; 1573 catch 1574 exponents = [hAxes.([ax 'Ruler']).SecondaryLabel]; 1575 end 1576 if isempty([exponents.String]) 1577 % Fix for issue #205 - only set manual ticks when the Ticks number match the TickLabels number 1578 if numel(tickVals) == numel(tickStrs) 1579 set(hAxes, props{:}); % no exponent and matching ticks, so update both ticks and tick labels to manual 1580 end 1308 1581 end 1309 1582 catch % probably HG1 1310 set(hAxes, props{:}); % revert back to old behavior 1583 % Fix for issue #220 - exponent is removed in HG1 when TickMode is 'manual' (internal Matlab bug) 1584 if isequal(tickVals, str2num(tickStrs)') %#ok<ST2NM> 1585 set(hAxes, props{:}); % revert back to old behavior 1586 end 1311 1587 end 1312 1588 end … … 1332 1608 end 1333 1609 end 1610 1611 function hBlackAxles = fixBlackAxle(hAxes, axleName) 1612 hBlackAxles = []; 1613 for idx = 1 : numel(hAxes) 1614 ax = hAxes(idx); 1615 axleColor = get(ax, axleName); 1616 if isequal(axleColor,[0,0,0]) || isequal(axleColor,'k') 1617 hBlackAxles(end+1) = ax; %#ok<AGROW> 1618 end 1619 end 1620 set(hBlackAxles, axleName, [0,0,0.01]); % off-black 1621 end 1622 1623 % Issue #269: format-specific options 1624 function [optionsCells, bitDepth] = getFormatOptions(options, formatName) 1625 bitDepth = []; 1626 try 1627 optionsStruct = options.format_options.(lower(formatName)); 1628 catch 1629 % User did not specify any extra parameters for this format 1630 optionsCells = {}; 1631 return 1632 end 1633 optionNames = fieldnames(optionsStruct); 1634 optionVals = struct2cell(optionsStruct); 1635 optionsCells = [optionNames, optionVals]'; 1636 if nargout < 2, return, end % bail out if BitDepth is not required 1637 try 1638 idx = find(strcmpi(optionNames,'BitDepth'), 1, 'last'); 1639 if ~isempty(idx) 1640 bitDepth = optionVals{idx}; 1641 end 1642 catch 1643 % never mind - ignore 1644 end 1645 end
Note:
See TracChangeset
for help on using the changeset viewer.