Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating raster images using R

I am trying to use R to create a raster image from a matrix of data. However, I am getting some weird artifacts on the edge of my image.

The code I am using is as follows:

# From the example for rasterImage(). A 3 pixel by 5 pixel b/w checkerboard.
testImage <- as.raster(0:1, nrow=3, ncol=5)

testImage
     [,1]      [,2]      [,3]      [,4]      [,5]     
[1,] "#000000" "#FFFFFF" "#000000" "#FFFFFF" "#000000"
[2,] "#FFFFFF" "#000000" "#FFFFFF" "#000000" "#FFFFFF"
[3,] "#000000" "#FFFFFF" "#000000" "#FFFFFF" "#000000"

png('test.png', width=5, height=3, units='px')

# Just want the image, no margins, boarders or other fancy stuff.
par(mar = c(0,0,0,0) )
plot.new()
plotArea = par('fig')

rasterImage(testImage, plotArea[1], plotArea[3],
  plotArea[2], plotArea[4], interpolate = FALSE )

dev.off()

This was executed in R 2.12.0 on OS X but I get the same output from R 2.11.0.


The output I am getting is the following (scaled from 5x3 to 150x90)

R output

The pixels in the corners should be black which suggests some form of interpolation is occurring.


The output I am expecting to see is:

Expected output

Any suggestions on why my code fails to faithfully produce a raster image from a matrix?


Intended Use

This is for a package I am working on so I would like to stay within the R base packages if possible so as not to introduce additional dependencies. The package implements a graphics device, so if anyone has a C level solution picks up from the info passed by GERaster() in src/main/engine.c and creates a PNG using only the R libraries, I would be willing to give that a shot as well.


Solutions for OS X

As pointed out by nico, the errant behavior is the result of antialiasing. The plot behaves as expected if png() is told to use an output method for which antialiasing can be disabled, such as Cairo graphics:

png('test.png', width=5, height=3, units='px', type='cairo', antialias=NULL)

On OS X the default backend for png() is Quartz, however png(..., type='quartz') currently ignores directives set by quartz.options(). Faithful output can be produced natively on OS X if the device is started by calling quartz() directly instead of using png():

quartz(file='test.png', type='png', width=5, height=3, dpi=1, antialias=FALSE)

Windows Thinks Differently

The following output is generated on Windows:

Windows output

According to an answer given by Paul Murrell (the benevolent dictator of R graphics devices) on the R-help mailing list:

This is a rounding (truncation) problem. Working on a fix.

This behavior on Windows should not be noticeable unless the raster image contains a very small number of pixels.

like image 551
Sharpie Avatar asked Oct 17 '10 20:10

Sharpie


People also ask

How do you plot a raster image in R?

Plot Raster Data We can do a simple plot with the plot() function. R has an image() function that allows you to control the way a raster is rendered on the screen. The plot() function in R has a base setting for the number of pixels that it will plot (100,000 pixels).

What is a raster object in R?

An object of class "raster" is a matrix of colour values as given by rgb representing a bitmap image. It is not expected that the user will need to call these functions directly; functions to render bitmap images in graphics packages will make use of the as.


1 Answers

Your code works as intended for me... (R 2.11.1 running under Fedora Core 13). It appears to be an antialias problem

This code does the trick

png('test.png', width=5, height=3, units='px', type='cairo', antialias=NULL)

The default antialias options can be set in X11.options

From ?X11.options

antialias: for cairo types, the type of anti-aliasing (if any) to be
      used.  One of ‘c("default", "none", "gray", "subpixel")’.
like image 196
nico Avatar answered Oct 05 '22 17:10

nico