开发者

R: Creating graphs where the nodes are images

I'm trying to create a graph (graph as in graph theory, nodes and edges, etc.) where each node is represented by an image from file (preferably some raster format). I've looked in the RGraphviz package, but unfortunately the shapefill attribute is "Currently unsupported".

I also had a look at iGraph, but browsing through the documentation I couldn't seem to find anything on using images in the graphs.

Does an开发者_StackOverflowyone have experience with using image files in graphs generated from within R?


There are some ways to do this manually, since you can read and plot images in R (here I use rimage) and graphs are typically also plotted on a x-y plane. You can use igraph for almost anything you want to do with graphs in R, and an alternative is to use my own package qgraph which can also be used to plot various types of graphs.

In both packages the placement of the nodes is specified/given in a matrix with two columns and a row for each node indicating the x and y location. Both packages also plot on a -1 to 1 horizontal and vertical area. So with that layout-matrix we can plot the images on the right locations using rasterImage.

I will start with undirected graphs (no arrows).

First I load an image:

# Load rimage library:
library('rimage')

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

And sample a graph to be used (using an adjacency matrix):

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

Then in 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))

Which looks like this:

R: Creating graphs where the nodes are images

In igraph you first need to make the layout. This layout also needs to be rescaled to fit the -1 to 1 plotting area (this is done by igraph itself in the plot function):

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))

R: Creating graphs where the nodes are images

Now if you want directed graphs it is less trivial, as the arrows need to be pointing to the edge of the image. Best way to do this is to use invisible square nodes that are about the size of the image. To do this you need to fiddle around with the vsize argument in qgraph or the vertex.size argument in igraph. (if you want I can look up the exact code for this, but it is not trivial).

in 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))

R: Creating graphs where the nodes are images

in 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))

R: Creating graphs where the nodes are images

2013 update:

Please mind that rimage is no longer on CRAN but you can use png or the ReadImages library. I have just updated qgraph to include functionality to do this a lot easier. See this example:

# 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)

This requires qgraph version 1.2 to work.


Take a look at a previous question:

Placing Custom Images in a Plot Window--as custom data markers or to annotate those markers

And, take a look at:

http://www.stat.auckland.ac.nz/~paul/RGraphics/rgraphics.html

http://www.stat.auckland.ac.nz/~paul/RGraphics/chapter1.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜