2015-03-22 10 views
6

Spojrzałem na wersję this question, która wydaje się podobna, ale mam problemy z jej uruchomieniem.Jak przypisać różne obrazy do różnych wierzchołków w kodzie igraph?

Powiedzmy moja edgelist składa się z następujących elementów:

P1 P2 weight 
a b 1 
a c 3 
a d 2 
b c 8 

używam read.csv zbierać dane, a następnie przekonwertować go do macierzy. Następnie wykreślam go, używając:

g=graph.edgelist(x[,1:2],directed=F) 
E(g)$weight=as.numeric(x[,3]) 
tkplot(g,layout=layout.fruchterman.reingold,edge.width=E(g)$weight) 

I to zwraca sieć z wierzchołkami i krawędziami. Chciałbym zastąpić wierzchołek a jednym obrazem, wierzchołek b innym i tak dalej. Wiem, jak zastosować ten sam obraz do wszystkich, ale chcę zastosować inny obraz do każdego wierzchołka. Jak mam to zrobić?

Edit: Dodawanie kodu powtarzalne poniżej wymagane przez user20650

# loading libraries 
library(igraph) 
library(rgdal) 

# reading data from edgelist 
x <- read.csv('edgelist', colClasses = c("character","character","numeric"), header=T) 
# however, to replicate the data, use this line instead (Above line included just to show how I get the data) 
x <- data.frame(P1 = c("a","a","a","b"), P2 = c("b","c","d","c"), weight = c(1,3,2,8)) 

# converting x to a matrix 
x = as.matrix(x) 

# preparing graph (getting rid of arrows, edge colors) 
g = graph.edgelist(x[,1:2], directed=F) 
E(g)$weight=as.numeric(x[,3]) 
E(g)[weight<=1]$color='dodgerblue' 
E(g)[weight>=2&weight<=3]$color='dodgerblue1' 
E(g)[weight>=4&weight<=7]$color='dodgerblue2' 
E(g)[weight>=8&weight<=9]$color='dodgerblue3' 
E(g)[weight==10]$color='dodgerblue4' 

# plot the graph 
# beginning of stuff I do not do anymore - the tkplot and adj lines below here I do not do anymore as they have been replaced with suggestions by user20650 
tkplot(g, canvas.width=640, canvas.height=640, layout=layout.fruchterman.reingold, edge.width=E(g)$weight) 

# just to make sure everything is correct, I was also verifying with this 
adj <- get.adjacency(g, attr='weight') 
# end of stuff I do not do anymore and I replaced it with what follows 

# this is where I started placing user20650's lines (survcont1.png through survcont13.png are local files - 1 is the image for a, 2 for b, and so on) 
url <- paste0("survcont", 1:13, ".png") 

# my mapply which I guess I don't need anymore (I'm using rgdal because it is a library I already have that can read the images, am willing to use a better method if one exists) 
mapply(readGDAL, url) 
img <- lapply(url, png::readPNG) 

set.seed(1) 
adj <- matrix(sample(0:1,3^2,T,prob=c(0.8,0.8)),13,13) 
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 

# I added in the label so I can verify if the right vertices are showing up in the right places, I will remove in final version, also added in the edge weights 
plot(g, layout=l, vertex.size=10, vertex.shape="square", vertex.color="#00000000", vertex.frame.color="#00000000", vertex.label="", edge.width=E(g)$weight) 

# and finally plotting of the images 
for(i in 1:nrow(l)) { 
    rasterImage(img[[i]], l[i, 1]-0.2, l[i, 2]-0.2, l[i, 1]+0.2, l[i, 2]+0.2) 
} 

Jestem zgadywania coś jest nie tak z linii po korekcie, a ja jakoś nie łącząc moje dane do obrazów. Nie rozumiem też, dlaczego muszę ustawić.

Obrazy są drukowane, co jest świetne, ale moje oryginalne szerokości i kolory krawędzi nie są i nie jestem pewien, czy obraz 1 łączy się z a, 2 na b, i tak dalej.

+3

Zobacz http://igraph.org/r/doc/igraph.vertex.shapes.html; ostatni przykład go ma! –

Odpowiedz

8

Możesz użyć Sacha's answer w pytaniu, do którego linkujesz, aby to zrobić. Jeśli twoje obrazy są zapisane na liście, po prostu wykonaj iterację, aby wyrenderować pliki PNG. Musiałem dostosować regulację ręczną (od 0,1 do 0,2), aby zmienić rozmiar obrazu.

EDIT Wykorzystując dane OP i dodanie wagi krawędzi i kolor (usunięty oryginalny post jak ten w dużej mierze powtarza)

Najpierw trzeba jakieś obrazy dla wierzchołków.

# As i dont have access to your images i will download and use the 
# images as before. We need four images as there are four vertices 
# You dont need to do this bit exactly, all you need to do is read 
# in your images into your R session, in a list called img 

url <- paste0("http://pngimg.com/upload/cat_PNG", 1632:1635, ".png") 
mapply(download.file, url, basename(url)) 
img <- lapply(basename(url), png::readPNG) 


library(igraph) 

# data 
x <- data.frame(P1 = c("a","a","a","b"), 
       P2 = c("b","c","d","c"), 
       weight = c(1,3,2,8)) 

# this reads in the third column which you can then assign to be weights 
g <- graph.data.frame(x, directed=FALSE) 
# check 
E(g)$weight 

# edge colour - you might need to tweak this depending on your 
# data, with the right argument etc 
E(g)$colour <- as.character(cut(as.numeric(E(g)$weight), 
         breaks = c(0, 1, 3, 7, 9, 10), 
         labels=paste0("dodgerblue", c("", 1:4)))) 

# you need to set the seed as the layout function is an 
# iterative process and not deterministic 
set.seed(1)  
l <- layout.norm(layout.fruchterman.reingold(g), 
          xmin=-1, xmax=1, ymin=-1, ymax=1) 


par(mar=rep(0,4)) 
plot(g, layout=l, vertex.size=20, vertex.shape="square", 
    vertex.color="#00000000", vertex.frame.color="#00000000", 
    vertex.label="", edge.width=E(g)$weight, edge.color=E(g)$colour) 

# and finally plotting of the images 
for(i in 1:nrow(l)) { 
    rasterImage(img[[i]], l[i, 1]-0.2, l[i, 2]-0.2, l[i, 1]+0.2, l[i, 2]+0.2) 
} 

enter image description here

+0

Próbowałem tego, ale używam obrazów lokalnych, więc zastąpiłem twoją pierwszą sekcję 'url <- paste0 (" survcont ", 1:13," .png "); mapply (readGDAL, url); img <- lapply (url, png :: readPNG) '. Ale kiedy uruchomię fabułę (nawet gdy dodaję 'edge.width = E (g) $ weight'), otrzymam te same linie, które robisz w twoim przykładzie i grubość linii w moim oryginalnym przykładzie, gdzie bazuję na wadze. A gdy usuniemy 'vertex.label =" "' otrzymam liczby z obrazów zamiast liter z mojej macierzy. Wiem, że prawdopodobnie brakuje mi czegoś naprawdę oczywistego, ale nie mogę zrozumieć, co jest nie tak. BTW, ładowanie obrazów. – thequerist

+0

ok, nie mam za późno, przepraszam. Jeśli obrazy są lokalne, nie potrzebowałbyś etapu "mapowania" mojego kodu - po prostu pobrałem obrazy, aby uzyskać powtarzalny przykład. Dlaczego używasz 'readGDAL'? Czy możesz edytować swoje pytanie z minimalnym przykładem (być może używając podobnego podejścia do mojej odpowiedzi) pokazując wszystkie kody i gdzie jest problem. Ty – user20650

+0

Dodałem przykład. Używam readGDAL, ponieważ używam tej biblioteki do czytania obrazów do innych projektów i jestem do tego przyzwyczajony. Mogę to zmienić, jeśli istnieje lepszy sposób (który zawsze jest w R). – thequerist

Powiązane problemy