Combining vector and bitmap graphics in a pdf
Use ?rasterImage
, or more conveniently in recent versions image
with option useRaster = TRUE
.
That will dramatically reduce the size of the file.
my.func <- function(x, y) x %*% t(y)
pdf(file="image.pdf")
image(my.func(seq(-10,10,,500), seq(-5,15,,500)), col=heat.colors(100))
dev.off()
pdf(file="rasterImage.pdf")
image(my.func(seq(-10,10,,500), seq(-5,15,,500)), col=heat.colors(100), useRaster = TRUE)
dev.off()
file.info("image.pdf")$size
file.info("rasterImage.pdf")$size
image.pdf: 813229 bytes
rasterImage.pdf 16511 bytes
See more details about the new features here:
http://developer.r-project.org/Raster/raster-RFC.html
http://journal.r-project.org/archive/2011-1/RJournal_2011-1_Murrell.pdf
R: Bitmap output in PDF
UPDATE: have now added method based on readPNG()
as suggested in comments above. It's a bit slower (3s vs 9s) and seems to result in slightly larger file sizes than ImageMagick. rasterImage()
interpolation makes no difference to filesize or timing, but alters the appearance slightly. If it's FALSE, then it looks the same as ImageMagick
I have just come up with the following solution using ImageMagick. It's not perfect, but it seems to work well so far.
png2pdf <- function(name=NULL,removepngs=TRUE,method="imagemagick",pnginterpolate=FALSE){
# Run the png() function with a filename of the form name%03d.png
# Then the actual plotting functions, e.g. plot(), lines() etc.
# Then dev.off()
# Then run png2pdf() and specify the name= argument if other pngs exist in the directory
# Need to incorporate a way of dealing with non-square plots
if(is.null(name)){
names <- list.files(pattern="[.]png")
name <- unique(sub("[0-9][0-9][0-9][.]png","",names))
if(length(name)!=1) stop("png2pdf() error: Check filenames")
}else{
names <- list.files(pattern=paste0(name,"[0-9][0-9][0-9][.]png"))
}
# Can change this to "convert" if it is correctly in the system path
if(method=="imagemagick"){
cmd <- c('C:\\Program Files\\ImageMagick-6.9.0-Q16\\convert.exe',names,paste0(name,".pdf"))
system2(cmd[1],cmd[-1])
}else if(method=="readPNG"){
library(png)
pdf(paste0(name,".pdf"))
par(mar=rep(0,4))
for(i in 1:length(names)){
plot(c(0,1),c(0,1),type="n")
rasterImage(readPNG(names[i]),0,0,1,1,interpolate=pnginterpolate)
}
dev.off()
}
if(removepngs) file.remove(names)
}
Plot as bitmap in PDF
Here's a solution that gets you close (50kb) to your desired file size (25kb), without requiring you to install LaTeX and/or learn Sweave. (Not that either of those are undesirable in the long-run!)
It uses the grid
functions grid.cap()
and grid.raster()
. More details and ideas are in a recent R-Journal article by Paul Murrell (warning : PDF):
require(grid)
# Make the plots
dev.new() # Reducing width and height of this device will produce smaller raster files
plot(rnorm(2e4), rnorm(2e4), pch="+", cex=0.6)
cap1 <- grid.cap()
plot(rnorm(2e4), rnorm(2e4), pch="+", cex=0.6, col="red")
cap2 <- grid.cap()
dev.off()
# Write them to a pdf
pdf("test.pdf", onefile=TRUE)
grid.raster(cap1)
plot.new()
grid.raster(cap2)
dev.off()
The resulting pdf
images appear to retain more detail than your files test1.png
and test2.png
, so you could get even closer to your goal by trimming down their resolution.
Combining vector and raster images in gnuplot
Use the multiplot feature in gnuplot to do this
e.g.
set terminal postscript eps enhanced color "Helvetica" 20
set output 'my_data.eps'
# beginning of multiplot
set multiplot
# the first plot
set size 1,1
set origin 0,0
set xlabel "Distance 1"
set ylabel "Distance 2"
set log x
set log y
set xrange[0.01:1]
plot "my_data.m" title "" with p pt 5
# smaller overlay plot
set size 0.45,0.45
set origin 0.15,0.5
set xrange [:0.2]
set lmargin 5
unset xlabel
unset ylabel
unset arrow
unset logscale
set xtics 0.05
set ytics 0.2
set grid
plot "my_data.m" title "" with p pt 5
# end of multiplot
unset multiplot
Reference
You may also find this link helpful : http://gnuplot.sourceforge.net/demo_4.2/image.html
Related Topics
How to Write an Xts Object Using Write.CSV in R
Arrow() in Ggplot2 No Longer Supported
Is the Plyr Package for R Not Available for R Version 3.0.2
Apply a Function to All Variables Starting with Specific Pattern in R
Assigning and Removing Objects in a Loop: Eval(Parse(Paste(
Fuzzyjoin Two Data Frames Using Data.Table
Enriching a Ggplot2 Plot with Multiple Geom_Segment in a Loop
Assign Names to Vector Entries Without Assigning the Vector a Variable Name
Highcharter Plotbands, Plotlines with Time Series Data
Why Doesn't "+" Operate on Characters in R
How to Determine If a Character Vector Is a Valid Numeric or Integer Vector
How to Add Colorbar with Perspective Plot in R
How to Do Str_Extract with Base R
R Multiple Conditions in If Statement
R-How to Generate Random Sample of a Discrete Random Variables