Adding an image to a graph in R

I am trying to add an image (jpeg, png doesn't matter) to the plot, which is determined by the layout function. For instance:

a<-c(1,2,3,4,5) b<-c(2,4,8,16,32) m <- matrix(c(1,1,1,1,2,3,2,3), nrow = 2, ncol = 4) layout(m); hist(a);boxplot(a~b);plot(b~a)* 

Instead of the histogram in position 1, I want to add an image (in my case it is a map)

I don’t know how to deal with jpeg package, maybe you can help me!

+8
source share
3 answers

You need to read your png or jpeg files through png and jpeg packages. Then, using the rasterImage function rasterImage you can draw an image on the chart. Say your file is myfile.jpeg , you can try the following:

 require(jpeg) img<-readJPEG("myfile.jpeg") #now open a plot window with coordinates plot(1:10,ty="n") #specify the position of the image through bottom-left and top-right coords rasterImage(img,2,2,4,4) 

The above code draws an image between (2,2) and (4,4) points.

+9
source

Regarding Rodrigo's comment, I created a function that should keep the aspect ratio of the image pixel ( addImg ).

 addImg <- function( obj, # an image file imported as an array (eg png::readPNG, jpeg::readJPEG) x = NULL, # mid x coordinate for image y = NULL, # mid y coordinate for image width = NULL, # width of image (in x coordinate units) interpolate = TRUE # (passed to graphics::rasterImage) A logical vector (or scalar) indicating whether to apply linear interpolation to the image when drawing. ){ if(is.null(x) | is.null(y) | is.null(width)){stop("Must provide args 'x', 'y', and 'width'")} USR <- par()$usr # A vector of the form c(x1, x2, y1, y2) giving the extremes of the user coordinates of the plotting region PIN <- par()$pin # The current plot dimensions, (width, height), in inches DIM <- dim(obj) # number of xy pixels for the image ARp <- DIM[1]/DIM[2] # pixel aspect ratio (y/x) WIDi <- width/(USR[2]-USR[1])*PIN[1] # convert width units to inches HEIi <- WIDi * ARp # height in inches HEIu <- HEIi/PIN[2]*(USR[4]-USR[3]) # height in units rasterImage(image = obj, xleft = x-(width/2), xright = x+(width/2), ybottom = y-(HEIu/2), ytop = y+(HEIu/2), interpolate = interpolate) } 

Usage example:

 library(png) myurl <- "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/Jupiter_%28transparent%29.png/242px-Jupiter_%28transparent%29.png" z <- tempfile() download.file(myurl,z,mode="wb") pic <- readPNG(z) file.remove(z) # cleanup dim(pic) png("plot.png", width = 5, height = 4, units = "in", res = 400) par(mar = c(3,3,0.5,0.5)) image(volcano) addImg(pic, x = 0.3, y = 0.5, width = 0.2) dev.off() 

enter image description here

+2
source

I just wanted to offer an alternative solution from the built-in "grid" package called grid.raster

From what I can say, it is very similar to rasterImage, but it accepts the "npc" --a bonus in normalized units, in my opinion, and maintains the aspect ratio if you do not specify the width and height. For my purposes, I just installed / or, and the image seems to scale perfectly.

 library(png) library(grid) x11() mypng = readPNG('homer.png') image(volcano) grid.raster(mypng, .3, .3, width=.25) # print homer in ll conrner grid.raster(mypng, .9, .7, width=.5) # print bigger homer in ur corner while(!is.null(dev.list())) Sys.sleep(1) 

Apparently I can’t post images yet ... here is a link to my sample output

0
source

Source: https://habr.com/ru/post/1210477/


All Articles