Use tkplot in igraph when matching vertex size to label - r

I am trying to apply the script suggested in another post on this forum for matching vertex size to label: Match vertex size to label size in igraph.
The solution for the plot function works perfectly but the same syntax cannot be used for the tkplot function. Replacing plot by tkplot returns an error message. I need to use the latter one because my figure has many vertexes and too long vertex labels, and i want to be able to readjust the positions of the vertexes manually. Can someone help?

This is not really an answer to your question, but a workaround. Use tkplot() to plot your vertices, adjust the vertex positions, then query the positions with tkplot.getcoords(), and use the returned coordinates in plot().

Related

R: Untangle graph plot

I have the following graph plot with 131 vertices made by using plot with an object of the igraph class. My question is whether there is any way to present this in a cleaner way so that nodes at least don't overlap each other and edges are more visible.
I'm not too familiar with these types of graphs, so I can't provide a specific answer. But this sounds like a good time to use the jitter() function which adds random noise between the data points, thus separating them out.

How to plot a graph with labels that don't superimpose on each others

I am new at R but I haven't find any topic that could answer my question.
I want to plot a graph named g, using the package igraph. However the result is not fully satisfying as the nodes names aren't all readable.
This is the code I used to plot :
plot(g, layout_nicely(g), asp=FALSE, vertex.shape=V(g)$shape, vertex.label.dist=0.3,
vertex.label.degree=-pi/2)
And this is the result
I've tried to reduce the number of characters of each label, or to reduce their font sizes but it wasn't enough. I also used several layout such as layout.kamada.kawai, layout.fruchterman.reingold but the labels are always too close to each others.
Is there any way to choose a better position for the labels or to increase the length of the edges ?
Any help would be appreciated

How can I rearrange the order of edges in an igraph plot?

I'm trying to make a network plot in igraph that highlights certain important edges by coloring them differently than the others. For large graphs, they often get buried under the others. For example:
library(igraph)
test <- barabasi.game(200,m=2)
E(test)$color <- "gray"
E(test)[1]$color <- "red"
sort(order(E(test)$color)[E(test)],decreasing=TRUE)
plot(test,
vertex.label=NA,
vertex.shape="none",
vertex.size=0,
edge.arrow.mode=0,
edge.width=2)
gives me a plot where the single red edge is at the bottom.
If I choose to color a higher-numbered edge (rather than #1) it has a better chance of not being buried.
So it seems to me that one option is to somehow re-order the edges. I tried
E(test) <- E(test)[order(E(test)$color)]
but that gets me an "invalid indexing" error. Any ideas about what else I should try?
igraph plots the edges in the order they appear in the graph's edge list, so you are right, edges with higher IDs will be drawn on top of the edges with lower IDs. Unfortunately igraph does not provide an easy way to reorder the edges of the graph (although it has a function named permute.vertices, which will allow you to permute the vertices), so the only way I can think of right now is that you need to construct another graph in which the edges are in the "right order". make_graph ensures that the edges are stored in the graph exactly in the order you specify them, and I think so does graph_from_data_frame.
Another option (if you don't want to reconstruct the entire graph) is to plot the graph twice: first you plot the "not-so-important" edges and set the width of the important ones to zero, then you plot the important edges on top.
If you would like edge permutations to be supported in an upcoming version of igraph, please file a feature request on Github.
You can reconstruct the graph with the edges reordered using "as_data_frame" and "graph_from_data_frame" fairly easily in conjunction with the dplyr and tidyr packages:
new_graph=graph_from_data_frame(d=as_data_frame(old_graph,what="edges") %>%
arrange(desc(ordering_attribute)),
vertices=as_data_frame(old_graph,what="vertices"))
if you had a layout stored on the old graph you would need to transfer it manually...
new_graph$layout = old_graph$layout
The reason why E(test) <- E(test)[order(E(test)$color)] can not work out is that we are not allowed to assign an 'igraph.es' variable to another existing one or itself; however, we can create a new 'igraph.es' varibale using: a <- E(test)[order(E(test)$color)]. Thus, we need create a new graph to inherit a new order of edges from the orginal graph:
library(igraph)
test <- barabasi.game(200,m=2)
E(test)$color <- "gray"
E(test)[1]$color <- "red"
# to make a new graph:test2 whose edges are descended from the ordering edges of the orginal graph:test
test2 <- make_graph(as.vector(t(get.edgelist(test)[order(E(test)$color),])))
# to assign the attribute value to the edges of the new graph
E(test2)$color <- E(test)$color[order(E(test)$color)]
plot(test2,
vertex.label=NA,
vertex.shape="none",
vertex.size=0,
edge.arrow.mode=0,
edge.width=2)
As the plot shows, the red edge becomes the toppest one:
Or you could simply rearrange your data based on the variable you wish to be ordered and then feed it to igraph

How to code edge attributes as vertex attributes using igraph in R

I am graphing a network and trying to color the vertices using non-overlapping attributes. I want my network diagram to be colored according to different attributes. In this example, if the first three letters of ID 2 are equal to U 50 or U 51, I want this to show up as red. I have 5 attributes I want this graph coded by and any observations that don't fall into one of the categories should be coded in a default color. In this way I will be able to see the intensity of these attributes and better communicate this to other people. So far, I have been unable to get the code to work using a variety of different coding methods. First I tried to create a new variable that assigned the correct attribute to each observation before converting it into an i graph object.
anon.nd$vertexcolor[substr(anon.nd$ID2,1,3)=="U50" | substr(anon.nd$ID2,1,3)=="U51"]<-"O"
anon.nd$vertexcolor[substr(anon.nd$ID2,1,3)=="U54" | substr(anon.nd$ID2,1,3)=="U55"]<-"P"
anon.nd$vertexcolor[anon.nd$INT.type=="K1"]<-"INT.NB"
anon.nd$vertexcolor[anon.nd$Country=="L12"]<-"UK"
anon.nd$vertexcolor[anon.nd$ID2=="U769"]<-"OBL"`
I then specified the colors I wanted to assign to each each attribute. I used the get vertex attribute code and filled in the appropriate colors.
anon.nd1<-graph.data.frame(anon.nd)
vertex_colors=get.vertex.attribute(anon.nd1,"vertexcolor")
colors=c('azure3', 'firebrick1', 'orange1', 'darkblue', 'darkolivegreen', 'gold')
vertex_colors[vertex_colors==0]=colors[1]
vertex_colors[vertex_colors==1]=colors[2]
vertex_colors[vertex_colors==2]=colors[3]
vertex_colors[vertex_colors==3]=colors[4]
vertex_colors[vertex_colors==4]=colors[5]
vertex_colors[vertex_colors==5]=colors[6]
I tried this same method using just:
vertex_colors<-vertex_colors+1
Then to plot, I changed my edge color to black, specified my layout, and change the size of my edges and vertices.
E(anon.nd1)$color="black"
nd.layout<-layout.fruchterman.reingold(anon.nd1)
plot(anon.nd1, layout=nd.layout, vertex.color=vertex_colors, vertex.size=2, edge.arrow.size=.01, vertex.label=NA)
Using this method, no color shows up on the vertices, not even the default color. Using a different method where I set the vertex attribute, I do a little better. The default color shows up, but the colors I want do not.
anon.nd2<-graph.data.frame(anon.nd)
V(anon.nd2)$colors<-"azure3"
V(anon.nd2)$colors[substr(anon.nd2$ID2,1,3)=="U50" | substr(anon.nd2$ID2,1,3)=="U51"]<-"firebrick1"
V(anon.nd2)$colors[substr(anon.nd2$ID2,1,3)=="U54" | substr(anon.nd2$ID2,1,3)=="U55"]<-"orange1"
V(anon.nd2)$colors[anon.nd2$Country=="L12"]<-"darkblue"
V(anon.nd2)$colors[anon.nd2$INT.type=="K1"]<-"darkolivegreen"
V(anon.nd2)$colors[anon.nd2$ID2=="U769"]<-"gold"
E(anon.nd2)$color<-"black"
nd.layout<-layout.fruchterman.reingold(anon.nd2)
windows(width=20, height=16)
plot(anon.nd2, layout=nd.layout, vertex.size=2, edge.arrow.size=.01, vertex.label=NA, vertex.color="vertex_colors")
I think the problem might be that I am trying to code vertex color using multiple (non-overlapping) edge attributes. But I don't know how to convert and edge attribute into a vertex attribute. I also don't know if there is some other, unidentified problem with my code.
Here is the link to my data is copied below as well as a link to my full code file which has one or two other methods I tried using to solve this problem. Any help would be much appreciated!
Data
And here is an R file with my code, which is also above: R-file
I think you are messing up your vertex_color vector, have a look at it with head().
anon.nd$vertexcolor[anon.nd$INT.type=="K1"]<-"INT.NB"
vertex_colors[vertex_colors==0]=colors[1]
You first assign a string and then compare with numbers, so non of them should be true.
plot(anon.nd2, layout=nd.layout, vertex.size=2, edge.arrow.size=.01, vertex.label=NA, vertex.color="vertex_colors")
This contains a typo and returns an error for me since "vertex_colors" isn't a colour name.
Last but not least, does
plot(anon.nd2, vertex.color=colors)
or
plot(anon.nd2, vertex.color=1:8)
result in a colourful plots? If yes, the vertex_colors vector is your problem, if not something else is.

How to sort and visualize a directed graph?

I am using R with igraph and I have a square matrix with weights. I want to sort it. I thought to use page.rank(g) and I got a corresponding vector and its values.
library(igraph)
g<-get.matrix()
page.rank(g)$value
page.rank(g)$vector
Now I want to sort using this values and visualizing it in a graph if it is possible.
Something similar to the following picture:
How I could do this?
Choose a force-based layout and set the vertex size (vertex.size) to be proportional to the page rank values. See an example on the igraph homepage on how to set the vertex size. (The example uses tkplot, but you can just use plot instead of that.) You can set the vertex labels via the vertex.label argument to plot, and \n is allowed to make multi-line labels.

Resources