rich-iannone / DiagrammeR

Graph and network visualization using tabular data in R
https://rich-iannone.github.io/DiagrammeR/
Other
1.7k stars 249 forks source link

DiagrammeR not opening browser window when call is buried inside another function #226

Closed tbates closed 7 years ago

tbates commented 7 years ago

I've got a graphing function which writes a graphviz file, then calls DiagrammeR::DiagrammeR(diagram = file, type = "grViz") on it. All working fine.

EXCEPT, if I call this function from within another function, my graphviz file writing code still runs, but the graph is not rendered in the browser. So, I assume something is preventing the DiagrammeR call from opening a browser window.

Any thoughts on why this should be expected, or anyone else seeing this? Any work arounds? If it's new, I'll try and post some repro code.

jonmcalder commented 7 years ago

I don't think this is expected behaviour - I've tested locally and I'm able to successfully render a grViz graph either in the RStudio viewer pane or in a browser (depending on the setting of the 'viewer' option) when calling DiagrammeR() from within another function.

I think you'll need to post a reproducible example before the issue can be explored further.

tbates commented 7 years ago

If you install.packages("umx") and run this code, setting a breakpoint in DiagrammeR, you should see that a file ("ace.gv") is written , DiagrammeR is being called, but no plotting happens.

require(umx)
data(twinData)
selDVs = c("wt1", "wt2")
mz = cov(twinData[twinData$zyg == 1, selDVs], use = "complete")
dz = cov(twinData[twinData$zyg == 3, selDVs], use = "complete")
m1 = umxACE(selDVs = selDVs, dzData = dz, mzData = mz, numObsDZ=569, numObsMZ=351)

Should have plotted as umxACE calls DiagrammeR, but doesn't. The traceback stack is: umxACE->plot.MxModel.ACE -> xmu_dot_maker -> DiagrammeR

If you're on mac, then umx_set_plot_format("graphviz") will set the program to try and open Graphviz, and that works fine (toggles an IF statement in the same function that tries to call DiagrammeR.

jonmcalder commented 7 years ago

Ah ok. I may be wrong, but I think the issue here is simply that since this is non-interactive use, the DiagrammeR output needs to be explicitly returned somewhere in order for it to be rendered.

Running plot(m1) immediately after the code you provided produces the expected DiagrammeR result just fine.

If you want your above code to produce the DiagrammeR output as a side-effect, then I think you'd just need to wrap the call to DiagrammeR within umx_dot_maker() in a print statement i.e.

if (umx_set_plot_format(silent = TRUE) == "DiagrammeR") {
      print(DiagrammeR::DiagrammeR(diagram = file, type = "grViz"))
}

This is the same kind of behavior you get from ggplot - you have to either call it interactively, call it last within a function call (i.e. return it from the function), or force the output with print.

tbates commented 7 years ago

Fantastic! I'd wondered how plot() was ever working and had noticed the plot call is last, but it never occurred to me that this was equivalent to calling print (duh..). Nor that print actually means "print, which entails interacting..." Nice!