2

[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

hhh
  • 50,788
  • 62
  • 179
  • 282
  • 1
    Maybe [Rgraphviz](http://www.bioconductor.org/packages/2.11/bioc/html/Rgraphviz.html) is better suited to this task. – Tyler Rinker Mar 29 '13 at 01:17
  • if all you want is that the graph look like the image you have put up, then try the `layout` parameter of the graph. you can specify the layout as a matrix containing the coordinates of each vertex. `layout.g4<- matrix(c(...vertex coordinates here...),nrow=7,ncol=2)` – Venkatramanan P.R. Mar 29 '13 at 05:31
  • 2
    igraph is for graph theory, it is not a diagramming tool, so it is not the best for this task. If you want to do this from R, you can take a look at the diagram package, that seems to be able to do things like this. – Gabor Csardi Mar 29 '13 at 08:44

2 Answers2

3

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

Gabor Csardi
  • 10,705
  • 1
  • 36
  • 53
  • I realised an interactive way to align the vertices so not manually deciding the locations of the points. Could you preview my [code](http://stackoverflow.com/a/15744409/164148). It contains co-occurrency matrix and coordinates for each vertex. Your answer somehow specifies the locations but cannot yet understand how it really works. I did a dominance graph about the example in question. Now is there any plot like `PlotXYZ(co-occurrencyMatrix, coordinatesForVertices)` where co-occurency matrix is 7x7 matrix and coordinatesForVertices is 7x2 matrix with x-y-coordinates? – hhh Apr 01 '13 at 13:36
  • Well, "by hand" is not completely correct, indeed. What I wanted to write was "some way, other than using an igraph layout". So yeah, if there is some code/toool to generate the coordinates, then it is easy to create the plot, but then the plot was not really created with igraph. – Gabor Csardi Apr 01 '13 at 17:35
2

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)
Community
  • 1
  • 1
hhh
  • 50,788
  • 62
  • 179
  • 282