Search code examples
rigraphdata-manipulationadjacency-matrixsna

using igraph to plot asymmetric ties


HAVE is a two-mode adjacency matrix of lead actors (ids in the 1st column) and supporting actors (ids in the column names).

    f1  f2  f3  f4  f5  f6  f7
f1  0   1   0   2   5   0   6
f2  0   0   3   0   0   6   0
f3  9   4   0   1   0   0   0

The numbers in the matrix are film counts. The matrix is asymmetric. For example, f2 played the lead in a film with f3 in a supporting role three times, but f3 was the lead in a film where f2 supported four times.

I need to produce a directed graph where arrows are drawn from actors to supporters - the size of the arrow/arc needs to be proportional to the number of films. See below for the mock-up of the f2-f3 dyad:enter image description here

The identical naming conventions in both "modes" of the graph obviously cause problems. Let me know if you have any clear solutions, or if I'm not asking my question well (I'm new to igraph and two-mode projections). Thanks!


Solution

  • If you look at the help page help(igraph.plotting), you can find that it says:

    arrow.size

    The size of the arrows. Currently this is a constant, so it is the same for every edge.

    So I do not think it is possible to accomplish this by the size of the arrow head. However, it certainly is possible to vary the line width of the arrows using the parameter edge.width.

    Since you do not provide any data, I am including a small example that I think you should be able to match to your problem.

    Sample Data

    CoStar = matrix(c(0,1,3,1, 3,0,3,1, 2,1,0,0, 0,1,1,0), nrow=4)
    CoStar
         [,1] [,2] [,3] [,4]
    [1,]    0    3    2    0
    [2,]    1    0    1    1
    [3,]    3    3    0    1
    [4,]    1    1    0    0
    

    Now we can turn this into a graph object and display it using the weights as the edge width. You need to use the edge.curved parameter so that the edge A->B is not on top of the edge B->A.

    library(igraph)
    G = graph_from_adjacency_matrix(CoStar, weighted=TRUE)
    V(G)$label = c("Steve", "Sean", "Andy", "Tim")
    plot(G, edge.width=E(G)$weight+1, edge.arrow.size=1.5, edge.curved=0.25)
    

    Asymmetric graph

    You can see that the edge sizes are proportional to the weights (number of joint appearances).