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:
- Compute the grob
- Get its dimensions
- Use
svglite::svglite()
orragg::agg_png()
with the know dimensions as width and height for the graphic to be created. - call
plot()
method with the grob object - Close the graphical device and finalize the graphic file.
# $width
# [1] 3.353297
#
# $height
# [1] 1.971171
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")