Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In igraph in R, is it possible to create dotted lines around the vertex objects?

Tags:

r

igraph

In igraph in R, I currently have a graph looking like:

enter image description here

which was made from the code:

g <- make_undirected_graph(edges = c(1, 3, 2, 1, 2, 4, 3, 4, 4, 5), n = 5)

I would like to instead have dotted lines on the vertices, which are circles. There is an edge.label option, but no vertex.label option. Is there another way to do this? thanks.

like image 342
user321627 Avatar asked Oct 24 '19 14:10

user321627


People also ask

Does igraph support different vertex shapes when plotting graphs?

Starting from version 0.5.1 igraph supports different vertex shapes when plotting graphs. RDocumentation Moon Search all packages and functions igraph(version 0.7.1)

How can I draw a graph in R?

There are currently three different functions in the igraph package which can draw graph in various ways: plot.igraph does simple non-interactive 2D plotting to R devices. Actually it is an implementation of the plot generic function, so you can write plot (graph) instead of plot.igraph (graph).

How to set vertex and edge attributes in a graph?

Setting vertex and edge attributes are handy if you want to assign a given ‘look’ to a graph, attributes are saved with the graph is you save it with save or in GraphML format with write_graph, so the graph will have the same look after loading it again.

What is the vertex sequence of a graph?

A vertex sequence is tied to the graph it refers to: it really denoted the specific vertices of that graph, and cannot be used together with another graph.


3 Answers

You can define your own shapes: https://igraph.org/r/doc/shapes.html and an example of a point with a dotted border is given at https://r.789695.n4.nabble.com/Drawing-a-dotted-circle-td4655331.html. A full example of creating a new shape given at https://lists.gnu.org/archive/html/igraph-help/2013-03/msg00030.html. Also see more examples at ?add_shape. The example below tweaks the code from lists.gnu.org to combine everything.

Function to create new igraph shape

myimg <- function(coords, v=NULL, params) {
  vertex.color <- params("vertex", "color")
  if (length(vertex.color) != 1 && !is.null(v)) {
    vertex.color <- vertex.color[v]
  }
  vertex.size  <- 1/200 * params("vertex", "size")
  if (length(vertex.size) != 1 && !is.null(v)) {
    vertex.size <- vertex.size[v]
  }
  vertex.frame.color <- params("vertex", "frame.color")
  if (length(vertex.frame.color) != 1 && !is.null(v)) {
    vertex.frame.color <- vertex.frame.color[v]
  }
  vertex.frame.width <- params("vertex", "frame.width")
  if (length(vertex.frame.width) != 1 && !is.null(v)) {
    vertex.frame.width <- vertex.frame.width[v]
  }
  ltype <- params("vertex", "ltype")
  if (length(ltype) != 1 && !is.null(v)) {
    ltype <- ltype[v]
  }   

  mapply(coords[,1], coords[,2], vertex.color, vertex.frame.color,
         vertex.size, vertex.frame.width, ltype, 
         FUN=function(x, y, bg, fg, size, lwd, lty) {
           symbols(x=x, y=y, bg=bg, fg=fg, lwd=lwd, lty=lty,
                   circles=size, add=TRUE, inches=FALSE)
         })
  }

You then make igraph recognise the shape using add_shape. You set default parameter values using the parameters argument.

library(igraph)

g <- make_undirected_graph(edges = c(1, 3, 2, 1, 2, 4, 3, 4, 4, 5), n = 5)

add_shape("myimg",  plot=myimg, 
          parameters = list(
            vertex.frame.color=1, 
            vertex.frame.width=1,
            vertex.ltype=1))

Then plot

plot(g,  vertex.shape="myimg", 
         vertex.frame.color=1:5, 
         vertex.frame.width=5, 
         vertex.ltype=1:5,
         vertex.color=6:10,
         vertex.size=seq(50, 80, length=5))

To get all the borders dotted just use vertex.ltype="dotted" or vertex.ltype=3.

enter image description here

like image 79
user20650 Avatar answered Nov 01 '22 08:11

user20650


I'm not sure how to do this within igraph, but one option would be to print it using ggraph, a package that bridges igraph with ggplot2. Then we can build up the graph in layers and specify the appearance of each one:

library(ggraph)
ggraph(g) +
  geom_edge_link(color = "gray60") +
  geom_node_circle(aes(r = 0.1), lty = "dashed", fill = "orange") +
  geom_node_text(aes(label = ggraph.orig_index)) +
  coord_equal() +
  theme_void()

enter image description here

like image 26
Jon Spring Avatar answered Nov 01 '22 08:11

Jon Spring


I don't use igraph but I found the network package a good replacement of it, and it's plotting function is more intuitive (if you are familiar with the base plot parameters) and easier to customize. But I am 100% sure you could find a similar function in igraph that lets you adjust the plot parameters.

require(network)

# build the network
g = as.network.matrix(x = matrix(c(1, 3, 2, 1, 2, 4, 3, 4, 4, 5), nrow = 5, byrow = T), matrix.type = 'edgelist', directed = F)

# vertex.lty is the parameter you are looking for, and you can pass an array to it.
# lty = 2 for dashed lines and lty = 3 for dotted lines.
plot(g, label = 1:5, label.pos = 5, 
     vertex.cex =6, vertex.col = "#ffdd88",
     vertex.lty = c(1,2,2,3,3), vertex.lwd = c(2,3,4,2,3)) 

enter image description here

(Edited for better formatting.)

like image 32
Yue Y Avatar answered Nov 01 '22 08:11

Yue Y