<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog:  R tips and tricks:  Producing smooth bitmap plots</title>
    <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title> R tips and tricks:  Producing smooth bitmap plots</title>
      <description>&lt;p&gt;The &lt;a href="http://www.r-project.org/"&gt;R statistics system&lt;/a&gt; can produce
first-class data visualizations, commonly known as plots.  Internally,
plots are represented in an abstract graphics format that can be
rendered on any of R&amp;#8217;s wide range of graphics &amp;#8220;devices&amp;#8221; to produce
concrete output &amp;#8211; windows, bitmap files, PostScript files, &lt;span class="caps"&gt;PDF&lt;/span&gt; files,
and others.&lt;/p&gt;


	&lt;p&gt;The bitmap formats, such as &lt;span class="caps"&gt;PNG&lt;/span&gt;, are preferred for posting
plots online because of their widespread support by web browsers.  The
default bitmap-rendering devices in R, unfortunately, produce graphics
that look a little too &amp;#8220;bitmapped&amp;#8221; for modern web tastes.  Here, for example,
is a plot rendered by R&amp;#8217;s &amp;#8220;png&amp;#8221; device:&lt;/p&gt;


&lt;div class="photo"&gt;

	&lt;p&gt;&lt;img src="http://community.moertel.com/~thor/blog/pix-20070825/plot.png" title="Plot rendered via R's PNG device" alt="Plot rendered via R's PNG device" /&gt;&lt;/p&gt;


&lt;/div&gt;

	&lt;p&gt;There&amp;#8217;s nothing technically wrong with the plot, but it looks out
of place on a web page.  That&amp;#8217;s because modern web
browsers use font-smoothing and anti-aliasing techniques to render
just about everything else on the page.  Against this clean, un-jagged
backdrop, the oh-so-bitmapped plot looks like a throwback to
a previous era.&lt;/p&gt;


	&lt;p&gt;Happily, we &lt;em&gt;can&lt;/em&gt; produce clean, anti-aliased R plots with a little
help.  Here&amp;#8217;s the earlier plot, anti-aliased:&lt;/p&gt;


&lt;div class="photo"&gt;

	&lt;p&gt;&lt;img src="http://community.moertel.com/~thor/blog/pix-20070825/plot2.png" title="Plot rendered via R's PDF device, then post-processed" alt="Plot rendered via R's PDF device, then post-processed" /&gt;&lt;/p&gt;


&lt;/div&gt;

	&lt;p&gt;To produce the anti-aliased plot, I used R to produce a &lt;span class="caps"&gt;PDF&lt;/span&gt; file.  Then I
rendered the &lt;span class="caps"&gt;PDF&lt;/span&gt; file into a &lt;span class="caps"&gt;PNG&lt;/span&gt; image at 300 dpi using Ghostscript.
Finally, I scaled the 300-dpi image down to screen resolution,
producing a high-quality, anti-aliased result.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the recipe in detail.&lt;/p&gt;


	&lt;p&gt;First, I define an R function called &lt;em&gt;pdfit&lt;/em&gt; that takes an
abstract graphics object and makes a &lt;span class="caps"&gt;PDF&lt;/span&gt;-file rendering of it, using
my preferred graphics-device settings:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;require("lattice")

pdfit &amp;lt;- function(f, ...) {
  trellis.device(dev=pdf, theme="col.whitebg", ...);
  print(f);
  dev.off()
}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then, when I create a plot I want to publish, I use &lt;em&gt;pdfit&lt;/em&gt; to render
it into a &lt;span class="caps"&gt;PDF&lt;/span&gt; file:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;P.img &amp;lt;- xyplot( subs.low + subs.high ~ date, ... )

pdfit(P.img, file="image-downloads.pdf")  # render plot into PDF file
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Finally, I use &lt;a href="http://www.ghostscript.com/"&gt;Ghostscript&lt;/a&gt; and
&lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt; to convert the &lt;span class="caps"&gt;PDF&lt;/span&gt; file into
a high-quality, anti-aliased &lt;span class="caps"&gt;PNG&lt;/span&gt; file.  (I keep both formats: the &lt;span class="caps"&gt;PDF&lt;/span&gt;
file is best for publishing in printed papers, and the &lt;span class="caps"&gt;PNG&lt;/span&gt; file is
best for posting online.)  I use a simple Makefile to automate the
process of converting the &lt;span class="caps"&gt;PDF&lt;/span&gt; files into &lt;span class="caps"&gt;PNG&lt;/span&gt; files:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# Makefile (GNU make)

pdfs := $(wildcard *.pdf)
pngs := $(pdfs:.pdf=.png)

all: $(pngs)
.PHONY: all

%.png: %.pdf
    gs -dSAFTER -dBATCH -dNOPAUSE -sDEVICE=png16m \
       -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -r300 \
       -dBackgroundColor='16#ffffff' \
       -sOutputFile=$@ &amp;gt; /dev/null \
       $&amp;lt; &amp;#38;&amp;#38; \
    mogrify -resize 500 $@
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;With this Makefile in my graphics directory, just a single &amp;#8220;make&amp;#8221; 
command is all it takes to convert my &lt;span class="caps"&gt;PDF&lt;/span&gt; images into
anti-aliased &lt;span class="caps"&gt;PNG&lt;/span&gt; files, ready to post online.&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s it.&lt;/p&gt;


	&lt;p&gt;Do you have any tips or tricks for making good-looking graphics with
R?  If so, please do share.&lt;/p&gt;


&lt;div class="update"&gt;

	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;  There is one downside to the sexy, anti-aliased plots: they
are not as compressible as the old-style jagged plots.  For the
images above, for instance, the anti-aliased &lt;span class="caps"&gt;PNG&lt;/span&gt; file weighs in
at 45&amp;#160;KB, but the original &lt;span class="caps"&gt;PNG&lt;/span&gt; file is a feathery 4.7&amp;#160;KB.
So, if bandwidth is precious to you &amp;#8211; or you&amp;#8217;re planning on getting
Slashdotted &amp;#8211; you might want to stick
with the jaggies.&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Sat, 25 Aug 2007 21:56:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:c0e03deb-df96-4c4b-aea7-a4d9a256421b</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots</link>
      <category>statistics</category>
      <category>R</category>
      <category>statistics</category>
      <category>plots</category>
      <category>graphics</category>
      <category>tips</category>
      <category>tricks</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/550</trackback:ping>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Ryan J. Parker</title>
      <description>&lt;p&gt;Wow I&amp;#8217;m glad I finally found this. I&amp;#8217;ve had an issue with blocky PNGs from R for some time. This works great on my Linux box.&lt;/p&gt;


	&lt;p&gt;My image is only 16k, so not too bad. If it gets out of control I&amp;#8217;ll try out some of the suggestions above.&lt;/p&gt;


	&lt;p&gt;Thanks again.&lt;/p&gt;</description>
      <pubDate>Tue, 28 Oct 2008 00:56:33 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:654ae8c0-5686-47be-807f-fef32f29c95b</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-836</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Ana Nelson</title>
      <description>&lt;p&gt;This is also a useful approach if you are plotting a very large number of data points, for example data generated from a simulation, in which case a raster image file may actually be smaller and load much faster than a vector image which has to render each plotted data point individually.&lt;/p&gt;</description>
      <pubDate>Sun, 02 Sep 2007 17:29:45 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:1ed18927-4a6a-480c-b3a1-262cd777b2aa</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-564</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Tom Moertel</title>
      <description>&lt;p&gt;Thibault and Howard, I&amp;#8217;m completely in agreement that vector formats are the best way to represent plots.  The problem is that on the web there is no ubiquitously supported vector format.&lt;/p&gt;


	&lt;p&gt;Flash has fairly widespread support, but it is far from universal and additionally requires the use of a proprietary plug-in, making it unacceptable for people who prefer an open pipeline to the reader&amp;#8217;s eyeballs.  SVG is more open and has the hope of being integrated into future web browsers, and the &lt;a href="http://www.darkridge.com/~jake/RSvg/"&gt;RSvgDevice&lt;/a&gt; CRAN package lets R produce SVG output, but &lt;a href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics#Support_for_SVG_in_browsers"&gt;browser support for SVG is poor&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;In theory, HTTP content negotiation could allow us to offer both SVG and PNG formats for an image, with the client&amp;#8217;s browser selecting the preferred format, but here, too, the &lt;a href="http://bitworking.org/news/WebServicesAndContentNegotiation"&gt;practice has not caught up with the theory&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;In sum, if you care about communicating on the web, you are stuck with raster image formats for the present.&lt;/p&gt;


	&lt;p&gt;Cheers,&lt;br /&gt;Tom&lt;/p&gt;</description>
      <pubDate>Tue, 28 Aug 2007 16:35:31 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:f9138bee-b473-4391-abe3-deaa8a4d9a91</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-561</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Howard B. Golden</title>
      <description>&lt;p&gt;My thoughts echo Thibault. Is there a vector format acceptable to almost all browsers? If so, I&amp;#8217;d rather use that.&lt;/p&gt;</description>
      <pubDate>Mon, 27 Aug 2007 17:09:13 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:57710a6d-2501-4258-87cd-0fe9c202f006</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-559</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Peter Hosey</title>
      <description>&lt;p&gt;Even better: Use &lt;a href="http://cybertherial.com/pngnq/pngnq.html"&gt;pngnq&lt;/a&gt; and &lt;a href="http://www.jonof.id.au/index.php?p=pngout"&gt;pngout&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;pngnq converts the image (lossily, if necessary) to 8-bit color while preserving the quality of the image, and nine times out of ten, it does an &lt;strong&gt;awesome&lt;/strong&gt; job. pngout then compresses it, almost always better than pngcrush or optipng do. Together, they make a mighty combo.&lt;/p&gt;


	&lt;p&gt;In your case, plot2.png (the anti-aliased version) went from 45,716 bytes to 17,704 bytes (pngnq only) to 15,549 bytes (pngnq+pngout). That&amp;#8217;s a savings of 66%.&lt;/p&gt;


	&lt;p&gt;The downside to pngout over pngcrush and optipng is that pngout is closed-source, so if that&amp;#8217;s a deal-breaker for you, you&amp;#8217;ll have to stick with optipng.&lt;/p&gt;</description>
      <pubDate>Sun, 26 Aug 2007 20:06:33 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:32cc1fb0-5da9-4d1f-a186-6d50c76814a0</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-558</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Tom Moertel</title>
      <description>&lt;p&gt;Neil, thanks for the tip on &lt;a href="http://optipng.sourceforge.net/"&gt;OptiPNG&lt;/a&gt;. Thanks to you, my images are now about 20% slimmer.&lt;/p&gt;


	&lt;p&gt;Cheers!&lt;br /&gt;
&amp;#8212;Tom&lt;/p&gt;</description>
      <pubDate>Sun, 26 Aug 2007 11:36:21 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:d109c643-d733-4b8d-a406-18883cecc2f0</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-556</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Neil Mitchell</title>
      <description>&lt;p&gt;Optipng will take 20% of size off the final one.&lt;/p&gt;</description>
      <pubDate>Sun, 26 Aug 2007 08:47:56 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:3f336816-884e-4211-b391-6082957b7653</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-554</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Thibault</title>
      <description>&lt;p&gt;Thanks for this tip Tom.
But can we not produce SVG file from R? Or a simple Flash file? Also can we not display the PDF inline directly? 
After all those pictures are originally vectors. Why converting them into bitmaps?
Maybe I’m missing a point there, just a thought.&lt;/p&gt;</description>
      <pubDate>Sun, 26 Aug 2007 06:24:56 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:d85f24bb-d086-4c7d-ac4b-9ce22992092f</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-553</link>
    </item>
    <item>
      <title>" R tips and tricks:  Producing smooth bitmap plots" by Vineet Kumar</title>
      <description>&lt;p&gt;You can probably cut the size of that new PNG by half if you convert it to an 8-bit colormap instead of 24-bit rgb.  Still, you&amp;#8217;ll probably never get it as small as the jaggy one.&lt;/p&gt;</description>
      <pubDate>Sun, 26 Aug 2007 03:41:01 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:59018a8e-ccd2-4697-ae6a-ecbc15c81c75</guid>
      <link>http://blog.moertel.com/articles/2007/08/25/r-tips-and-tricks-producing-smooth-bitmap-plots#comment-551</link>
    </item>
  </channel>
</rss>
