2011-02-12 21 views
19

Estoy tratando de crear un gráfico (gráfico como en la teoría de gráficos, nodos y bordes, etc.) donde cada nodo está representado por una imagen de archivo (preferiblemente algún formato de trama) . He buscado en el paquete RGraphviz, pero desafortunadamente el atributo shapefill es "Actualmente no compatible".R: Creando gráficos donde los nodos son imágenes

También eché un vistazo a iGraph, pero viendo la documentación no pude encontrar nada sobre el uso de imágenes en los gráficos.

¿Alguien tiene experiencia con el uso de archivos de imagen en gráficos generados desde R?

Respuesta

35

Hay algunas maneras de hacer esto manualmente , ya que puedes leer y trazar imágenes en R (aquí uso rimage) y gráficos una generalmente, también se trazan en un plano x-y. Puede usar igraph para casi cualquier cosa que quiera hacer con gráficos en R, y una alternativa es usar mi propio paquete qgraph que también se puede usar para trazar varios tipos de gráficos.

En ambos paquetes, la ubicación de los nodos se especifica/da en una matriz con dos columnas y una fila para cada nodo que indica la ubicación xey. Ambos paquetes también trazan en un área horizontal y vertical de -1 a 1. Entonces, con esa matriz de disposición, podemos trazar las imágenes en las ubicaciones correctas usando rasterImage.

Comenzaré con gráficos no dirigidos (sin flechas).

Primero cargar una imagen:

# Load rimage library: 
library('rimage') 

# Read the image: 
data(logo) 
img <- imagematrix(logo) 

y la muestra un gráfico para ser utilizado (usando una matriz de adyacencia):

# Sample an adjacency matrix: 
set.seed(1) 
adj <- matrix(sample(0:1,10^2,T,prob=c(0.8,0.2)),10,10) 

Luego, en qgraph:

library('qgraph') 

# Run qgraph (plot the graph) and save the layout: 
L <- qgraph(adj,borders=FALSE,vsize=0,labels=F,directed=F)$layout 

# Plot images: 
apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1)) 

Qué se ve así:

the network made in qgraph

En igraph primero tiene que hacer el diseño. Este diseño también necesita ser re-escalado para adaptarse a la -1 a 1 área de trazado (esto se hace por sí igraph en la función de parcela):

library('igraph') 

# Make the graph 
G <- graph.adjacency(adj,mode="undirected") 

# Create fixed layout: 
set.seed(1) 
L <- layout.fruchterman.reingold(G) 

# Rescale the layout to -1 to 1 
L[,1]=(L[,1]-min(L[,1]))/(max(L[,1])-min(L[,1]))*2-1 
L[,2]=(L[,2]-min(L[,2]))/(max(L[,2])-min(L[,2]))*2-1 

# Plot: 
plot(G,layout=L,vertex.size=0,vertex.frame.color="#00000000",vertex.label="") 

# Set images: 
apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1)) 

The graph in igraph

Ahora, si quieres grafos dirigidos que es menos trivial, ya que las flechas deben señalar hacia el borde de la imagen. La mejor forma de hacerlo es usar nodos cuadrados invisibles que tengan aproximadamente el tamaño de la imagen. Para hacer esto, necesita jugar con el argumento vsize en qgraph o el argumento vertex.size en igraph. (si lo desea, puedo buscar el código exacto para esto, pero no es trivial).

en qgraph:

L <- qgraph(adj,borders=FALSE,vsize=10,labels=F,shape="square",color="#00000000")$layout 

apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1)) 

Directed graph in qgraph

en igraph:

G <- graph.adjacency(adj) 

set.seed(1) 
L <- layout.fruchterman.reingold(G) 

L[,1]=(L[,1]-min(L[,1]))/(max(L[,1])-min(L[,1]))*2-1 
L[,2]=(L[,2]-min(L[,2]))/(max(L[,2])-min(L[,2]))*2-1 

plot(G,layout=L,vertex.size=17,vertex.shape="square",vertex.color="#00000000",vertex.frame.color="#00000000",vertex.label="") 

apply(L,1,function(x)rasterImage(img,x[1]-0.1,x[2]-0.1,x[1]+0.1,x[2]+0.1)) 

Directed graph in igraph

2013 actualización:

Tenga en cuenta que rimage ya no se encuentra en CRAN pero puede usar png o la biblioteca ReadImages. Acabo de actualizar qgraph para incluir la funcionalidad para hacer esto mucho más fácil. Vea este ejemplo:

# Download R logo: 
download.file("http://cran.r-project.org/Rlogo.jpg", file <- tempfile(fileext = ".jpg"), 
    mode = "wb") 

# Sample an adjacency matrix: 
set.seed(1) 
adj <- matrix(sample(0:1, 10^2, TRUE, prob = c(0.8, 0.2)), 10, 10) 

# Run qgraph: 
qgraph(adj, images = file, labels = FALSE, borders = FALSE) 

Esto requiere qgraph versión 1.2 para funcionar.

+2

lovely answer. ¿Qué más podría desear un interrogador SO? – Spacedman

+0

¡podría desear nada más! muchas gracias –

Cuestiones relacionadas