Draw Network in R (control edge thickness plus non-overlapping edges)

后端 未结 4 786
醉话见心
醉话见心 2021-01-30 15:27

I need to draw a network with 5 nodes and 20 directed edges (an edge connecting each 2 nodes) using R, but I need two features to exist:

  1. To be able to control the
相关标签:
4条回答
  • 2021-01-30 15:32

    The 'non overlapping' constraint on edges is the big problem here. First, your network has to be 'planar' otherwise it's impossible in 2-dimensions (you cant connect three houses to gas, electric, phone company buildings without crossovers).

    I think an algorithm for planar graph layout essentially solves the 4-colour problem. Have fun with that. Heuristics exist, search for planar graph layout, and force-directed, and read Planar Graph Layouts

    0 讨论(0)
  • 2021-01-30 15:45

    If it is ok for the lines to be curved then I know two ways. First I create an edgelist:

    Edges <- data.frame(
        from = rep(1:5,each=5),
        to = rep(1:5,times=5),
        thickness = abs(rnorm(25)))
    
    Edges <- subset(Edges,from!=to)
    

    This contains the node of origin at the first column, node of destination at the second and weight at the third. You can use my pacake qgraph to plot a weighted graph using this. By default the edges are curved if there are multiple edges between two nodes:

    library("qgraph")
    qgraph(Edges,esize=5,gray=TRUE)
    

    qgraph

    However this package is not really intended for this purpose and you can't change the edge colors (yet, working on it:) ). You can only make all edges black with a small trick:

    qgraph(Edges,esize=5,gray=TRUE,minimum=0,cut=.Machine$double.xmin)
    

    For more control you can use the igraph package. First we make the graph:

    library("igraph")
    g <- graph.edgelist(as.matrix(Edges[,-3]))
    

    Note the conversion to matrix and subtracting one because the first node is 0. Next we define the layout:

    l <- layout.fruchterman.reingold(g)
    

    Now we can change some of the edge parameters with the E()function:

    # Define edge widths:
    E(g)$width <- Edges$thickness * 5
    
    # Define arrow widths:
    E(g)$arrow.width <- Edges$thickness * 5
    
    # Make edges curved:
    E(g)$curved <- 0.2
    

    And finally plot the graph:

    plot(g,layout=l)
    

    igraph

    0 讨论(0)
  • 2021-01-30 15:47

    The package informatively named 'network' can draw directed networks fairly well, and handle your issues.

    ex.net <- rbind(c(0, 1, 1, 1), c(1, 0, 0, 1), c(0, 0, 0, 1), c(1, 0, 1, 0))
    
    plot(network(ex.net), usecurve = T, edge.curve = 0.00001,
         edge.lwd = c(4, rep(1, 7)))
    

    The edge.curve argument, if set very low and combined with usecurve=T, separates the edges, although there might be a more direct way of doing this, and edge.lwd can take a vector as its argument for different sizes.

    It's not always the prettiest result, I admit. But it's fairly easy to get decent looking network plots that can be customized in a number of different ways (see ?network.plot).

    0 讨论(0)
  • 2021-01-30 15:50

    While not an R answer specifically, I would recommend using Cytoscape to generate the network.

    You can automate it using a RCytoscape. http://bioconductor.org/packages/release/bioc/html/RCytoscape.html

    0 讨论(0)
提交回复
热议问题