Comment utiliser une image comme point dans ggplot?

est-il possible d'utiliser une petite image spécifique comme point dans un scatterplot avec ggplot2. Idéalement, je voudrais redimensionner les images en fonction d'une variable.

voici un exemple:

library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point(aes(size = qsec, shape = factor(cyl)))

donc je veux savoir s'il y a un moyen de fournir une image spécifique comme la forme?

31
demandé sur Mike Wise 2010-02-02 07:31:41

3 réponses

voici un geom minimaliste pour afficher des images matricielles au lieu de 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()

enter image description here

(sortie du paquet ggflags)

20
répondu baptiste 2016-07-22 19:02:40

Il y a une bibliothèque appelée ggimage . Voir une vignette ici

vous avez juste à ajouter une colonne à votre data.frame avec l'adresse des images, qui peuvent être stockées sur le web ou localement sur votre ordinateur et alors vous pouvez utiliser le 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)

enter image description here

ps. Notez que ggimage dépend de EBImage . Donc pour installer gginamge j'ai dû faire ceci:

# install EBImage
  source("https://bioconductor.org/biocLite.R")
  biocLite("EBImage")
# install ggimage
  install.packages("ggimage")
9
répondu rafa.pereira 2018-01-27 12:20:35

tout D'abord, voici votre réponse:

pour vous montrer comment utiliser les widgets pour représenter la différenciation des données, je vous renvoie à l'exemple de faces de chernoff à la galerie de graphe R.:

alt texte http://addictedtor.free.fr/graphiques/graphiques/graph_87.png

Tout le code de cet exemple est disponible sur le site.

Sinon, regardez gglplot stat_spoke pour un simple widget: alt texte http://had.co.nz/ggplot2/graphics/706b1badf6469940342f204b7bc98857.png

grImport fournit un mécanisme pour importer des images PDF simples dans votre parcelle pour une utilisation comme points.

suit Maintenant une critique de votre exemple.


ce n'est pas un scatterplot. C'est essentiellement une liste en flux de points de données ordonnés où la couleur est utilisée pour indiquer une des variables du texte, et un widget Non informatif et redondant a été utilisé pour encadrer les données, mais ne fournit pas d'autre rétroaction visuelle en termes de taille ou de forme.

ce n'est pas un bon graphique, parce qu'il ne répond absolument pas à la question posée "est-ce que payer plus conduit à de meilleurs résultats", et laisse le lecteur à la lutte tirer cette conclusion (et cet autre graphique, si nécessaire) par m'.

en outre, les auteurs ont gaspillé les axes x, y - qui auraient pu être bien utilisés pour positionner les éléments par la sortie et les résultats, pour fournir une compréhension visuelle de l'optimisation des ressources. Au lieu de cela, ils ont choisi d'ordonner les icônes par le rapport du coût par tête au taux moyen de diplomation, qui est en quelque sorte utile, mais ne répond pas à la question énoncée, et ne permet pas une comparaison visuelle directe du rapport relatif entre les collèges, ou la relation entre le coût et la valeur.

comme je le dis, à mon avis, c'est un mauvais graphique, et vos lecteurs ne seraient pas bien servis en vous le faisant répliquer.

5
répondu Alex Brown 2010-02-02 10:20:34