Create a Scatterplot of Raster Images in R

2019-09-11 10:44发布

I am not entirely sure if these kind of questions are allowed at SO, as I have no reproducible data at the moment.

My question is in regards to how one might go about creating a scatterplot of raster images in R. I am not familiar with any packages that allow you to do this. This is the only example I have come across so far in my search. Essentially, this is what I would like to do, however, I am wondering if it's possible for R to simply take the input data and plot the image rather than be fed coordinates in my plot area.

My end goal is to create raster image scatterplots of sports teams using their logos instead of labels. My first thought is to create a data frame including team name, X variable, Y variable, and .png image URL location.

Here is an example of what I am ultimately hoping to do. I'm not sure what program the OP uses, but obviously I would like to do something like this in R.

enter image description here


UPDATE

With the help of Greg Snow's suggestion, I was able to reproduce his example with my own logos.

enter image description here

1条回答
不美不萌又怎样
2楼-- · 2019-09-11 11:17

The the my.symbols and ms.image functions in the TeachingDemos package are one possible starting place. There is an example on the help page for ms.image that shows how to use the R logo as the plotting symbol. Currently it only does one image at a time, so you could either start with a blank plot and loop through the set of images, or a wrapper function can be written that takes a list of images and an indicator of which to plot. Here is a first stab at a wrapper function:

ms.image2 <- function(imgs, transpose=TRUE, 
                      which=1, ...) {
  ms.image(imgs[[which]], transpose=transpose, ...)
}

Then we can create a list of images with code like:

require(png)
img1 <- readPNG(system.file("img", "Rlogo.png", package="png"))
logos <- list( img1, img1[76:1,,], img1[,100:1,],
               img1[76:1,100:1,], img1[,,c(3:1,4)])

These are all variations on the logo, but for your example you could pass a vector of file names of the .png files to lapply to produce a similar list.

Now we can run my.symbols like this (though obviously you will use real data rather than random numbers for the locations):

my.symbols( runif(10), runif(10), ms.image2, 
            MoreArgs=list(imgs=logos), which=rep(1:5,2),
            inches=0.3, symb.plots=TRUE, add=FALSE)

And that produces a plot along the lines of your example:

enter image description here

Edit

For a speed up you can use rasterImage, here is some new code that ran in about half the time as the above (compared using microbenchmark):

ms.rasterImage <- function(imgs, which=1, ...) {
  rasterImage(imgs[[which]], -1, -1, 1, 1)
}

logos2 <- list(as.raster(img1), as.raster(img1[76:1,,]),
               as.raster(img1[,100:1,]), 
               as.raster(img1[76:1,100:1,]),
               as.raster(img1[,,c(3:1,4)])
    )

my.symbols( runif(10), runif(10), ms.rasterImage, 
            MoreArgs=list(imgs=logos2), which=rep(1:5,2),
            inches=0.3, symb.plots=TRUE, add=FALSE)

And here is some code using ggplot2 based on the link in the comment above, but using the list of logos:

ggplot(mtcars, aes(mpg, wt)) + 
  mapply(function(xx, yy, i) 
    annotation_raster(logos[[i]], xmin=xx-1, xmax=xx+1, ymin=yy-0.2, ymax=yy+0.2),
    mtcars$mpg, mtcars$wt, mtcars$gear-2) 

And mainly for my curiosity, here are the timings:

> microbenchmark(
+   my.symbols( mtcars$mpg, mtcars$wt, ms.image2, 
+               MoreArgs=list(imgs=logos), which=mtcars$gear-2,
+               inches=0.3, symb.plots=TRUE, add=FALSE),
+   my.symbols( mtcars$mpg, mtcars$wt, ms.rasterImage, 
+               MoreArgs=list(imgs=logos2), which=mtcars$gear-2,
+               inches=0.3, symb.plots=TRUE, add=FALSE),
+   plot(ggplot(mtcars, aes(mpg, wt)) + 
+          mapply(function(xx, yy, i) 
+            annotation_raster(logos[[i]], xmin=xx-1, xmax=xx+1, ymin=yy-0.2, ymax=yy+0.2),
+            mtcars$mpg, mtcars$wt, mtcars$gear-2) )
+ )
Unit: milliseconds

                      min       lq     mean   median        uq       max neval cld
       ms.image  518.9137 530.5549 661.9333 545.3890  751.7116 1737.7430   100  b 
 ms.rasterImage  158.7097 162.4493 244.6673 171.6103  381.6499  544.1656   100 a  
        ggplot2  478.3005 606.3831 896.8793 772.7210 1359.8888 1714.5647   100   c
查看更多
登录 后发表回答