[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.
Thanks,
---------
library(Rgraphviz)
# 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)
renderGraph(g)
}
# 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"))
label=c("0.7","-1.0")
col=c("blue","red")
width=c(2,4)
# 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(g)
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