2010-02-02 13 views
27

Existe-t-il un moyen d'utiliser une petite image spécifique comme point dans un nuage de points avec ggplot2. Idéalement, je vais vouloir redimensionner les images en fonction d'une variable.Comment utiliser une image comme un point dans ggplot?

Voici un exemple:

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

Je veux essentiellement savoir s'il y a un moyen de fournir une image spécifique que la forme?

Répondre

5

D'abord, voici votre réponse:

Pour vous montrer comment utiliser la façon dont vous pourriez mieux utiliser des widgets pour représenter la différenciation des données, je vous renvoie à l'exemple de chernoff faces à la galerie graphique R .:

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

Tout le code pour générer cet exemple est disponible sur le site.

Vous pouvez également consulter stat_spoke de ggplot pour un widget simple: alt text http://had.co.nz/ggplot2/graphics/706b1badf6469940342f204b7bc98857.png

grImport fournit un mécanisme permettant d'importer des images simples PDF dans votre parcelle pour une utilisation en tant que points.

Suit maintenant une critique de votre exemple.


Ce diagramme n'est pas un diagramme de dispersion. Il s'agit essentiellement d'une liste déroulante de points de données ordonnés où la couleur est utilisée pour indiquer l'une des variables de texte, et un widget non informatif et redondant a été utilisé pour encadrer les données mais ne fournit aucun retour visuel en termes de taille ou de forme. Ce n'est pas un bon graphique, car il échoue complètement à répondre à la question «Payer plus, ce qui conduit à de meilleurs résultats», et laisse le lecteur à lutter tirer cette conclusion (et cet autre graphique, si nécessaire) par eux-mêmes . En outre, les auteurs ont gaspillé les axes x, y - qui auraient pu être bien utilisés pour positionner les éléments en 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 entre le coût par tête et le taux moyen de diplomation, ce qui est plutôt utile, mais ne répond pas à la question posée et ne permet pas une comparaison visuelle directe entre les collèges. la relation entre le coût et la valeur. Comme je le dis, à mon avis, il s'agit d'un mauvais graphique, et vos lecteurs ne seraient pas bien servis en le faisant reproduire.

+0

Merci pour la réponse! J'ai enlevé ce lien parce que je pense que vous avez raison. Plus généralement, à moins de manquer quelque chose, cela ne semble pas être la fonction faces(), ni stat_spoke ne répond vraiment à mes besoins. faces() n'affiche que les visages ... vous ne pouvez pas modifier l'image. Et stat_spoke ne vous permet pas non plus de changer l'image. Mais grImport semble très prometteur! Merci! – griffin

+3

Vos liens d'image sont cassés ... J'ai fourré autour pour un peu en essayant de les réparer mais a échoué. – joran

+3

Il semble que la question a été éditée dans la mesure où la réponse n'a plus de sens; ainsi que d'avoir des liens brisés vers des images. –

16

Voici un geom minimaliste pour afficher des images raster 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)

2

Il y a une bibliothèque appelée ggimage à faire.Voir un intro vignette here

Il vous suffit d'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 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 je devais faire ceci:

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