[BioC] bug in rendering reciprocal edges?

Wouter van Atteveldt wouter at vanatteveldt.com
Mon Aug 29 18:55:33 CEST 2011

Dear list,

I want to use RGraphviz to create network diagrams of relations between actors (eg a social network), using attributes such as label, colour, and width to visualize relationship strength and valence. 

I decided to create a little helper function that takes a data frame of subject, object and optional width, label, and colour and renders that as a graph using Rgraphviz. This works fine, also for moderately complex graphs. However, reciprocal edges seem to give problems if colour and line width are used.

Below is included a small test program that creates two sets of graphs, varying on including a reciprocal and on the amount of 'features' (label, colour etc). (Syntax highlighted version at http://pastebin.com/bQGgaDiT).  

Resulting picture available at http://imageshack.us/photo/my-images/405/recip.png/ . You can see that the top row renders fine, but in the bottom row (which has a reciprocal relation) the relation from b to a loses its arrowhead when linewidths are added and disappears altogether (except for its label) when color is added.

I am using R version 2.12.1 (2010-12-16), Platform: x86_64-pc-linux-gnu (64-bit), Rgraphviz 1.28.0. I tried both RStudio and 'vanilla' R. 




# Assumes that a graph is  a data frame with columns
# subject, object, [label, width, hue, saturation, brightness]
namedvector <- function(names, values) {names(values) = names; values}

render <- function(graph) {
  nodes = union(graph$subject, graph$object)
  edges = tapply(graph$object, graph$subject, function(x) list(edges=as.character(x)), simplify=F)
  # add edges for object-only nodes (leafs)
  for (leaf in setdiff(graph$object, graph$subject)) edges[[leaf]] = list(edges=NULL)  
  # create graph
  g <- new("graphNEL", nodes = nodes, edgeL = edges, edgemode="directed")
  # add labels, width, color if given  
  edgeids = paste(graph$subject, graph$object, sep="~")
  edgeAttrs = if (is.null(graph$label)) list() else
    list(label=namedvector(edgeids, as.character(graph$label)) )
  if (!is.null(graph$col))
    edgeRenderInfo(g) <- list(col=namedvector(edgeids, as.character(graph$col)))
  if (!is.null(graph$width))
    edgeRenderInfo(g) <-  list(lwd=namedvector(edgeids, graph$width))
  if (!is.null(graph$label)) 
    edgeRenderInfo(g) <- list(label=namedvector(edgeids, as.character(graph$label)))
  # layour and render
  g = layoutGraph(g, recipEdges="distinct", edgeAttrs=edgeAttrs)

# test code: create normal and reciprocal graph and some attributes
graph = data.frame(subject=c("a", "c"), object=c("a", "a"))
rgraph = data.frame(subject=c("a", "b"), object=c("b", "a"))

# plot graphs in rows with increasing #features complexity in columns
layout(matrix(1:8, nrow=2, byrow=T))
for (g in list(graph, rgraph)) {
  render(cbind(g, label=label))
  render(cbind(g, label=label, width=width))
  render(cbind(g, label=label, width=width, col=col))

More information about the Bioconductor mailing list