Search code examples
rgridr-markdownflowchartgmisc

How to save a flowchart made with grid and Gmisc


What I want to do is to create a basic flowchart with R, add it to my R Markdown file and make it referencable (if possible like I did with my ggplot2 figures -> fig.cap = " " in the code chunk header).

The Flowchart:

library(grid)
library(Gmisc)

grid.newpage()

# set some parameters to use repeatedly
leftx <- .25
midx <- .5
rightx <- .75
width <- .4
gp <- gpar(fill = "lightgrey")

# create boxes
(Pharmazie <- boxGrob("Verbrauchsdaten von der\n Spitalpharmazie (Excel-Tabelle)", 
                  x=leftx, y=0.876, box_gp = gp, width = width))

(Finanzen <- boxGrob("Belegzahlen vom Ressort\n Finanzen (Excel-Tabelle)", 
                 x=rightx, y=.876, box_gp = gp, width = width))

(A <- boxGrob("Import der Daten aus Excel ins\n Microsoft Access (Datenbanksoftware)", 
          x=midx, y=0.76, box_gp = gp, width = width))

(B <- boxGrob("Zusammenführen der Informationen\n und erstellen neuer, berechneter Tabellen", 
          x=midx, y=.64, box_gp = gp, width = width))

(C <- boxGrob("Export der neu erstellten Tabellen\n in Form von Excel-Tabellen", 
          x=midx, y=.52, box_gp = gp, width = width))

(D <- boxGrob("Import der neuen Tabellen in R", 
          x=midx, y=.414, box_gp = gp, width = width))

(E <- boxGrob("Berechnung und grafische Darstellung\n der Grafiken und Tabellen", 
          x=midx, y=.308, box_gp = gp, width = width))


connectGrob(Pharmazie, A, "L")
connectGrob(Finanzen, A, "L")
connectGrob(A, B, "N")
connectGrob(B, C, "N")
connectGrob(C, D, "N")
connectGrob(D, E, "N")

The problem that I'm having is that I cannot find a way to save the flowchart to a variable / png file (to import it into my R Markdown file later) or, even better, to include it directly within a code chunk (it looks different when I execute the code within a code chunk vs. when executing it in a script, also when trying to give it a fig.cap it fails to knit).

Example of how differently it looks: enter image description here.

Any help would be greatly appreciated!

P.S. I tried to make the flowchart with the package "DiagrammeR", but I gave up after I did not manage to find a way to have the text on more than one line per box (so it wouldn't be so broad).


Solution

  • It looks different, because the viewport you are drawing on is not the same. You just need to fiddle a bit with the positioning options to make it fit. Below I used fig.width and fig.height and created a wrapper function in which I also vertically justified the boxes (top end). This makes it easier to build the chart top to bottom using the y coordinate.

    ---
    output: pdf_document
    ---
    
    
    ```{r echo = F, message = F, fig.width=7, fig.height = 6}
    library(grid)
    library(Gmisc)
    
    # grid.newpage()
    # set some parameters to use repeatedly
    leftx <- .2
    midx <- .5
    rightx <- .8
    
    myBoxGrob <- function(text, ...) {
      boxGrob(label = text, bjust = "top", box_gp = gpar(fill = "lightgrey"), ...)
    }
    
    # create boxes
    (Pharmazie <- myBoxGrob("Verbrauchsdaten von der\n Spitalpharmazie (Excel-Tabelle)", x=leftx, y=1, width = 0.38))
    (Finanzen <- myBoxGrob("Belegzahlen vom Ressort\n Finanzen (Excel-Tabelle)", x=rightx, y=1, width = 0.38))
    (A <- myBoxGrob("Import der Daten aus Excel ins\n Microsoft Access (Datenbanksoftware)", x=midx, y=0.87, width = 0.5))
    (B <- myBoxGrob("Zusammenführen der Informationen\n und erstellen neuer, berechneter Tabellen", x=midx, y=.70, width = 0.5))
    (C <- myBoxGrob("Export der neu erstellten Tabellen\n in Form von Excel-Tabellen", x=midx, y=.53, width = 0.5))
    (D <- myBoxGrob("Import der neuen Tabellen in R", x=midx, y=.36,  width = 0.5))
    (E <- myBoxGrob("Berechnung und grafische Darstellung\n der Grafiken und Tabellen", x=midx, y=.21, width = 0.5))
    
    
    connectGrob(Pharmazie, A, "L")
    connectGrob(Finanzen, A, "L")
    connectGrob(A, B, "N")
    connectGrob(B, C, "N")
    connectGrob(C, D, "N")
    connectGrob(D, E, "N")
    ```
    

    enter image description here

    If the flowchart is acceptable, you can scale the plot using the chunk option out.width (here =".5\\textwidth"):

    enter image description here