3

This code plots a graph from dataframes of actors and relations.

library(igraph)
actors <- data.frame(name=c("Alice", "Bob", "Cecil", "David",
                            "Esmeralda"))
relations <- data.frame(from=c("Bob", "Cecil", "Cecil", "David",
                               "David", "Esmeralda"),
                        to=c("Alice", "Bob", "Alice", "Alice", "Bob", "Alice"),
                        friendship=c(4,15,5,2,11,1))
g <- graph_from_data_frame(relations, directed=TRUE, vertices=actors)

plot(g)

The result is:

enter image description here

I would like to change the thickness (not the length) of the arcs based on the value of relations$friendship.

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
Mark
  • 1,577
  • 16
  • 43
  • 1
    https://stackoverflow.com/questions/22301119/change-edge-thickness-in-igraph-plot-r-according-to-edge-attributes , https://stackoverflow.com/questions/25269705/plot-edges-based-on-weight-using-r-igraph, e.g. `plot(g, edge.width=E(g)$friendship)` – user20650 Oct 31 '21 at 12:04

2 Answers2

7

Try

plot(g,edge.width = E(g)$friendship, edge.arrow.size = E(g)$friendship)

enter image description here


Note that, the first value of E(g)$friendship is assigned to edge.arrow.size, instead of a vector. Maybe the improved feature will be added to future igraph version.

arrow.size The size of the arrows. Currently this is a constant, so it is the same for every edge. If a vector is submitted then only the first element is used, ie. if this is taken from an edge attribute then only the attribute of the first edge is used for all arrows. This will likely change in the future.

The default value is 1.

arrow.width The width of the arrows. Currently this is a constant, so it is the same for every edge. If a vector is submitted then only the first element is used, ie. if this is taken from an edge attribute then only the attribute of the first edge is used for all arrows. This will likely change in the future.

This argument is currently only used by plot.igraph.

The default value is 1, which gives the same width as before this option appeared in igraph.

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
2

This can be achieved very simply. First your code:

library(igraph)

actors <- data.frame(name=c("Alice", "Bob", "Cecil", "David",
                            "Esmeralda"))
relations <- data.frame(from=c("Bob", "Cecil", "Cecil", "David",
                               "David", "Esmeralda"),
                        to=c("Alice", "Bob", "Alice", "Alice", "Bob", "Alice"),
                        friendship=c(4,15,5,2,11,1))
g <- graph_from_data_frame(relations, directed=TRUE, vertices=actors)

Now let's create a graph with a thickness of 2, line color black and line type 2.

plot(g, edge.width = 2, edge.color = "black", edge.lty = 2)

enter image description here

Of course, you can change it as you like

plot(g, edge.width = 5, edge.color = "black", edge.lty = 1)

enter image description here

Hope that's what you meant.

Small update

Finally, you may want to find the coordinates of the elements. You can do it this way:

coords = layout_nicely(g)
coords[5,]=c(20, 20)
coords

output

         [,1]     [,2]
[1,] 15.21285 18.97650
[2,] 15.18511 20.08411
[3,] 14.21575 19.70269
[4,] 16.17453 19.75255
[5,] 20.00000 20.00000

Plot

plot(g, layout=coords, edge.width = 5, edge.color = "black", edge.lty = 1)

enter image description here

You can also set other cutout attributes

plot(g, vertex.size = 20, vertex.color = "red", vertex.shape = "square", 
     edge.width = 3, edge.color = "black", edge.lty = 3, 
     edge.label = relations$friendship, edge.curved = TRUE)

enter image description here

Also note that any of these parameters can also come from a vector. So there is no obstacle for the thickness to come from the variable friendship, for example.

plot(g, vertex.size = 20, vertex.color = "red", 
     vertex.shape = c("square","circle","square","circle","rectangle"), 
     edge.width = relations$friendship, edge.color = "black", edge.lty = c(1,2,3,1,2,3), 
     edge.label = 10:20, edge.curved = TRUE)

enter image description here

Marek Fiołka
  • 4,825
  • 1
  • 5
  • 20
  • 1
    I don't understand how your answer resolves the question of how to *"change the thickness of the arcs"*. All of the line thicknesses here are identical, regardless of `$friendship`. Am I missing something? – r2evans Nov 03 '21 at 20:58
  • 1
    Dear @r2evans, you are absolutely right! I just assigned `relations$friendship` to `edge.label` instead of `edge.width` out of momentum. I hope this minor oversight will be forgiven. – Marek Fiołka Nov 04 '21 at 20:22
  • Dear @r2evans, you are very nice. Thanks for **all** the upvotes I have received recently from you :-). – Marek Fiołka Nov 06 '21 at 20:24
  • Regarding the above question, when I read it, it seemed almost impossible that @Mark could only ask about such a minor matter as setting the thickness of the arrows and even fund a reward for the answer. You probably know better from me that sometimes people on SO people ask about something more than what can be read from the content of their question. In any case, it has happened to me several times that when writing an answer that accurately corresponded to the question asked, I did not receive approval because someone answered a bit more broadly. – Marek Fiołka Nov 06 '21 at 20:24
  • Answers are not always accepted based on objective metrics, sometimes they are accepted because of timing, or that a better and more-generic answer looks much scarier. If the acceptance were controlled by those who know better about the material, SO would be a very different place. I agree that it can be frustrating, but ... I can't claim not getting my "money's worth" out of this based on the $$$ cost of entry :-) – r2evans Nov 06 '21 at 21:26
  • I have already learned this learning :-) – Marek Fiołka Nov 06 '21 at 21:47