Chapter 13 Plotting flextable

A flextable can be transformed into a ‘Grid Graphical Object’ created with the ‘grid’ package. To get a flextable as a grob, use flextable::gen_grob().

It can be arranged with ggplot by using package ‘patchwork’ and printed as is in a png or svg file.

To illustrate this, we will define a flextable from ‘mtcars’ dataset.

library(dplyr)

dat <- mutate(mtcars, cyl = factor(cyl))

ft <- group_by(dat, cyl) %>% 
  summarise(
    across(
      all_of(c("disp", "mpg")),
      list(
        mean = ~ mean(.x, na.rm = TRUE),
        sd = ~ sd(.x, na.rm = TRUE)
      )
    )
  ) %>% 
  flextable() %>% 
  separate_header() %>% 
  theme_vanilla() %>% 
  align(align = "center", part = "all") %>% 
  colformat_double(digits = 2) %>% 
  labelizor(labels = c(cyl = "Number of cylinders",
                       disp = "Displacement",
                       mpg = "Miles/(US) gallon",
                       mean = "µ", sd = "σ"
                       ), part = "all") %>% 
  autofit() %>% width(j = 1, width = .8) %>% 
  add_header_lines("used dataset: mtcars")
ft

used dataset: mtcars

Number of cylinders

Displacement

Miles/(US) gallon

µ

σ

µ

σ

4

105.14

26.87

26.66

4.51

6

183.31

41.56

19.74

1.45

8

353.10

67.77

15.10

2.56

gen_grob() returns a grob made of several grid elements that define the table.

The plot below shows the grobs organization in the main grob representing the flextable.

13.1 plot method

A plot() method is available and do a direct call to flextable::gen_grob(). It is a convenient function we use for testing.

When you need to print a flextable with its exact dimensions, you will have to use option fit="fixed".

plot(ft, fit = "fixed", just = "center")

13.1.1 Save as PNG or SVG

One can easily save tables as images with the R functions that support ‘systemfonts’ : svglite::svglite(), ragg::agg_png() or ggiraph::dsvg(). These devices must be used to ensure all fonts you are using will be recognized by the R graphical device.

Because R graphics have fixed dimensions, you will need to know what is the width and height of a flextable grob to set correctly ‘knitr’ chunk options fig.width and fig.height. The function dim() applied to the result of gen_grob() returns optimal width and height in a named list.

To save a flextable as an svg file or png file, the following method should be used:

  1. Compute the grob
  2. Get its dimensions
  3. Use svglite::svglite() or ragg::agg_png() with the know dimensions as width and height for the graphic to be created.
  4. call plot() method with the grob object
  5. Close the graphical device and finalize the graphic file.
gr <- gen_grob(ft, fit = "fixed", just = "center")
dims <- dim(gr)
dims
# $width
# [1] 3.353297
# 
# $height
# [1] 1.971171
svglite::svglite(filename = "hello-grid-graphics.svg", width = dims$width + .1, height = dims$height + .1)
plot(gr)
dev.off()

13.2 Grob options

Function gen_grob() has options to specify how the flextable should be transformed as a grob.

The most important is argument fit, it defines how the grob should be fitting in the region where the table will be rendered (its parent viewport). There are three options:

  • ‘auto’ makes the grob resized to fit in the parent viewport, the table row heights and column widths are resized proportionally.
  • ‘width’ makes the grob resized to fit the width of the parent viewport, column widths are resized proportionally, row heights are unaffected, the table height may be smaller or larger than the height of the parent viewport.
  • “fixed” makes the grob with fixed dimensions, the exact dimensions, as determined by the column widths and the row heights of the flextable.

Argument scaling defines how the content size (text, borders and images) should scale. There are three options:

  • “min”: when the parent viewport is smaller than the necessary, the various content sizes (text font size, line width and image dimensions) decrease accordingly so that the content can still fit; when the parent viewport is larger than the necessary, the content sizes remain the same.
  • “full” : same as “min”, except that the content sizes are scaled fully, they will increase or decrease, according to the size of the drawing surface.
  • “fixed”: same as “min”, except that the content sizes are scaled fully, they increase or decrease, according to the size of the drawing surface.

Argument just specify how the layout should be justified if it is not the same size as its parent viewport. Possible string values are: “left”, “right”, “centre”, “center”, “bottom”, and “top”. See ?grid::grid.layout.

  • fit="width", scaling="full"
  • fit="auto", scaling="full"

13.3 Option fit

To illustrate this option, we will define few ggplot graphics and we will use patchwork to arrange them together with a flextable.

library(patchwork)
library(ggplot2)

cyls <- c("4" = "red", "6" = "orange", "8" = "maroon")

gg1 <- ggplot(dat) +
  geom_point( aes(disp, mpg, color = cyl)) +
  scale_color_manual(values = cyls)

gg2 <- ggplot(dat) +
  geom_point(aes(disp, hp, color = cyl)) +
  scale_color_manual(values = cyls)

gg3 <- ggplot(dat) +
  geom_point( aes(hp, mpg, color = cyl))  +
  scale_color_manual(values = cyls)

The table original size is not wider or higher than the available space. It fits perfectly under the 3 graphics.

(gg1 + gg2 + gg3) /
  gen_grob(ft, fit = "fixed", just = "centre") +
  plot_layout(guides = "collect") & 
  theme(legend.position = "top")

It does not fit with all layouts:

(gg1 + gg2 + gen_grob(ft, fit = "fixed", just = "centre")) +
  plot_layout(guides = "collect") & 
  theme(legend.position = "top")

To fit the table into its graphics space, the fit argument must be set to auto. Unfortunately, the aspect ratio of the table is very different from its container and makes it difficult to read.

(gg1 + gg2 + gen_grob(ft, fit = "auto", just = "centre")) +
  plot_layout(guides = "collect") & 
  theme(legend.position = "top")

Argument fit should then be set to “width” so that row heights are not too high. The table is resized according to its aspect ratio and not the aspect ratio of its container.

(gg1 + gg2 + gen_grob(ft, fit = "width", just = "centre")) +
  plot_layout(guides = "collect") & 
  theme(legend.position = "top")

13.4 Option scaling

Using scaling = "full" is creating table where font sizes and line sizes will be increased to a maximum that enable a correct display of all the content.

plot(ft, scaling = "full", just = "centre")

Using scaling = "min" is creating table where font sizes and line sizes are set so that they are the minimums sizes that enable a correct display of all the content.

plot(ft, scaling = "min", just = "centre")