Chapter 11 Charts with mschart

Package mschart lets R users to create Microsoft Office charts from data, and then add title, legends, and annotations to the chart object.

The graph produced is a Microsoft graph, which means that it can be edited in your Microsoft software and that the underlying data are available.

The package will not allow you to make the same charts as with ggplot2. It allows only a subset of the charts possible with ‘Office Chart’. The package is often used to industrialize graphs that are then consumed and annotated by non-R users.

11.1 How to create a chart

Names of high level functions are all prefixed with ms_. The following charts are the only available from all possible MS charts:

  • barcharts: ms_barchart()
  • line charts: ms_linechart()
  • scatter plots: ms_scatterchart()
  • area charts: ms_areachart()

They all are producing a chart that can be quickly previewed with command:

print(the_chart, preview = TRUE)

After the creation of the object, it can be customized

  • by using options specific to the chart (with chart_settings()),
  • by changing the options related to the axes (with chart_ax_x() and chart_ax_y()),
  • by changing the options related to the labels (with chart_data_labels()),
  • by changing the colors, line widths, … with functions
    • chart_labels_text()
    • chart_data_fill()
    • chart_data_line_style()
    • chart_data_line_width()
    • chart_data_size()
    • chart_data_smooth()
    • chart_data_stroke()
    • chart_data_symbol()
  • by changing the general theme with function chart_theme(),
  • by changing the title labels with function chart_labels().

11.2 Quick start

11.2.1 Call an high level function

We need to call an high level function (one of those starting with ms_). These functions accept the following arguments:

  • data: the data.frame containing the data to be plotted.
  • x, y, the names of x and y columns.
  • eventually group: a column name that contains the groups that will separate the data into distinct series.
  • eventually labels: a column name that will be used as labels associated with the graphic elements. If more than a value, the first value is used for custom labels, the other columns will be written in the underlying ‘Microsoft Excel’ file so that users can manually choose these labels.
my_barchart <- ms_barchart(data = browser_data, 
  x = "browser", y = "value", group = "serie")

11.2.2 Write charts in Microsoft documents

Let’s have a look at the result by sending it to a new PowerPoint presentation:

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_barchart, location = ph_location_fullsize())
print(doc, target = "static/reports/barchart_01_stacked_powerpoint.pptx")

Note you can quickly preview the chart in a PowerPoint file by calling:

print(my_barchart, preview = "pptx")

Or in a new Word document:

doc <- read_docx()
doc <- body_add_chart(doc, chart = my_barchart, style = "Normal")
print(doc, target = "static/reports/barchart_01_stacked_word.docx")

11.3 Customise charts

Charts are generated with default values. Options are available to change charts properties.

  • Global chart settings can be specified with generic function chart_settings(). Each type of chart has its own set of parameters.

The following code stacks the bars for each group.

my_barchart <- chart_settings( my_barchart, grouping = "stacked", gap_width = 50, overlap = 100 )
  • Axis properties are available with functions chart_ax_x() and chart_ax_y():
my_barchart <- chart_ax_x(my_barchart, cross_between = 'between', 
  major_tick_mark = "in", minor_tick_mark = "none")
my_barchart <- chart_ax_y(my_barchart, num_fmt = "0.00", rotation = -90)
  • Titles (main title, axis labels) can be set with function chart_labels():
my_barchart <- chart_labels(my_barchart, title = "A main title", 
  xlab = "x axis title", ylab = "y axis title")
  • Series visual settings can be customized with functions chart_data_fill(), chart_data_stroke(), chart_data_size(), chart_data_symbol(),
    chart_data_line_width(), chart_data_line_style() and chart_labels_text():
my_barchart <- chart_data_fill(my_barchart,
  values = c(serie1 = "#003C63", serie2 = "#ED1F24", serie3 = "#F2AA00") )
my_barchart <- chart_data_stroke(my_barchart, values = "transparent" )
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_barchart, location = ph_location_fullsize())
print(doc, target = "static/reports/barchart_02_custom_powerpoint.pptx")

  • Global visual settings (e.g. groups fill and stroke colours) can be customised with functions set_theme().

11.4 Chart settings

Chart settings are general options relative to the graphic layout, such as grouping options (stacked, clustered, etc.) or scatter plot style (markers only, lines and markers, etc.).

Chart settings can be changed with function chart_settings(), a generic function, each type of chart has its own method. I encourage you to open the documentation of the function which details the appropriate parameters for each type of graph.

The following examples are illustrating usage of chart_settings with two different chart types:

my_bc_01 <- ms_barchart(
    data = browser_data, x = "browser", y = "value", group = "serie") |> 
  chart_settings( dir = "vertical", grouping = "stacked", overlap = 100 )

my_bc_02 <- ms_barchart(
    data = browser_data, x = "browser", y = "value", group = "serie") |> 
  chart_settings( dir = "vertical", grouping = "clustered", 
                  gap_width = 400, overlap = -100 )

my_sc_01 <- ms_scatterchart(
  data = mtcars, x = "disp", y = "drat") |> 
  chart_settings(scatterstyle = "marker")

my_sc_02 <- ms_scatterchart(
  data = mtcars, x = "disp", y = "drat") |> 
  chart_settings(scatterstyle = "lineMarker")
layout <- "Title and Content"
master <- "Office Theme"
read_pptx() |> 
  add_slide(layout, master) |> 
  ph_with(my_bc_01, location = ph_location_fullsize()) |> 
  add_slide(layout, master) |> 
  ph_with(my_bc_02, location = ph_location_fullsize()) |> 
  add_slide(layout, master) |> 
  ph_with(my_sc_01, location = ph_location_fullsize()) |> 
  add_slide(layout, master) |> 
  ph_with(my_sc_02, location = ph_location_fullsize()) |> 
  print(target = "static/reports/chart_settings_01.pptx")

As bar charts can be complex to configure, helper function barchart_options() is provided.

11.5 Theme

A theme is a set of parameters (i.e. colors, fonts) that can be applied to a chart. As for ggplot objects, a theme is controling the appearance of non-data components of the plot.

Let’s first create a chart:

my_bc <- ms_barchart(
  data = browser_data, x = "browser", y = "value", group = "serie") |> 
  as_bar_stack( ) |> 
  chart_labels(title = "Title example", xlab = "x label", ylab = "y label")

… and add that chart in a PowerPoint file with ‘officer’:

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_bc, location = ph_location_fullsize())
print(doc, target = "static/reports/theme_00.pptx")

mschart is providing an interface to themes with function set_theme(). This function is using an object produced by mschart_theme(). The following are the supported arguments of the function:

  • axis_text
  • axis_text_x
  • axis_text_y
  • axis_ticks
  • axis_ticks_x
  • axis_ticks_y
  • axis_title
  • axis_title_x
  • axis_title_y
  • date_fmt
  • double_fmt
  • grid_major_line
  • grid_major_line_x
  • grid_major_line_y
  • grid_minor_line
  • grid_minor_line_x
  • grid_minor_line_y
  • integer_fmt
  • legend_position
  • legend_text
  • main_title
  • str_fmt
  • table_text
  • title_rot
  • title_x_rot
  • title_y_rot
mytheme <- mschart_theme(
  axis_title = fp_text(color = "#0D6797", font.size = 20, italic = TRUE),
  main_title = fp_text(color = "#0D6797", font.size = 24, bold = TRUE),
  grid_major_line = fp_border(color = "#AA9961", style = "dashed"),
  axis_ticks = fp_border(color = "#AA9961") 
  )
my_bc <- set_theme(my_bc, mytheme)
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_bc, location = ph_location_fullsize())
print(doc, target = "static/reports/theme_01.pptx")

Some elements are inheriting properties from other theme elements. For example, axis_title_x and axis_title_y inherit from axis_title and are all expecting a fp_text; grid_major_line_x and grid_major_line_y inherit from grid_major_line and are all expecting a fp_border.

An helper function is provided to allow modifications of elements of the chart theme:

my_bc <- chart_theme( x = my_bc, 
  axis_title_x = fp_text(color = "red", font.size = 11),
  main_title = fp_text(color = "red", font.size = 15),
  legend_position = "t" )
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_bc, location = ph_location_fullsize())
print(doc, target = "static/reports/theme_02.pptx")

11.6 Bar charts

Bar charts illustrate comparisons among individual items. In a bar chart, the categories are typically organized along the vertical axis, and the values along the horizontal axis.

11.6.1 grouped bars

my_barchart_01 <- ms_barchart(
  data = browser_data, x = "browser",
  y = "value", group = "serie"
)
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_barchart_01, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_bar_01.pptx")

11.6.2 vertical stacked bars

as_bar_stack() is an helper function.

my_barchart_02 <- as_bar_stack(my_barchart_01)

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_barchart_02, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_bar_02.pptx")

11.6.3 horizontal stacked bars

  • Values
my_barchart_03 <- as_bar_stack(my_barchart_01, dir = "horizontal")

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_barchart_03, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_bar_03.pptx")

  • Percent
my_barchart_04 <- as_bar_stack(my_barchart_01, dir = "horizontal", 
  percent = TRUE)

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = my_barchart_04, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_bar_04.pptx")

11.7 Line charts

In a line chart, category data is on x axis, and value data is on the y axis. Line charts can show continuous data over time on an evenly scaled axis.

data <- data.frame(
  supp = factor(rep(c("OJ", "VC"), each = 3), levels = c("OJ", "VC")),
  dose = factor(rep(c("low", "medium", "high"), 2), levels = c("low", "medium", "high")),
  length = c(13.23, 22.7, 26.06, 7.98, 16.77, 26.14), 
  stringsAsFactors = FALSE)

lc_01 <- ms_linechart(data = data, x = "dose", y = "length", group = "supp")

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = lc_01, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_line_01.pptx")

11.7.1 With dates

Auto detection of dates is not yet implemented, sorry. You will need to specify the num_fmt argument.

lc_02 <- ms_linechart(data = browser_ts, x = "date",
                      y = "freq", group = "browser")
lc_02 <- chart_ax_x(lc_02, num_fmt = "m/d/yy")

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = lc_02, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_line_02.pptx")

11.7.2 Smoothed lines

It’s easy to smooth a line (or all lines) by using chart_data_smooth().

linec <- ms_linechart(data = iris, x = "Sepal.Length", y = "Sepal.Width", 
  group = "Species")
linec_smooth <- chart_data_smooth(linec, 
  values = c(virginica = 1, versicolor = 0, setosa = 0) )

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = linec_smooth, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_line_04.pptx")

11.8 Area chats

Area charts can be used to plot change over time and draw attention to the total value across a trend. By showing the sum of the plotted values, an area chart also shows the relationship of parts to a whole.

ac_01 <- ms_areachart(data = data, x = "dose", 
  y = "length", group = "supp")

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = ac_01, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_area_01.pptx")

If using an x axis with date values, you will have to set a format with parameter num_fmt (with “m/d/yy” for example) in a call to chart_ax_x.

ac_02 <- ms_areachart(data = browser_ts, x = "date",
  y = "freq", group = "browser")
ac_02 <- chart_settings(ac_02, grouping = "percentStacked")
ac_02 <- chart_ax_x(ac_02, cross_between = "midCat", num_fmt = "m/d/yy")

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = ac_02, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_area_02.pptx")

11.9 Scatter plots

A scatter chart has two value axes: a horizontal (x) and a vertical (y) value axis. It combines x and y values into single data points and shows them in irregular intervals, or clusters. Scatter charts are typically used for showing and comparing numeric values.

sc_01 <- ms_scatterchart(data = mtcars, x = "disp", y = "drat", group = "gear")
sc_01 <- chart_settings(sc_01, scatterstyle = "marker")

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = sc_01, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_scatter_01.pptx")

Scatter plots can be customized. For example, it is possible to join the dots of only one category:

dat <- expand.grid(type = c("N", "S", "V", "X", "Y"),
            y = 1:20)
dat$value = rnorm(n = nrow(dat), mean = 50, sd = 4)

sc_02 <- ms_scatterchart(data = dat, x = "value", y = "y", group = "type")
sc_02 <- chart_settings(sc_02, style = "lineMarker")
sc_02 <- chart_data_line_style(sc_02,
  values = c("X" = "solid", "Y" = "none", "V" = "none", "N" = "none", "S" = "none") )

doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = sc_02, location = ph_location_fullsize())
print(doc, target = "static/reports/gallery_scatter_02.pptx")

11.10 Custom labels

You can use custom data labels in a chart by specifying a data label column.

The data.frame below contains a column named label. It is made of some text and unicodes for emoji (thanks to package emojifont). See this table for a complete list: https://apps.timwhitlock.info/emoji/tables/unicode

dat_no_group <- data.frame(
  stringsAsFactors = FALSE,
  cut = c("Fair", "Good", "Very Good", "Premium", "Ideal"),
  carat = c(1, 0.82, 0.71, 0.86, 0.54),
  n = c(1610L, 4906L, 12082L, 13791L, 21551L),
  label = c("\U0001f603", "\U0001f525", "", "Hello \U0001f47d", "\U0001f44e"),
  group = c("OK", "KO", "KO", "KO", "KO")
)
dat_no_group

cut

carat

n

label

group

character

numeric

integer

character

character

Fair

1.0

1'610

😃

OK

Good

0.8

4'906

🔥

KO

Very Good

0.7

12'082

KO

Premium

0.9

13'791

Hello 👽

KO

Ideal

0.5

21'551

👎

KO

n: 5

We can use that column as label column when calling ms_barchart and other high level functions :

chrt <- ms_barchart(
  data = dat_no_group, group = "group",
  x = "cut", labels = "label", y = "n"
)
chrt <- chart_settings(chrt,
  vary_colors = TRUE,
  grouping = "standard",
  overlap = 90, gap_width = 150
)
chrt <- chart_data_labels(chrt, position = "outEnd")

chrt <- chart_data_fill(chrt, values = c(KO = "#0088CC", OK = "red"))
chrt <- chart_data_stroke(chrt, "transparent")

chrt <- chart_labels_text(chrt, fp_text(font.size = 20))
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = chrt, location = ph_location_fullsize())
print(doc, target = "static/reports/chrt_with_label_01.pptx")

This feature should be used sparingly. For example, adding a label on each point of a scatter plot can result in an overloaded and unreadable graph.

As demonstrated in the previous example, when you need to change the font, color, size of labels, you can use function chart_labels_text() that accept an object returned by function officer::fp_text().