Entering edit mode
Wouter van Atteveldt
▴
20
@wouter-van-atteveldt-4823
Last seen 10.2 years ago
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))
}