<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oliver Woodford &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/tag/oliver-woodford/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Wed, 21 Jan 2015 18:00:02 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>
	<item>
		<title>export_fig</title>
		<link>https://undocumentedmatlab.com/articles/export_fig?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=export_fig</link>
					<comments>https://undocumentedmatlab.com/articles/export_fig#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 21 Jan 2015 18:00:02 +0000</pubDate>
				<category><![CDATA[Guest bloggers]]></category>
		<category><![CDATA[Handle graphics]]></category>
		<category><![CDATA[Medium risk of breaking in future versions]]></category>
		<category><![CDATA[File Exchange]]></category>
		<category><![CDATA[Oliver Woodford]]></category>
		<category><![CDATA[Pure Matlab]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=5470</guid>

					<description><![CDATA[<p>The export_fig utility enables publication-quality Matlab plotting output. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/export_fig">export_fig</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/capturing-print-events" rel="bookmark" title="Capturing print events">Capturing print events </a> <small>Matlab print events can be trapped by users to enable easy printout customization. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/multi-column-grid-legend" rel="bookmark" title="Multi-column (grid) legend">Multi-column (grid) legend </a> <small>This article explains how to use undocumented axes listeners for implementing multi-column plot legends...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-print-setup" rel="bookmark" title="Customizing print setup">Customizing print setup </a> <small>Matlab figures print-setup can be customized to automatically prepare the figure for printing in a specific configuration...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/graphic-sizing-in-matlab-r2015b" rel="bookmark" title="Graphic sizing in Matlab R2015b">Graphic sizing in Matlab R2015b </a> <small>Matlab release R2015b's new "DPI-aware" nature broke some important functionality. Here's what can be done... ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p><i>I would like to introduce guest blogger <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/profile/authors/1073021-oliver-woodford">Oliver Woodford</a>. For the past several years Oliver has been a top contributor on the Matlab File Exchange, and several of his utilities have earned the prestigious distinction as &#8220;Pick of the Week&#8221;. This is no easy feat in a File Exchange that hosts ~23K utilities at latest count. For the past few years, excluding short spans of time, Oliver&#8217;s <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/23629-export-fig"><b>export_fig</b></a> was the File Exchange&#8217;s most downloaded utility, by a wide margin. <b>export_fig</b> has improved the output quality of figures for so many numerous Matlab users that it is hard to imagine a Matlab File Exchange without it. Today, Oliver describes the basic technical mechanisms underlying <b>export_fig</b>.</i><br />
Yair has very kindly agreed to take over maintenance of <i><b>export_fig</b></i>. For his benefit, and anyone else&#8217;s interest, I will briefly describe the layout and functionality of the toolbox.<br />
Before starting, I always recommend that new users read the <a target="_blank" rel="nofollow" href="https://github.com/altmany/export_fig/blob/master/README.md">README file</a>, to get a better understanding of the available options, how the functions perform, how to do certain frequently-asked things, and what problems still remain. The following excerpt comes from the README file (please do read the entire file):<br />
If you&#8217;ve ever wondered what&#8217;s going on in the icon on the <i><b>export_fig</b></i> download page (reproduced below), then this explanation is for you: The icon is designed to demonstrate as many of <i><b>export_fig</b></i>&#8216;s features as possible. Given a figure containing a translucent mesh (top right), <i><b>export_fig</b></i> can export to pdf (bottom center), which allows the figure to be zoomed in without losing quality (because it&#8217;s a vector graphic), but isn&#8217;t able to reproduce the translucency, and also, depending on the viewer, creates small gaps between the patches, which are seen here as thin white lines. By contrast, when exporting to png (top left), translucency is preserved (see how the graphic below shows through), the figure is anti-aliased, but zooming-in does not reveal more detail.<br />
<center><figure style="width: 450px" class="wp-caption aligncenter"><a target="_blank" rel="nofollow" href="http://bit.ly/1yAD3o4"><img fetchpriority="high" decoding="async" alt="export_fig demo usage (click for details)" src="http://bit.ly/1yAD3o4" title="export_fig demo usage (click for details)" width="450" height="318" /></a><figcaption class="wp-caption-text"><i><b>export_fig</b></i> demo usage (click for details)</figcaption></figure></center><br />
<span id="more-5470"></span></p>
<h3 id="goals">Goals of <i>export_fig</i></h3>
<ol>
<li>
<h4 id="quality">Publication quality</h4>
<p>I wrote <i><b>export_fig</b></i> to produce nice looking figures for my PhD thesis and journal papers. The two standard MATLAB functions for exporting figures are <i><b>saveas</b></i> and <i><b>print</b></i>. Unfortunately, the quality of their default outputs just wasn&#8217;t good enough. For example, images in PDF outputs would be heavily compressed and I wanted control over image quality.<br />
<i>eps2pdf</i> (which is part of the <i><b>export_fig</b></i> package) takes a quality setting as input, and converts this into suitable settings for <i>ghostscript</i> to convert the EPS file to a PDF, allowing users to get much higher fidelity output. In addition, <i>ghostscript</i> also crops the figure border to the EPS bounding box, and embeds fonts in the PDF. This last feature is obligatory for some publications, and <i><b>export_fig</b></i> is sometimes recommended by conferences or journals for this reason. Control of JPEG quality is achieved by passing the quality option to <i><b>imwrite</b></i> in <i>export_fig.m</i>.<br />
In <i>export_fig.m</i>, I also added anti-aliasing for raster outputs (by exporting at a higher resolution and downsizing), and alpha-matting (by exporting with both black and white backgrounds to compute transparency) for PNG outputs. The alpha-matting feature allows textured backgrounds to show through the exported figure, which can be useful for presentation slides. Here is an image that demonstrates such alpha-matting:<br />
<center><figure style="width: 300px" class="wp-caption aligncenter"><img decoding="async" alt="Transparency alpha-matting" src="https://undocumentedmatlab.com/images/transparency_alpha_matting.png" title="Transparency alpha-matting" width="300" height="274" /><figcaption class="wp-caption-text">Transparency alpha-matting</figcaption></figure></center>
</li>
<li>
<h4 id="WYSIWYG">WYSIWYG (<i>what you see is what you get</i>)</h4>
<p>Another issue with <i><b>saveas</b></i> and <i><b>print</b></i> is that, by default, they do not reproduce a figure exactly as it appears on screen. The dimensions change, the aspect ratio changes, the amount of whitespace changes, the background color changes, the axes ticks change, line dash lengths change, the fonts change, etc. All these changes are generally-undesirable side-effects of those functions.<br />
<i><b>export_fig</b></i> avoids these changes to the figure, ensuring that it gets exported as faithfully as possible to the on screen visualization. <i><b>export_fig</b></i> uses <i><b>print</b></i> under the hood, but changes various figure and axes settings to get the desired result. For example, in <i>export_fig.m</i> I call <code>set(fig,'InvertHardcopy','off')</code>, which ensures that the background color doesn&#8217;t change. I also set the axes Limits and Tick modes to <code>'manual'</code>, to ensure that axes don&#8217;t change. Similarly, in <i>print2eps.m</i>, I call <code>set(fig, 'PaperPositionMode','auto', 'PaperOrientation','portrait')</code> to ensure that the figure dimensions don&#8217;t change for vector outputs.<br />
Two of the changes, line dash lengths and fonts, are caused by the Painters renderer, and so they only occur in vector output. The only way to fix these issues was to edit the EPS file that <i><b>print</b></i> generates: <i>fix_lines.m</i> changes the definition of dash lengths in the EPS file, so that the dash lengths depend on the line widths. Likewise, <i>print2eps.m</i> changes unsupported fonts in the figure to supported ones, then reinserts the unsupported font into the EPS. Unfortunately this doesn&#8217;t work so well when the two fonts have different character widths.<br />
In addition to these features, the MATLAB rendering pipeline (in both HG1 and HG2 versions) is full of bugs. Many lines of code in <i><b>export_fig</b></i> are dedicated to circumventing these undocumented bugs. For example, lines 249-273 of today&#8217;s <i>export_fig.m</i>:</p>
<pre lang='matlab'>
% MATLAB "feature": black colorbar axes can change to white and vice versa!
hCB = findobj(fig, 'Type', 'axes', 'Tag', 'Colorbar');
if isempty(hCB)
    yCol = [];
    xCol = [];
else
    yCol = get(hCB, 'YColor');
    xCol = get(hCB, 'XColor');
    if iscell(yCol)
        yCol = cell2mat(yCol);
        xCol = cell2mat(xCol);
    end
    yCol = sum(yCol, 2);
    xCol = sum(xCol, 2);
end
% MATLAB "feature": apparently figure size can change when changing colour in -nodisplay mode
pos = get(fig, 'Position');
% Set the background colour to black, and set size in case it was changed internally
tcol = get(fig, 'Color');
set(fig, 'Color', 'k', 'Position', pos);
% Correct the colorbar axes colours
set(hCB(yCol==0), 'YColor', [0 0 0]);
set(hCB(xCol==0), 'XColor', [0 0 0]);
</pre>
<p>Similarly, lines <i>143-160</i> of today&#8217;s <i>print2eps.m</i>:</p>
<pre lang='matlab'>
% MATLAB bug fix - black and white text can come out inverted sometimes
% Find the white and black text
black_text_handles = findobj(fig, 'Type', 'text', 'Color', [0 0 0]);
white_text_handles = findobj(fig, 'Type', 'text', 'Color', [1 1 1]);
% Set the font colors slightly off their correct values
set(black_text_handles, 'Color', [0 0 0] + eps);
set(white_text_handles, 'Color', [1 1 1] - eps);
% MATLAB bug fix - white lines can come out funny sometimes
% Find the white lines
white_line_handles = findobj(fig, 'Type', 'line', 'Color', [1 1 1]);
% Set the line color slightly off white
set(white_line_handles, 'Color', [1 1 1] - 0.00001);
% Print to eps file
print(fig, options{:}, name);
% Reset the font and line colors
set(black_text_handles, 'Color', [0 0 0]);
set(white_text_handles, 'Color', [1 1 1]);
set(white_line_handles, 'Color', [1 1 1]);
</pre>
</li>
</ol>
<h3 id="design">Design philosophy</h3>
<p>The <i><b>export_fig</b></i> toolbox is just a collection of functions. I put code into a separate function when either:</p>
<ol>
<li>One might want to use that functionality on its own, or</li>
<li>That functionality is required by two or more other functions.</li>
</ol>
<p>Subfunctions are used for code called multiple times in only one file, or where it improves legibility of the code.<br />
The easiest way to understand the structure of the <i><b>export_fig</b></i> toolbox is to visualize the tree of function dependencies within the toolbox:<br />
<center><figure style="width: 600px" class="wp-caption aligncenter"><a target="_blank" href="/images/export_fig.png"><img decoding="async" alt="export_fig overview (click for details)" src="https://undocumentedmatlab.com/images/export_fig.png" title="export_fig overview (click for details)" width="600" height="300" /></a><figcaption class="wp-caption-text"><i><b>export_fig</b></i> overview (click for details)</figcaption></figure></center><br />
I&#8217;ll now describe what each function does in a bit more detail:</p>
<ol>
<li>
<h4 id="export_fig"><i>export_fig</i></h4>
<p>This is the main function in the toolbox. It allows exporting a figure to several different file formats at once. It parses the input options. If only a subset of axes are being exported then it handles the transfer of these to a new figure (which gets destroyed at the end). It makes calls to <i>print2array()</i> for raster outputs, and <i>print2eps()</i> for vector outputs. For raster outputs, it also does the downsampling if anti-aliasing is enabled, and alphamatte computation if transparency is enabled. For vector outputs, it also does the conversion from eps to pdf, and also pdf back to eps. The reason for this last conversion is that the pdf is cropped, compressed and has the fonts embedded, and eps outputs should get this too (though I don&#8217;t think the font embedding remains).</li>
<li>
<h4 id="print2array"><i>print2array</i></h4>
<p>This function rasterizes the figure. If the painters algorithm is specified then it calls <i>print2eps()</i>, then rasterizes the resulting EPS file using ghostscript. If another renderer is specified then this function just calls <i><b>print</b>()</i> to output a bitmap. Finally, borders are cropped, if requested.</li>
<li>
<h4 id="print2eps"><i>print2eps</i></h4>
<p>This function calls <i><b>print</b>()</i> to generate an EPS file, then makes several fixes to the EPS file, including making dash lengths commensurate with line width (old graphics system (HG1) only, i.e. R2014a or earlier), and substituting back in unsupported fonts.</li>
<li>
<h4 id="crop_borders"><i>crop_borders</i></h4>
<p>Crops away any margin space surrounding the image(s): Given an image or stack of images (stacked along the 4th dimension), and a background color, <i>crop_borders()</i> computes the number of rows at the top and bottom and number of columns on the left and the right of the image(s) that are entirely the background color, and removes these rows and columns.</li>
<li>
<h4 id="ghostscript"><i>ghostscript</i></h4>
<p>This function looks for a Ghostscript executable. or asks the user to specify its location. It then stores the path, or simply loads the path if one is already stored. It then calls the Ghostscript executable with the specified arguments.</li>
<li>
<h4 id="fix_lines"><i>fix_lines</i></h4>
<p>This function makes dash lengths commensurate with line width, and converts grid lines from dashes to circular dots, in EPS files generated by MATLAB using HG1 (R2014a or earlier). <i><b>fix_lines</b></i> is also available as a separate <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/23604-fix-lines">File Exchange utility</a> (<a target="_blank" rel="nofollow" href="http://blogs.mathworks.com/pick/2010/01/15/fixing-postscript-lines/">selected</a> for Pick-of&#8211;the-Week, <a target="_blank" rel="nofollow" href="http://blogs.mathworks.com/pick/2010/05/28/creating-and-exporting-publication-quality-graphics/">just like</a> <i><b>export_fig</b></i>). This function is no longer required in HG2 (R2014b or newer) &#8211; see below.</li>
<li>
<h4 id="read_write_entire_textfile"><i>read_write_entire_textfile</i></h4>
<p>Does what it says, reading or writing and entire text file from/to disk to/from memory, but handles errors gracefully, not leaving files open.</li>
<li>
<h4 id="eps2pdf"><i>eps2pdf</i></h4>
<p>This function converts an EPS file into a PDF file using <a target="_blank" rel="nofollow" href="http://www.ghostscript.com">Ghostscript</a>.</li>
<li>
<h4 id="pdf2eps"><i>pdf2eps</i></h4>
<p>This function converts a PDF file into an EPS file using <i>pdftops</i>, from the <a target="_blank" rel="nofollow" href="http://www.foolabs.com/xpdf/">Xpdf package</a>.</li>
<li>
<h4 id="pdftops"><i>pdftops</i></h4>
<p>Does exactly the same thing as the <i>ghostscript</i> function, but for the <i>pdftops</i> executable instead.</li>
<li>
<h4 id="user_string"><i>user_string</i></h4>
<p>This stores or loads user-specific strings in text files. This allows user-specific values to propagate across different versions of MATLAB, whilst avoiding these values being stored in version controlled code.</li>
<li>
<h4 id="copyfig"><i>copyfig</i></h4>
<p>This function simply creates a copy of a figure, like the built-in <i><b>copyobj</b>()</i>. However, because the latter has some bugs, this function, which saves the figure to disk then opens it again, is required. Indeed, much of the code within the toolbox is simply circumventing bugs in MATLAB functions.</li>
<li>
<h4 id="isolate_axes"><i>isolate_axes</i></h4>
<p>This function removes unwanted axes from a figure. The approach to exporting a subset of axes is to copy the figure then remove the unwanted axes. Again, this is to circumvent bugs in the builtin function <i><b>copyobj</b>()</i>.</li>
<li>
<h4 id="using_hg2"><i>using_hg2</i></h4>
<p>This function provides a robust way of checking if HG2 is in use (HG1 is the default in R2014a or older; HG2 is the default in R2014b or newer).<br />
In HG2, the entire rendering pipeline has changed. While most of the features remain the same, the bugs have completely changed. For example, dash lengths in HG2 vector output are now sensible, so <i>fix_lines</i> is not required. However, in R2014b at least, patch-based graphics generate bloated EPS files, and line widths cannot go below 0.75pt. Finally, an obvious change for raster output is that it is smoothed by default, so anti-aliasing is not required; the default settings in the <i>parse_args()</i> function within <i>export_fig.m</i> reflect this.</li>
<li>
<h4 id="append_pdfs"><i>append_pdfs</i></h4>
<p><i><b>export_fig</b></i> does have a <code>-append</code> option, but this gets slower the larger the appended file becomes. A quicker way of generating a multipage PDF from several figures is to export them all to separate PDFs, then use this function to combine them into one in a single go. Also available as a separate <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/31215-append-pdfs">File Exchange utility</a>.</li>
<li>
<h4 id="im2gif"><i>im2gif</i></h4>
<p>This function converts a stack of images, or a multi-image TIFF file, to an animated GIF. <i><b>export_fig</b></i> can generate multi-image TIFFs using the <code>-append</code> option, making generating animated GIFs straightforward. Also available as a separate <a target="_blank" rel="nofollow" href="http://www.mathworks.com/matlabcentral/fileexchange/32546-im2gif">File Exchange utility</a>.</li>
</ol>
<p>And that&#8217;s it! All the functions have help text describing their input and output arguments.</p>
<h3 id="editorial">Editorial notes</h3>
<p><i>After several year of creating, improving and maintaining <i><b>export_fig</b></i>, Oliver is unfortunately no longer able to maintain this utility. As Oliver mentioned above, I (Yair) have volunteered to try to step into his shoes and maintain it. As Oliver&#8217;s detailed description (which barely scratches the surface) shows, this is certainly not a trivial utility. It will take me some time to get up to speed with all the internal technical details, so please be patient&#8230;<br />
Readers interested in high-fidelity export might also consider using my <a target="_blank" href="/articles/screencapture-utility">ScreenCapture utility</a>. Unlike <i><b>export_fig</b></i>, which uses Matlab&#8217;s builtin <i><b>print</b></i> function to generate (and fix) the output, <i><b>ScreenCapture</b></i> uses the standard <code>java.awt.Robot.<i>createScreenCapture()</i></code> to take an actual screen-capture of the requested figure, axes or window area and then saves this to file/clipboard or sends it to the printer. In a sense, the <i><b>export_fig</b></i> and <i><b>ScreenCapture</b></i> utilities nicely complement each other.<br />
</i></p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/export_fig">export_fig</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/capturing-print-events" rel="bookmark" title="Capturing print events">Capturing print events </a> <small>Matlab print events can be trapped by users to enable easy printout customization. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/multi-column-grid-legend" rel="bookmark" title="Multi-column (grid) legend">Multi-column (grid) legend </a> <small>This article explains how to use undocumented axes listeners for implementing multi-column plot legends...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/customizing-print-setup" rel="bookmark" title="Customizing print setup">Customizing print setup </a> <small>Matlab figures print-setup can be customized to automatically prepare the figure for printing in a specific configuration...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/graphic-sizing-in-matlab-r2015b" rel="bookmark" title="Graphic sizing in Matlab R2015b">Graphic sizing in Matlab R2015b </a> <small>Matlab release R2015b's new "DPI-aware" nature broke some important functionality. Here's what can be done... ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/export_fig/feed</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
	</channel>
</rss>
