Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot output any DiagrammeR graph to a pdf file through knitr #133

Closed
ghost opened this issue Oct 3, 2015 · 42 comments
Closed

cannot output any DiagrammeR graph to a pdf file through knitr #133

ghost opened this issue Oct 3, 2015 · 42 comments

Comments

@ghost
Copy link

ghost commented Oct 3, 2015

Hi, I am using DiagrammeR to make flow charts. Everything is fine on the environment of html output mode. But when I switch to pdf output, it could not be done. After some troubleshooting, the problem is derived from diagrammeR that its plots are html format.

....(omitted)
|.................................................................| 100%
  ordinary text without R code


output file: dataProcess.knit.md

Error: Functions that produce HTML output found in document targeting latex output.
Please change the output type of this document to HTML.
Execution halted
@dchiu911
Copy link

dchiu911 commented Oct 9, 2015

I came across the same problem trying to embed flowchart in Beamer presentation (PDF).

@rich-iannone
Copy link
Owner

@HalbertDong There's been a recent update that addresses this issue. Could you try again and report on whether the problem persists (or is solved)? Thanks!

@dchiu911
Copy link

dchiu911 commented Oct 9, 2015

Error: Functions that produce HTML output found in document targeting beamer output. Please change the output type of this document to HTML.

@ghost
Copy link
Author

ghost commented Oct 11, 2015

@rich-iannone Hi, thank you for your update. I just tried and it's still not gonna work. Here are the log:

  |.................................................................| 100%
  ordinary text without R code


output file: dataProcess.knit.md

Error: Functions that produce HTML output found in document targeting latex output.
Please change the output type of this document to HTML.
Execution halted

@sculptor3
Copy link

@rich-iannone Any news regarding this issue? I get the same error when trying to embed the diagrammer graph in a pdf. I really like this package. Being able to embed the graphs in pdf would be most welcome. Thanks!

@rich-iannone
Copy link
Owner

@HalbertDong @dchiu911 @sculptor3 Thanks for reporting (and I apologize for being late in getting to this). This issue, unfortunately, has been one of the more difficult ones to resolve.

@sculptor3 can you post a bit code that causes the error?

@sculptor3
Copy link

@rich-iannone Thank you for digging into it!

this is a piece of code that gives an error when trying to knit it as pdf in RStudio:

---
title: "PDF document"
output:
  pdf_document:
    fig_caption: yes
    latex_engine: xelatex
    number_sections: yes
    toc: yes
    toc_depth: 3
  html_document:
    self_contained: yes
    theme: cerulean
    toc: yes
---
# test code
```{r results="asis",eval=TRUE,echo=FALSE,message=FALSE, error=FALSE, warning=FALSE, comment = NA,fig.height=10}
library(DiagrammeR)
df <- structure(list(node = c("a", "b", "c", "d", "e", "f"), text = c("this is a piece of text", 
"and this as well", "and this", "and this as well", "here again", 
"and again")), .Names = c("node", "text"), row.names = c(NA, 
6L), class = "data.frame")
nodes <-  
  create_nodes(nodes = c(df[1,2],df[3,2],df[4,2],df[5,2],df[6,2]),
               label = TRUE,
               type = "lower",
               #style = "filled",
               fontcolor = "white",
               color = "DodgerBlue",
               shape = c("rectangle", "rectangle",
                         "circle","circle","rectangle"))
edges <-
  create_edges(from = c(df[1,2],df[3,2],df[1,2],df[3,2]),
               to = c(df[3,2],df[4,2],df[5,2],df[6,2]),
               relationship = "leading_to")
graph <-
  create_graph(nodes_df = nodes,
               edges_df = edges,
                node_attrs = c("fontname = Helvetica",
                              "style = filled"),
               edge_attrs = c("color = gray20","penwidth= 3",
                              "arrowsize = 1.5"))
render_graph(graph)
```

@sculptor3
Copy link

When I use

render_graph(graph)

the error is:

Error: Functions that produce HTML output found in document targeting latex output.
Please change the output type of this document to HTML. 

and no pdf document is created, But when I change the render_graph code
into

render_graph(graph, output="svg")

a pdf documented is created, but without the graph (and maybe that's obvious, I am not sure if that's one of the possible outputs).

@rich-iannone I hope this helps. Do you need more information?

@millerjef
Copy link

@rich-iannone I suspect I'm having a similar issue, though with slightly different manifestations that I hope might track down the problem. I'm trying to export a flowchart graph to SVG or EMF but I'm getting empty files. I'm not getting any error messages.

When I use the devEMF package, an emf file is created (204 bytes). If I open it in powerpoint, the canvas size appears to be consistent with the HTML flowchart rendered in the RStudio plot window.

The sample code on the DiagrammeR website (http://rich-iannone.github.io/DiagrammeR/graphs.html) produces a svg file of zero bytes but does render properly in the RStudio plot window:

###
# Create node and edge data frames for graph
###

library(DiagrammeR)
library(pipeR)
library(V8)

# Create a node data frame
nodes <-
  create_nodes(nodes = LETTERS,
               type = "letter",
               shape = sample(c("circle", "rectangle"),
                              length(LETTERS),
                              replace = TRUE),
               fillcolor = sample(c("aqua", "gray80",
                                    "pink", "lightgreen",
                                    "azure", "yellow"),
                                  length(LETTERS),
                                  replace = TRUE))

edges <-
  create_edges(from = sample(LETTERS, replace = TRUE),
               to = sample(LETTERS, replace = TRUE),
               relationship = "letter_to_letter")

# Generate an SVG file
create_graph(nodes_df = nodes,
             edges_df = edges,
             graph_attrs = "layout = neato",
             node_attrs = c("fontname = Helvetica",
                            "style = filled"),
             edge_attrs = c("color = gray20",
                            "arrowsize = 0.5")) %>>%
  render_graph(output = "SVG") %>>% cat(file = "~/graph.svg")

This behavior is occurring regardless of whether I'm using DiagrammeR version 0.8.1 from CRAN or via github.

My sessionInfo() is as follows:

R version 3.2.0 (2015-04-16)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.10.5 (Yosemite)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] DiagrammeR_0.8.1 V8_0.9           pipeR_0.6.0.6    devEMF_2.0      

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.1      visNetwork_0.1.2 digest_0.6.8     R6_2.1.1         jsonlite_0.9.17  magrittr_1.5     httr_1.0.0      
 [8] stringi_1.0-1    curl_0.9.3       rstudioapi_0.3.1 devtools_1.9.1   tools_3.2.0      stringr_1.0.0    htmlwidgets_0.5 
[15] yaml_2.1.13      memoise_0.2.1    htmltools_0.2.6 

@millerjef
Copy link

@rich-iannone Is it possible that dot svg output is failing on single-quoted attributes/objects?

I'm not much of a programmer but I wanted to troubleshoot this. I generated dot.gv using the sample code on the project website. To debug things, I downloaded the graphviz port for OS X via homebrew. I tried running dot -Tsvg dot.gv from the command line. I got the following error:

Error: dot.gv: syntax error in line 11 near '''

To be clear, dot graphviz from the command line fails to compile the dot.gv file created through the DiagrammeR package using render_graph(output = "DOT") %>>% cat(file = "~/dot.gv")

I created a minimal .gv file:

digraph {
graph [layout = dot]
node [fontname = Helvetica,
     style = filled]
  'A' [shape = 'circle'] 
  'B' [shape = 'circle'] 
edge [color = gray20,
     arrowsize = 0.5]
  'A' -> 'B'
}

The preview button in RStudio, which generates DiagrammeR::grViz("dot.gv") works as expected on the above code, but dot -Tsvg dot.gv on the above code produces an error: Error: dot.gv: syntax error in line 5 near '''

However, the preview button and the command line dot -Tsvg dot.gv compile as expected if I remove the quotes in the dot.gv file as below:

digraph {
graph [layout = dot]
node [fontname = Helvetica,
     style = filled]
  A [shape = circle] 
  B [shape = circle] 
edge [color = gray20,
     arrowsize = 0.5]
  A -> B
}

I played around with things a bit more. dot seems to choke on both single-quoted nodes (e.g., A, B) and the attributes (e.g., circle). However, " (double quotes) seem to work fine; so, this also works:

digraph {
graph [layout = dot]
node [fontname = Helvetica,
     style = filled]
  "A" [shape = "circle"] 
  "B" [shape = "circle"] 
edge [color = gray20,
     arrowsize = 0.5]
  "A" -> "B"
}

Thoughts?

@rich-iannone
Copy link
Owner

@millerjef SVG is only failing because the support for it had to be taken out (it will be re-implemented in a separate, GitHub-only package).

DiagrammeR does a few things behind the scenes to handle quoted IDs and attribute values. Strictly, these things should not have quotes as you have observed when using the native Graphviz binary.

@sculptor3
Copy link

@rich-iannone, for me this new GitHub-only package announcement is the best news of the week! :-). Please let me know if you need testers.

@sculptor3
Copy link

@rich-iannone, I am very curious, any news regarding this topic?

@Puriney
Copy link

Puriney commented Dec 2, 2015

Thought an old issue. I came across this problem as well. Furthermore I cannot even export the PNG image.


separate package for exporting Graphviz diagrams in DiagrammeR to SVG: https://github.com/rich-iannone/DiagrammeRsvg

It helps. Thanks for your work.

@rich-iannone
Copy link
Owner

@Puriney I've put together a separate package for exporting Graphviz diagrams in DiagrammeR to SVG: https://github.com/rich-iannone/DiagrammeRsvg. It contains a single function that performs the conversion of a grViz object to SVG text. An example is included in the help file for the function.

@sculptor3
Copy link

@rich-iannone I haven't figured out yet how this new package can help me putting my graph in a pdf. Taking into account my example earlier in this thread, how would you use export_svg function to render the graph in the pdf document? Or @Puriney can you give me a hint?

---
title: "PDF document"
output:
  pdf_document:
    fig_caption: yes
    latex_engine: xelatex
    number_sections: yes
    toc: yes
    toc_depth: 3
  html_document:
    self_contained: yes
    theme: cerulean
    toc: yes
---
# test code
```{r results="asis",eval=TRUE,echo=FALSE,message=FALSE, error=FALSE, warning=FALSE, comment = NA,fig.height=10}
library(DiagrammeR)
df <- structure(list(node = c("a", "b", "c", "d", "e", "f"), text = c("this is a piece of text", 
"and this as well", "and this", "and this as well", "here again", 
"and again")), .Names = c("node", "text"), row.names = c(NA, 
6L), class = "data.frame")
nodes <-  
  create_nodes(nodes = c(df[1,2],df[3,2],df[4,2],df[5,2],df[6,2]),
               label = TRUE,
               type = "lower",
               #style = "filled",
               fontcolor = "white",
               color = "DodgerBlue",
               shape = c("rectangle", "rectangle",
                         "circle","circle","rectangle"))
edges <-
  create_edges(from = c(df[1,2],df[3,2],df[1,2],df[3,2]),
               to = c(df[3,2],df[4,2],df[5,2],df[6,2]),
               relationship = "leading_to")
graph <-
  create_graph(nodes_df = nodes,
               edges_df = edges,
                node_attrs = c("fontname = Helvetica",
                              "style = filled"),
               edge_attrs = c("color = gray20","penwidth= 3",
                              "arrowsize = 1.5"))
render_graph(graph)
```

@sculptor3
Copy link

I tried this:

instead of

render_graph(graph)

I write:

svg_file <- export_svg(render_graph(graph))
 cat(svg_file, file = "svg_file.svg",sep = "\n")
 cat("![](svg_file.svg)")

this is the result:

pandoc.exe: Unable to convert image `svg_file.svg':
Cannot load file
Jpeg Invalid marker used
PNG Invalid PNG file, signature broken
Bitmap Invalid Bitmap magic identifier
GIF Invalid Gif signature :  
                   }
l.144 ...time: 8 ms \includegraphics{svg_file.svg}

Any ideas about how to solve this? Many thanks in advance.

p.s. Maybe it's better to add this issue to the DiagrammeRsvg github repository, but since this thread was intended to make it possible to insert a DiagrammeR into pdf, I continued here.

@sculptor3
Copy link

Has anyone succeeded in including an DiagrammeR graph into a pdf document rendered by rmarkdown yet (and using the new DiagrammeRsvg package)? Please, help me with an example. Many, many thanks in advance!

@skanskan
Copy link

Could the DiagrammeRsvg package also be used to export ggvis plots?

@slowkow
Copy link

slowkow commented Jan 31, 2016

@sculptor3 This is how I found I could include a Graphviz plot in my PDF rendered by rmarkdown:

Installation

First, make sure you have the dot command. You need to install graphviz (I use homebrew):

brew install graphviz

Now I have dot installed:

which dot
/usr/local/bin/dot

temp.Rmd

This is what my .Rmd file contains:

---
title: "Untitled"
author: "Kamil Slowikowski"
date: "January 31, 2016"
output: pdf_document
---

```{r}
system('echo \'
digraph DAG {

  # Intialization of graph attributes
  graph [overlap = false,
         layout = dot,
         rankdir = LR]

  # Initialization of node attributes
  node [shape = plaintext,
        fontname = Helvetica,
        fixedsize = false]

  # Initialization of edge attributes
  edge [color = black,
        rel = yields,
        fontname = Helvetica]

  a->b->c
}
\' > graph.dot')
system('dot -Tpdf graph.dot -o graph.pdf')
```

![graph](graph.pdf)

temp.pdf

The output PDF looks like this:

temp.pdf

image

@sculptor3
Copy link

Dear Kamil,

Thank you for your solution! I will try it.

I had another idea the other day. Jeroen Ooms came up with another
brilliant package: https://www.opencpu.org/posts/svg-release/

Since this package rsvg is able to convert svg to png or jpg, and Richards
new github only package is able to convert r diagrammer objects to svg,
this chain should be possible in theory: let an r chunk render a
diagrammer, convert it to svg, convert the svg to png, save it and include
it back in the document as png and render the document as pdf. Am I right?
I haven't had time to try this yet, but I will in the near future.

Kind regards
Op 31 jan. 2016 20:16 schreef "Kamil Slowikowski" <notifications@github.com

:

@sculptor3 https://github.com/sculptor3 This is how I found I could
include a Graphviz plot in my PDF rendered by rmarkdown:
Installation

First, make sure you have the dot command. You need to install graphviz
(I use homebrew):

brew install graphviz

Now I have dot installed:

which dot
/usr/local/bin/dot

temp.Rmd

This is what my .Rmd file contains:


title: "Untitled"
author: "Kamil Slowikowski"
date: "January 31, 2016"

output: pdf_document

system('echo \'
digraph DAG {

  # Intialization of graph attributes
  graph [overlap = false,
         layout = dot,
         rankdir = LR]

  # Initialization of node attributes
  node [shape = plaintext,
        fontname = Helvetica,
        fixedsize = false]

  # Initialization of edge attributes
  edge [color = black,
        rel = yields,
        fontname = Helvetica]

  a->b->c
}
\' > graph.dot')
system('dot -Tpdf graph.dot -o graph.pdf')

graph

temp.pdf

The output PDF looks like this:

temp.pdf
https://github.com/rich-iannone/DiagrammeR/files/111458/temp.pdf

[image: image]
https://cloud.githubusercontent.com/assets/209714/12704249/acae9054-c824-11e5-857a-72fe630d7a82.png


Reply to this email directly or view it on GitHub
#133 (comment)
.

@skanskan
Copy link

skanskan commented Feb 1, 2016

Can the svg or the graphviz solutions be used on Windows?

@rich-iannone
Copy link
Owner

@sculptor3 @Haodong @millerjef @slowkow @Puriney : thanks for your patience on this issue. I think I've got a workaround thanks to the great information within this thread (thanks @sculptor3 for the tip on rsvg!).

Here's a pretty ugly way of getting a graph (with Graphviz-type output) into a PNG file in the working directory. (I'll make this more functional in DiagrammeR proper but, for now, it's a useful proof of concept.)

# Install the development version of `DiagrammeRsvg`
devtools::install_github('rich-iannone/DiagrammeRsvg')

# Load other necessary libraries
library(DiagrammeR)
library(DiagrammeRsvg)
library(magrittr)
library(svglite)
library(rsvg)
library(png)

# Create a random graph
graph <-
  create_random_graph(
    80, 140,
    directed = TRUE,
    fully_connected = TRUE,
    set_seed = 25)

# Create a PNG of this graph
export_svg(grViz(graph$dot_code)) %>%
  charToRaw %>% rsvg %>% png::writePNG('graph.png')

It works on my system but do test it out on yours. It doesn't require the use of the dot binary so it should work on all systems that can load the necessary packages. Moreover, this should work with RMarkdown documents since an actual image file is available.

@skanskan
Copy link

skanskan commented Feb 1, 2016

@rich-iannone Hello, I had to install many things but it works perfectly. (tried with R 3.2.3)
Could you please tell me how to use it to include diagrammer diagrams with knitr Rnw files (latex), please.
It would be even better if I knew how to embed the diagrams directly in svg format in the pdf.

Regards.

@Wario84
Copy link

Wario84 commented Aug 21, 2016

Hi,

I have tried to embed a ggvis plot in a pdf using knitr without success. I have failed to use the export_png() from ggvis, I read the installing vega on windows has problems. I was wondering if it is possible to use DiagrammeRsvg/DiagrammeR to export the ggvis object to PNG? My final goal is to embed it in a pdf doc using knitr.

Thanks a lot for any suggestion,

@ellereve
Copy link

Is there any solution for including a DiagrammeR figure into Knitr for the less tech savvy?

@ellereve
Copy link

@skanskan ever get it to work?

@rich-iannone
Copy link
Owner

@ellereve for now, the only solution is to install webshot and phantomjs. I'll work on including documentation to help with this.

@skanskan
Copy link

webshot? I guess this won't allow any interactivity, just an static image

@HJAllen
Copy link

HJAllen commented Feb 17, 2017

I was able to successfully output a grviz chart as follows. Note the need for capture.output so that pre-main prep time: is not put to stdin.

```{r stndQAFlow}

stnds.qa.d<-"digraph {
	
	  # Nodes
	  node [shape = diamond]
	  cvF [label = 'CV Fail > 0']
	  cvF0 [label = 'Standard 0\n Fail']
    cvF01 [label ='Supplement\n Standard 0\nwith LRBs']
	  cvF15 [label = 'CV <= 15%']
	  calc [shape = rectangle, label = 'Calculate Standard Curve']
	  cvF1 [label = 'CV Failures > 1']
    outlier [label = 'Test Standard\nReplicates\nas outlier']
	  
	  # Edges
	  edge [color = black,
	        arrowhead = vee]
	  rankdir = TD
	  cvF->calc [label = 'No']
	  cvF->cvF0 [label = 'Yes']
	  cvF0->cvF1 [label = 'No'] 
	  cvF0->cvF01 [label = 'Yes']
    cvF01->cvF1 [label = 'CV <= 10%']
    cvF1->cvF15 [label = 'No']
    cvF1->outlier [label = 'Yes']
    cvF15->calc [label = 'Yes']
    cvF15->outlier [label = 'No']
    outlier->calc[label = 'Discard\nOutliers']

	{rank=same; cvF; calc}
	{rank=same; cvF0; cvF1}
	{rank=same; cvF1; cvF15}
	  
	}"
stnds.qa.d2 <- grViz(stnds.qa.d)
tmp<-capture.output(rsvg_png(charToRaw(export_svg(stnds.qa.d2)),'stnds.qa.png'))
cat('![Standards QA flowchart](stnds.qa.png){#fig:stnds.qa.flow}\n\n')
```

![Standards QA flowchart](stnds.qa.png){#fig:stnds.qa.flow}

with graph looking like:
stnds qa

@rich-iannone
Copy link
Owner

@HJAllen this is phenomenal! I've tried to no avail to eliminate that message. I'll take what's here and try to suppress this message as part of the function.

@jrgant
Copy link

jrgant commented Mar 4, 2017

Great solution, @HJAllen! Used this with rsvg_pdf and have a nice, scalable diagram. Thank you!

@skanskan
Copy link

skanskan commented Mar 4, 2017

Graphviz 2.38 is now three years old.
Is there any newer version or alternative software for Windows?

@rich-iannone
Copy link
Owner

@skanskan I'm looking into using the latest release of the viz.js JavaScript library which provides Graphviz 2.40.1. There will have to be some testing but I hope to have this change implemented in less than 2 weeks.

@puterleat
Copy link

Just on the issue above, I'm using the following function to insert digraphs into rmarkdown beamer presentations:

pdf_digraph <- function(filename, code){
  capture.output({
  g <- grViz(paste("digraph{", code, "}"))
  DiagrammeRsvg::export_svg(g) %>% charToRaw %>% rsvg::rsvg_pdf(filename)
  },  file='NUL')
  knitr::include_graphics(filename)
}

@rstub
Copy link

rstub commented Jul 12, 2017

Is this solution GraphViz only, or should it also work for mermaid (sequence) diagrams? I get the error message

## Error in context_eval(join(src), private$context): abort(0) at Error
##     at jsStackTrace (:5:22063)
##     at stackTrace (:5:22246)
##     at abort (:28:10646)
##     at nullFunc_iii (:5:662060)
##     at Array.a8 [as 0] (:21:31632)
##     at iC (:9:83383)
##     at aD (:9:102096)
##     at uF (:9:173803)
##     at pG (:9:204482)
##     at xc (:11:738)

when trying to process this example:

---
title: "DiagrammeR PDF"
author: "Ralf Stubner"
date: "12 Juli 2017"
output: pdf_document
---

```{r setup, include=FALSE}
library(DiagrammeR)
library(DiagrammeRsvg)
library(rsvg)
```

```{r, echo=FALSE}
seq <- mermaid("
sequenceDiagram
  customer->>ticket seller: ask ticket
  ticket seller->>database: seats
  alt tickets available
    database->>ticket seller: ok
    ticket seller->>customer: confirm
    customer->>ticket seller: ok
    ticket seller->>database: book a seat
    ticket seller->>printer: print ticket
  else sold out
    database->>ticket seller: none left
    ticket seller->>customer: sorry
  end
")
tmp<-capture.output(rsvg_png(charToRaw(export_svg(seq)),'seq.png'))
cat('![Sequence diagram](seq.png){#fig:seq}\n\n')
```

![Sequence diagram](seq.png){#fig:seq}

@Lulliter
Copy link

This may work:

install.packages("webshot")
webshot::install_phantomjs()

Explanation in https://bookdown.org/yihui/bookdown/html-widgets.html:
When knitr detects an HTML widget object in a code chunk, it either renders the widget normally when the current output format is HTML, or saves the widget as an HTML page and calls webshot to capture the screen of the HTML page when the output format is not HTML.

@jorgesinval
Copy link

@Lulliter you just made my day!

@skanskan
Copy link

skanskan commented Aug 28, 2018

@Lulliter but then we don't get a vectorial image of the diagram but just a screenshot, isn't it?

@gtalckmin
Copy link

@ellereve for now, the only solution is to install webshot and phantomjs. I'll work on including documentation to help with this.

Hi, has this been made? The only documentation I found in on the bookdown website.

@etwatson
Copy link

After 8 years, is there a fix for people who knit their projects to PDF?

@jrgant
Copy link

jrgant commented Aug 23, 2023

@etwatson Are you looking for conversion of GraphViz or Mermaid diagrams?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests