Dnaiel
Dnaiel

Reputation: 7832

image plot in R too large

I have a 65,000 by 160 matrix, that I then transform into an image using image(X) in R.

I also use the option useRaster = TRUE, and this makes the plotting lots faster, and less large of a file.

However, the file size is still rather large ~ 60 Mb. Is there anyway to control the file size of an image in R? If so I'd love to hear how, and also how much resolution one would lose by constraining the file size.

The file is created as a pdf file, code below:

# ----- Define a function for plotting a matrix ----- #
myImagePlot <- function(x, filename, ...){
  dev = "pdf"
  #filename = '/home/dnaiel/test.pdf'
  if(dev == "pdf") { pdf(filename, version = "1.4") } else{}
     min <- min(x)
     max <- max(x)
     yLabels <- rownames(x)
     xLabels <- colnames(x)
     title <-c()
  # check for additional function arguments
  if( length(list(...)) ){
    Lst <- list(...)
    if( !is.null(Lst$zlim) ){
       min <- Lst$zlim[1]
       max <- Lst$zlim[2]
    }
    if( !is.null(Lst$yLabels) ){
       yLabels <- c(Lst$yLabels)
    }
    if( !is.null(Lst$xLabels) ){
       xLabels <- c(Lst$xLabels)
    }
    if( !is.null(Lst$title) ){
       title <- Lst$title
    }
  }
# check for null values
if( is.null(xLabels) ){
   xLabels <- c(1:ncol(x))
}
if( is.null(yLabels) ){
   yLabels <- c(1:nrow(x))
}

layout(matrix(data=c(1,2), nrow=1, ncol=2), widths=c(4,1), heights=c(1,1))

 # Red and green range from 0 to 1 while Blue ranges from 1 to 0
 ColorRamp <- rgb( seq(0,1,length=256),  # Red
                   seq(0,1,length=256),  # Green
                   seq(1,0,length=256))  # Blue
 ColorLevels <- seq(min, max, length=length(ColorRamp))

 # Reverse Y axis
 reverse <- nrow(x) : 1
 yLabels <- yLabels[reverse]
 x <- x[reverse,]

 # Data Map
 par(mar = c(3,5,2.5,2))
 image(1:length(xLabels), 1:length(yLabels), t(x), col=ColorRamp, xlab="",
 ylab="", axes=FALSE, zlim=c(min,max), useRaster=TRUE)
 if( !is.null(title) ){
    title(main=title)
 }
# Here we define the axis, left of the plot, clustering trees....
#axis(BELOW<-1, at=1:length(xLabels), labels=xLabels, cex.axis=0.7)
# axis(LEFT <-2, at=1:length(yLabels), labels=yLabels, las= HORIZONTAL<-1,
# cex.axis=0.7)

 # Color Scale (right side of the image plot)
 par(mar = c(3,2.5,2.5,2))
 image(1, ColorLevels,
      matrix(data=ColorLevels, ncol=length(ColorLevels),nrow=1),
      col=ColorRamp,
      xlab="",ylab="",
      xaxt="n", useRaster=TRUE)

 layout(1)
  if( dev == "pdf") {
    dev.off() }
}
# ----- END plot function ----- #

Thanks!

Upvotes: 1

Views: 2619

Answers (2)

pedrosaurio
pedrosaurio

Reputation: 4926

When you save it in pdf format you are actually saving vector objects for each of the plotted square in the matrix. By doing this, you can have 'unlimited' resolution as by having the information of the vector of each element, when you zoom into it, you actually redraw the whole subset of elements that are covered by the zoomed field. Think of it as if you were saving the whole matrix in a different format.

When you save it in any type of bitmap (bmp, jpeg, png) you are actually not saving the information of each element, each pixel is getting a statistical value that represents the information of all the elements that each pixel covers. Think of it as if you were averaging the values of your matrix in order to fit a particular pixel grid, determined by the resolution of your output device.

A quick search of ""difference between vector images and bitmaps will make everything more clear to you.

Upvotes: 1

IRTFM
IRTFM

Reputation: 263411

When I create such matrix and plot using image inside a jpeg call with the default size for that device, I get a file measured in KB (90KB).

> bigm <-matrix(sample(1:8, 65000*160, repl=TRUE),  160, 65000)
> jpeg(filename="test.jpg")
> image(bigm)
> dev.off()
quartz 
     2 

Whether this is appropriate for your application will probably depend both of the exact nature of this task and the OS, neither of which are yet specified.

Upvotes: 5

Related Questions