hhh
hhh

Reputation: 52810

iGraph: how to create graph with specific levels?

[Update] The below has an example that I am trying to accomplish. I am also interested in more general techniques to level arbitrary plots. Does there exist some GUI method to adjust the vertices visually after plotting them so not having to do it by hand like the Gabor solution? I have found a way to do it, see my answer below, but taking time to make it more general.

Goal

enter image description here

Failure

library(igraph)
g4<-graph.formula(Out-1:3:5:6,1-2,3-4,5:6-7,2:4:7-In)
tkplot(g4)

enter image description here

Upvotes: 2

Views: 967

Answers (2)

hhh
hhh

Reputation: 52810

but you need to set the vertex positions pretty much by hand.

This is not totally correct. I will show an easier interactive way. I will use the below code by Greg Snow.

dynmodfunc <- function() {
    plot(0:1,0:1,ann=FALSE,type='n')
    mypoints <- matrix(ncol=2, nrow=0)
    while( length(p <- locator(1, type='p', col='red')) ) {
        mypoints <- rbind(mypoints, unlist(p))
        plot(mypoints, col='red', ann=FALSE, xlim=0:1, ylim=0:1)
        if(nrow(mypoints)>1) {
            xspline(mypoints, shape=-1)
        }
    }
    mypoints
}

(out <- dynmodfunc())

I want to plot this dominance graph

enter image description here

but adjm<-t(matrix(c(0,0,0,0,1,1,0, 0,0,0,0,1,1,0, 0,0,0,0,1,1,0, 0,0,0,0,1,1,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,0, 1,1,1,1,0,0,0),nrow=7,ncol=7)); g1<-graph.adjacency(adjm); plot(g1) will generate

enter image description here

and use Greg's code: click points on the GUI and then click right-mouse-button

enter image description here

where I have the points in the order of 7-1-2-3-4-5-6 as shown by the line or by the debug:

> out
             x          y
[1,] 0.5082585 1.03551763
[2,] 0.1067841 0.59191675
[3,] 0.3818711 0.59358184
[4,] 0.6380311 0.58883584
[5,] 0.8787300 0.58464820
[6,] 0.3417308 0.09010765
[7,] 0.6614686 0.07504212
> str(out);dput(out)
 num [1:7, 1:2] 0.508 0.107 0.382 0.638 0.879 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "x" "y"
structure(c(0.508258492696219, 0.106784127536735, 0.381871061286441, 
0.63803114223351, 0.878729976271015, 0.341730770349654, 0.661468641881514, 
1.03551763062279, 0.591916752784156, 0.593581838904923, 0.588835844931958, 
0.584648203191106, 0.0901076547476853, 0.0750421150561933), .Dim = c(7L, 
2L), .Dimnames = list(NULL, c("x", "y")))

and now by Gabor Csardi's solution it should be possible to get the levelled plot. We have now the co-occurrency matrix ajdm and coordinates coords for each point. I cannot yet see how to use them with Gabor's method, trying to understand.

Code for fast copy-pasting

> library(igraph); 
> coords<-structure(c(0.508258492696219, 0.106784127536735, 0.381871061286441, 0.63803114223351, 0.878729976271015, 0.341730770349654, 0.661468641881514, 1.03551763062279, 0.591916752784156, 0.593581838904923, 0.588835844931958, 0.584648203191106, 0.0901076547476853, 0.0750421150561933), .Dim = c(7L, 2L), .Dimnames = list(NULL, c("x", "y")))
> adjm<-t(matrix(c(0,0,0,0,1,1,0,   0,0,0,0,1,1,0,   0,0,0,0,1,1,0,   0,0,0,0,1,1,0,   0,0,0,0,0,0,0,    0,0,0,0,0,0,0,   1,1,1,1,0,0,0),nrow=7,ncol=7)); g1<-graph.adjacency(adjm); plot(g1)

Upvotes: 2

Gabor Csardi
Gabor Csardi

Reputation: 10825

So just to answer this question, it is possible to do this with igraph, but you need to set the vertex positions pretty much by hand. You can use tkplot() and tkplot.getcoords() to finetune, though.

Furthermore, you need to add vertices for the junctions as well, since in igraph edges are either straight lines or curves, but not broken lines.

library(igraph)

G <- graph.formula(Out-3, j1-1:j2, j2-j4, j3-5:j5, j5-6,
                   1-2, 3-4, 5-j6, 6-j8, j6-j8, j7-7, 2-j9, 4-In, 7-j10,
                   j9-j10)

coords <- read.table(textConnection(
  "Out 2   1
   In  2   8
   1   1   4
   2   1   6
   3   2   4
   4   2   6
   5   2.5 4
   6   3.5 4
   7   3   6
   j1  1   2
   j2  3   2
   j3  2.5 3
   j4  3   3
   j5  3.5 3
   j6  2.5 5
   j7  3   5
   j8  3.5 5
   j9  1   7
   j10 3   7"))

layout <- as.matrix(coords[match(V(G)$name, coords[,1]),2:3])
layout[,2] <- -layout[,2]

V(G)$shape <- ifelse(grepl("^j", V(G)$name), "none", "circle")
V(G)$label <- ifelse(grepl("^j", V(G)$name), "", V(G)$name)
V(G)$size  <- ifelse(grepl("^j", V(G)$name), 0, 30)
V(G)$color <- "white"
V(G)$label.color <- "black"

par(mar=c(0,0,0,0)+.1)
plot(G, layout=layout, asp=NA)

plot

Upvotes: 3

Related Questions