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)
The pixels in the corners should be black which suggests some form of interpolation is occurring.
The output I am expecting to see is:
Any suggestions on why my code fails to faithfully produce a raster image from a matrix?
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.
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)
The following output is generated on Windows:
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.
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).
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.
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")’.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With