Подтвердить что ты не робот

R: Создание графиков, где узлы представляют собой изображения

Я пытаюсь создать граф (график, как в теории графов, узлы и ребра и т.д.), где каждый node представлен изображением из файла (желательно в растровом формате). Я посмотрел в пакете RGraphviz, но, к сожалению, атрибут shapefill - "В настоящее время не поддерживается".

Я также посмотрел на iGraph, но просматривая документацию, я не мог найти что-либо в использовании изображений на графиках.

Есть ли у кого-нибудь опыт использования файлов изображений в графах, сгенерированных из R?

4b9b3361

Ответ 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))

Что выглядит так:

the network made in qgraph

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

The graph in igraph

Теперь, если вы хотите, чтобы направленные графики были менее тривиальными, так как стрелки должны указывать на край изображения. Лучший способ сделать это - использовать невидимые квадратные узлы, которые имеют размер изображения. Для этого вам нужно сразиться с аргументом 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))

Directed graph in qgraph

в 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 обновление:

Обратите внимание, что 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.