How to use an image as a point in ggplot?

一笑奈何 提交于 2019-11-26 04:20:42

Here's a minimalist geom to display raster images instead of points,

library(ggplot2)
library(grid)

## replace by a named list with matrices to be displayed
## by rasterGrob
.flaglist <- list("ar" = matrix(c("blue", "white", "blue"), 1), 
                  "fr" = matrix(c("blue", "white", "red"), 1))

flagGrob <- function(x, y, country, size=1, alpha=1){
  grob(x=x, y=y, country=country, size=size, cl = "flag")
}

drawDetails.flag <- function(x, recording=FALSE){

  for(ii in seq_along(x$country)){
    grid.raster(x$x[ii], x$y[ii], 
                width = x$size[ii]*unit(1,"mm"), height = x$size[ii]*unit(0.5,"mm"),
                image = .flaglist[[x$country[[ii]]]], interpolate=FALSE)
  }
}


scale_country <- function(..., guide = "legend") {
  sc <- discrete_scale("country", "identity", scales::identity_pal(), ..., guide = guide)

  sc$super <- ScaleDiscreteIdentity
  class(sc) <- class(ScaleDiscreteIdentity)
  sc
}

GeomFlag <- ggproto("GeomFlag", Geom,
                    required_aes = c("x", "y", "country"),
                    default_aes = aes(size = 5, country="fr"),

                    draw_key = function (data, params, size) 
                    {
                      flagGrob(0.5,0.5, country=data$country,  size=data$size)
                    },

                    draw_group = function(data, panel_scales, coord) {
                      coords <- coord$transform(data, panel_scales)     
                      flagGrob(coords$x, coords$y, coords$country, coords$size)
                    }
)

geom_flag <- function(mapping = NULL, data = NULL, stat = "identity",
                      position = "identity", na.rm = FALSE, show.legend = NA, 
                      inherit.aes = TRUE, ...) {
  layer(
    geom = GeomFlag, mapping = mapping,  data = data, stat = stat, 
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )
}


set.seed(1234)
d <- data.frame(x=rnorm(10), y=rnorm(10), 
                country=sample(c("ar","fr"), 10, TRUE), 
                stringsAsFactors = FALSE)


ggplot(d, aes(x=x, y=y, country=country, size=x)) + 
  geom_flag() + 
  scale_country()

(output from the ggflags package)

There is a library called ggimage to do that. See an intro vignette here

You just have to add a column to your data.frame with the address of the images, which can be stored on the web or locally on your computer and then you can use the geom_image():

library("ggplot2")
library("ggimage")

# create a df

set.seed(2017-02-21)
d <- data.frame(x = rnorm(10),
                y = rnorm(10),
                image = sample(c("https://www.r-project.org/logo/Rlogo.png",
                                 "https://jeroenooms.github.io/images/frink.png"),
                               size=10, replace = TRUE)
                )
# plot2
  ggplot(d, aes(x, y)) + geom_image(aes(image=image), size=.05)

ps. Note that ggimage depends on EBImage. So to install gginamge I had to do this:

# install EBImage
  source("https://bioconductor.org/biocLite.R")
  biocLite("EBImage")
# install ggimage
  install.packages("ggimage")
Alex Brown

First, here's your answer:

To show you how to use how you might better use widgets to represent data differentiation, I refer you to the example of chernoff faces at the R graph gallery.:


(source: free.fr)

All the code to generate this example is available at the site.

Alternatively, look ggplot's stat_spoke for a simple widget:


(source: had.co.nz)

grImport provides a mechanism to import simple PDF images into your plot for use as points.

Now follows a critique of your example.


This is not a scatterplot. It's essentially a flowed list of ordered data points where colour is used to indicate one of the text variables, and an uninformative and redundant widget has been used to frame the data but otherwise provides no visual feedback in terms of size or shape.

It is not a good graph, because it completely fails to answer the stated question "Does Paying More Lead To Better Results", and leaves the reader to struggle draw that conclusion (and that other graph, as necessary) by themselves.

In addition, the authors have wasted the x, y axes - which could have been well used to position elements by outgoing and results, to provide a visual understanding of value-for-money. Instead they have opted to order the icons by the ratio of per head cost to average graduation rate, which is sort of useful, but doesn't answer the stated question, and fails to allow a direct visual comparison of relative ratio between colleges, or the relationship between cost and value.

As I say, in my opinion, this is a bad graph, and your readers would not be well served by having you replicate it.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!