2010-02-02 23 views
27

¿Hay alguna forma de utilizar una imagen pequeña específica como un punto en un diagrama de dispersión con ggplot2? Idealmente, querré redimensionar las imágenes en función de una variable.¿Cómo usar una imagen como un punto en ggplot?

He aquí un ejemplo:

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

Así que, básicamente, quiero saber si hay una manera de proporcionar una imagen específica como la forma?

Respuesta

5

En primer lugar, aquí está su respuesta:

que le muestre cómo usar cómo puede utilizar mejor los widgets para representar la diferenciación de datos, le remito al ejemplo de chernoff faces en la galería R gráfica .:

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

Todo el código para generar este ejemplo está disponible en el sitio.

alternativa, busque ggplot de stat_spoke para un widget simple: alt text http://had.co.nz/ggplot2/graphics/706b1badf6469940342f204b7bc98857.png

grImport proporciona un mecanismo para importar imágenes PDF simples en su parcela para uso como puntos.

Ahora sigue una crítica de su ejemplo.


Esto no es un diagrama de dispersión. Básicamente es una lista fluida de puntos de datos ordenados donde el color se usa para indicar una de las variables de texto, y un widget no informativo y redundante se ha utilizado para enmarcar los datos, pero de lo contrario no proporciona retroalimentación visual en términos de tamaño o forma.

No es un buen gráfico, porque no responde por completo la pregunta "¿Pagar más lleva a mejores resultados?", Y deja al lector que forcejee sacar esa conclusión (y ese otro gráfico, según sea necesario) por sí mismo .

Además, los autores han desperdiciado los ejes x, y, que podrían haber sido bien utilizados para posicionar los elementos por salida y resultados, para proporcionar una comprensión visual de la relación calidad-precio. En cambio, han optado por ordenar los íconos por la relación entre el costo por cabeza y la tasa promedio de graduación, que es más o menos útil, pero no responde a la pregunta planteada, y no permite una comparación visual directa de la proporción relativa entre universidades, o la relación entre costo y valor.

Como digo, en mi opinión, este es un gráfico malo, y a sus lectores no les convendría que lo repliquen.

+0

¡Gracias por la respuesta! Eliminé ese enlace porque creo que tienes razón. De manera más general, a menos que me esté perdiendo algo, no parece que la función faces() ni stat_spoke realmente responda a mi necesidad. caras() solo muestra caras ... no se puede alterar la imagen. Y stat_spoke tampoco te permite cambiar la imagen. ¡Pero grImport parece muy prometedor! ¡Gracias! – griffin

+3

Los enlaces de tu imagen están rotos ... Busqué un poco tratando de arreglarlos pero no tuve éxito. – joran

+3

Parece que la pregunta se ha editado en la medida en que la respuesta ya no tiene sentido; además de tener enlaces rotos a las imágenes. –

16

Aquí hay una geom minimalista para mostrar imágenes de mapa de bits en lugar de puntos,

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

(salida del paquete ggflags)

2

Hay una biblioteca llamada ggimage de hacer eso.Ver un intro vignette here

Sólo hay que añadir una columna a su data.frame con la dirección de las imágenes, que pueden almacenarse en la web o localmente en el equipo y luego se puede utilizar el 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. Tenga en cuenta que ggimage depende de EBImage. Así que para instalar gginamge tuve que hacer esto:

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