Ответ 1
Есть несколько способов сделать это вручную, так как вы можете читать и строить изображения в R (здесь я использую rimage
), а графики обычно также отображаются на плоскости x-y. Вы можете использовать igraph
для всего, что вы хотите делать с графиками в R, и альтернативой является использование моего собственного пакета qgraph
, который также может использоваться для построения графиков различных типов.
В обоих пакетах размещение узлов задается/задается в матрице с двумя столбцами и строкой для каждого node, указывающим местоположение x и y. Оба пакета также располагаются на горизонтальной и вертикальной областях от -1 до 1. Таким образом, с этой макет-матрицей мы можем построить изображения в правильных местах с помощью rasterImage
.
Я начну с неориентированных графов (без стрелок).
Сначала загружаю изображение:
# Load rimage library:
library('rimage')
# Read the image:
data(logo)
img <- imagematrix(logo)
И пример графика, который будет использоваться (с использованием матрицы смежности):
# Sample an adjacency matrix:
set.seed(1)
adj <- matrix(sample(0:1,10^2,T,prob=c(0.8,0.2)),10,10)
Тогда в 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))
Что выглядит так:
В igraph
вам сначала нужно создать макет. Этот макет также необходимо перемасштабировать, чтобы соответствовать области отпечатка -1 к 1 (это выполняется самим графиком в функции графика):
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))
Теперь, если вы хотите, чтобы направленные графики были менее тривиальными, так как стрелки должны указывать на край изображения. Лучший способ сделать это - использовать невидимые квадратные узлы, которые имеют размер изображения. Для этого вам нужно сразиться с аргументом vsize
в qgraph
или аргументе vertex.size
в igraph
. (если вы хотите, я могу найти точный код для этого, но это не тривиально).
в 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))
в 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))
2013 обновление:
Обратите внимание, что rimage
больше не находится в CRAN, но вы можете использовать png
или библиотеку ReadImages
. Я только что обновил qgraph
, чтобы включить функциональность, чтобы сделать это намного проще. См. Этот пример:
# 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)
Для этого требуется qgraph
версия 1.2.