[BioC] Rgraphviz: interactive graphs, how to map coordinates to plotted graph?

Florian Hahne fhahne at fhcrc.org
Thu Sep 3 00:35:08 CEST 2009


Hi Rainer,
let me try to be the hero here :)
When you call the renderGraph method, the graph object is returned  
with some useful information added to the graphRenderInfo slot:

library(graph)
set.seed(123)
V <- letters[1:5]
M <- 1:2
g1 <- randomGraph(V, M, 0.5)
edgemode(g1) <- "directed"
x <- layoutGraph(g1)
y <- renderGraph(x)
names(graphRenderInfo(y))
[1] "bbox"         "laidout"      "recipEdges"   "nativeCoords" "figDim"
[6] "usr"          "mai"

As you can see, there are two graphical parameters in there, 'mai' and  
'usr'. The former sets the plot margins  and the letter sets the user  
coordinate system. All you need to do is extract these values and set  
the graphical parameters accordingly using the 'par' function. Please  
note that 'mai' has to be set first since it affects the value of  
'usr'. So the following little example would add the numbers 1 to 5 on  
top of the nodes:
par(mai=graphRenderInfo(y)$mai, usr=graphRenderInfo(y)$usr)
text(nodeRenderInfo(y)$nodeX, nodeRenderInfo(y)$nodeY, 1:5, col=2,  
cex=4)

Of course you could make this a bit more elegant by creating a little  
function that calls an arbitrary plotting function with the parameters  
set accordingly, something along the lines of:

addToGraph <- function(graph, fun)
{
	opar <- par(mai=graphRenderInfo(graph)$mai, usr=graphRenderInfo(graph) 
$usr)
	on.exit(par=opar)
	fun(graph)
}

And the example from above would then be:
addToGraph(y, function(g) text(nodeRenderInfo(g)$nodeX,  
nodeRenderInfo(g)$nodeY, seq_along(nodes(g)), col=3, cex=4))

Hope that's what you were looking for,
Florian


On 31.08.2009, at 23:43, Rainer Machne wrote:

> On Mon, 2009-08-31 at 14:54 +0200, Wolfgang Huber wrote:
>> Dear Rainer
>>
>> Have a look at the 'renderGraph' function:
>> showMethods("renderGraph", includeDefs=TRUE)
>>
>> and at
>>
>> r1 <- renderGraph(g1)
>> graphRenderInfo(r1)
>>
>
> Ok, thanks! Still hacking around I have changed my function to first
> plot an empty plot on the same window (par(new=T)) using
> graphRenderInfo()$bbox coordinates as xlim and ylim values, before
> calling identify() or plotting stuff using the node coordinates.
>
> bbox <- graphRenderInfo(graph)$bbox
> par(new=T, mai=c(0,0,0,0))
> plot(xy,xlim=bbox[,1],ylim=bbox[,2], pch=19, col=showNodeXY*3)
>
> This already comes much closer, but is not quite there yet.
> I guess to do it correctly would require setting or using the user  
> coordinates in "usr",
> but I don't really know how "usr" works yet. I will have a closer  
> loock at this and the
> renderGraph methods once I have some spare time (unless someone  
> jumps in heroically
> to help me out ;)
>
> Thanks,
> Rainer
>
>
>
>> Florian might be able to tell you more on how to map the output of  
>> that
>> to the user coordinates of the R graphics device.
>>
>> Best wishes
>>      Wolfgang
>>
>>
>> Btw, a "poor man's" interactive plot (in static html) can be made  
>> like
>> this: http://www.ebi.ac.uk/~huber/tooltips/IMCA/imca.R
>> resulting in http://www.ebi.ac.uk/~huber/tooltips/IMCA/imca.html
>>
>>
>>
>> -------------------------------------------------------
>> Wolfgang Huber
>> EMBL
>> http://www.embl.de/research/units/genome_biology/huber
>> -------------------------------------------------------
>>
>>
>>
>>  Machne ha scritto:
>>> Hi,
>>>
>>> I want to use interactive features of R ("identify()") on Rgraphviz
>>> plots, and also plot other things over the plotted graph (using node
>>> coordinates) after it has been rendered. However, the plotted
>>> coordinates are shifted with respect to the coordinates returned by
>>> nodeRenderInfo(graph)$nodeX/nodeY.
>>>
>>> Does anyone know an easy way to calculate this shift, avoid the  
>>> shift,
>>> or reset the plot area to coordinates used for rendering the graph?
>>> Or: are there already packages providing interactivity for
>>> Rgraphviz-rendered graphs?
>>>
>>> Below you find a small example script, including a hack of the  
>>> function
>>> identifyPch() provided by the help page "?identify" to work on
>>> renderGraph(graph) plots, here for a graph object from the ? 
>>> randomGraph
>>> help page example.
>>> This should illustrate well what i want to do and what the problem  
>>> is.
>>>
>>> The green "x" should be on the nodes but are shifted. The
>>> identifyNode(graph) function would allow to click on nodes (here the
>>> "x"), plot something over them, and e.g. return a list of selected
>>> nodes. I think this would open up the graph and Rgraphviz packages  
>>> for a
>>> lot of nice applications.
>>>
>>> Rainer
>>>
>>>
>>> # graphCoordinates.R
>>>
>>> library('Rgraphviz')
>>>
>>> ## TODO : find out how we can set coordinates to allow
>>> ## usage of identify() function in Rgraphviz graphs
>>> identifyNode <- function(graph, pch=19, showNodeXY=TRUE, ...)
>>>  {
>>>
>>>    xy <- cbind(nodeRenderInfo(graph)$nodeX,nodeRenderInfo(graph) 
>>> $nodeY)
>>>
>>>    # show where x/y coordinates would put nodes
>>>    if (showNodeXY)
>>>      points(xy, pch=4, col=3)
>>>
>>>    n <- nrow(xy)
>>>
>>>    x <- xy[,1]
>>>    y <- xy[,2]
>>>
>>>    sel <- rep(FALSE, length(x)); res <- integer(0)
>>>    while(sum(sel) < n) {
>>>      ans <- identify(x[!sel], y[!sel], n=1, plot=FALSE, ...)
>>>      if(!length(ans)) break
>>>      ans <- which(!sel)[ans]
>>>      points(x[ans], y[ans], pch = pch, col=2)
>>>
>>>      cat(paste("SELECTED NODE", rownames(xy)[ans], "\n"))
>>>
>>>      sel[ans] <- TRUE
>>>      res <- c(res, ans)
>>>    }
>>>    res
>>>  }
>>>
>>> ## 1) generate random graph, from ?randomGraph help page:
>>> set.seed(123)
>>> V <- letters[1:10]
>>> M <- 1:4
>>> g1 <- randomGraph(V, M, 0.2)
>>> numEdges(g1) # 16, in this case
>>> edgeNames(g1)# "<from> ~ <to>"  since undirected
>>>
>>> ## 2) layout and plot the graph
>>> g1 <- layoutGraph(g1)
>>> renderGraph(g1)
>>>
>>>
>>> ## 3) Identify nodes:
>>> ## After calling identifyNode(g1) please click on the graph
>>> ## to identify nodes.
>>> ## The green "x" are plotted at x/y coordinates in nodeRenderInfo
>>> ## Note that they are shifted wrt to the rendered nodes.
>>>
>>> identifyNode(g1)
>>>
>>> # End of file
>>>
>>> _______________________________________________
>>> Bioconductor mailing list
>>> Bioconductor at stat.math.ethz.ch
>>> https://stat.ethz.ch/mailman/listinfo/bioconductor
>>> Search the archives: http://news.gmane.org/gmane.science.biology.informatics.conductor
>>
>



More information about the Bioconductor mailing list