-
Notifications
You must be signed in to change notification settings - Fork 3
/
themes.qmd
739 lines (594 loc) · 27.2 KB
/
themes.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
# Custom Data Visualization Themes {#sec-themes-chapter}
```{r}
i <- 1
chapter_number <- 3
source("_common.R")
```
A *custom theme* is nothing more than a chunk of code that applies a set of small tweaks to all plots. So much of the work involved in making a professional chart consists of these kinds of adjustments. What font should you use? Where should the legend go? Should axes have titles? Should charts have grid lines? These questions may seem minor, but they have a major impact on the final product.
In 2018, BBC data journalists Nassos Stylianou and Clara Guibourg, along with their team, developed a custom ggplot theme that matches the BBC’s style. By introducing this bbplot package for others to use, they changed their organization’s culture, removed bottlenecks, and allowed the BBC to visualize data more creatively.
Rather than forcing everyone to copy the long code to tweak each plot they make, custom themes enable everyone who uses them to follow style guidelines and ensure that all data visualizations meet a brand’s standards. For example, to understand the significance of the custom theme introduced at the BBC, it’s helpful to know how things worked before bbplot.
In the mid-2010s, journalists who wanted to make data visualization had two choices:
- Use an internal tool that could create data visualizations but was limited to the predefined charts it had been designed to generate.
- Use Excel to create mockups and then work with a graphic designer to finalize the charts. This approach led to better results and was much more flexible, but it required extensive, time-consuming back-and-forth with a designer.
Neither of these choices was ideal, and the BBC’s data visualization output was limited. R freed the journalists from having to work with a designer. It wasn’t that the designers were bad (they weren’t), but ggplot allowed the journalists to explore different visualizations on their own. As the team improved their ggplot skills, they realized that it might be possible to produce more than just exploratory data visualizations and to create production-ready charts in R that could go straight onto the BBC website.
This chapter discusses the power of custom ggplot themes, then walks through the code in the bbplot package to demonstrate how custom themes work. You’ll learn how to consolidate your styling code into a reusable function and how to consistently modify your plots’ text, axes, grid lines, background, and other elements.
## Styling a Plot with a Custom Theme
The bbplot package has two functions: `bbc_style()` and `finalise_plot()`. The latter deals with tasks like adding the BBC logo and saving plots in the correct dimensions. For now, let’s look at the `bbc_style()` function, which applies a custom ggplot theme to make all the plots look consistent and follow BBC style guidelines.
### An Example Plot
To see how this function works, you’ll create a plot showing population data about several penguin species. You’ll be using the `palmerpenguins` package, which contains data about penguins living on three islands in Antarctica. For a sense of what this data looks like, load the `palmerpenguins` and `tidyverse` packages:
```{r}
#| echo: true
library(palmerpenguins)
library(tidyverse)
```
Now you have data you can work with in an object called `penguins`. Here’s what the first 10 rows look like:
```{r}
penguins
```
To get the data in a more usable format, you’ll count how many penguins live on each island with the `count()` function from the `dplyr` package (one of several packages that are loaded with the `tidyverse`):
```{r}
#| echo: true
#| eval: false
penguins %>%
count(island)
```
This gives you some simple data that you can use for plotting:
```{r}
penguins %>%
count(island)
```
You’ll use this data multiple times in the chapter, so save it as an object called `penguins_summary` like so:
```{r}
#| echo: true
penguins_summary <- penguins %>%
count(island)
```
Now you’re ready to create a plot. Before you see what `bbplot` does, make a plot with the ggplot defaults:
```{r}
#| label: fig-basic-penguins-plot
#| echo: true
penguins_plot <- ggplot(
data = penguins_summary,
aes(
x = island,
y = n,
fill = island
)
) +
geom_col() +
labs(
title = "Number of Penguins",
subtitle = "Islands are in Antarctica",
caption = "Data from palmerpenguins package"
)
```
This code tells R to use the `penguins_summary` data frame, putting the island on the x-axis and the count of the number of penguins (`n`) on the y-axis, and making each bar a different color with the `fill` aesthetic property. Since you’ll modify this plot multiple times, saving it as an object called `penguins_plot` simplifies the process. @fig-basic-penguins-plot-plot shows the resulting plot.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-basic-penguins-plot-plot
#| fig-cap: "A chart with the default theme"
penguins_plot
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
This isn’t the most aesthetically pleasing chart. The gray background is ugly, the y-axis title is hard to read because it’s angled, and the text size overall is quite small. But don’t worry, you’ll be improving it soon.
### The BBC’s Custom Theme
Now that you have a basic plot to work with, you’ll start making it look like a BBC chart. To do this, you need to install the `bbplot` package. First, install the `remotes` package using `install.packages("remotes")` so that you can access packages from remote sources. Then, run the following code to install bbplot from the GitHub repository at <https://github.com/bbc/bbplot>:
```{r}
#| echo: true
#| eval: false
library(remotes)
install_github("bbc/bbplot")
```
Once you’ve installed the bbplot package, load it and apply the `bbc_style()` function to the penguins_plot as follows:
```{r penguins-bbc-style}
#| echo: true
#| eval: false
library(bbplot)
penguins_plot +
bbc_style()
```
@fig-penguins-bbc-style-plot shows the result.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-bbc-style-plot
#| ref-label: penguins-bbc-style
#| fig-cap: "The same chart with BBC style"
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
Vastly different, right? The font size is larger, the legend is on top, there are no axis titles, the grid lines are stripped down, and the background is white. Let’s look at these changes one by one.
## The BBC Theme Components
You’ve just seen the difference that the bbc_style() function makes to a basic chart. This section walks you through the function’s code, with some minor tweaks for readability. Functions are discussed further in @sec-packages-chapter.
### Function Definition
The first line gives the function a name and indicates that what follows is, in fact, a function definition:
```{r}
#| echo: true
#| eval: false
bbc_style <- function() {
font <- "Helvetica"
ggplot2::theme(
```
```{r}
font <- "Helvetica"
```
The code then defines a variable called font and assigns it the value `Helvetica`. This allows later sections to simply use font rather than repeating `Helvetica` multiple times. If the BBC team ever wanted to use a different font, they could change `Helvetica` here to, say, `Comic Sans` and it would update the font for all of the BBC plots (though I suspect higher-ups at the BBC might not be on board with that choice).
Historically, working with custom fonts in R was notoriously tricky, but recent changes have made the process much simpler. To ensure that custom fonts such as Helvetica work in ggplot, first install the `systemfonts` and `ragg` packages by running this code in the console:
```{r}
#| echo: true
#| eval: false
install.packages(c("systemfonts", "ragg"))
```
The `systemfonts` package allows R to directly access fonts you’ve installed on your computer, and `ragg` allows ggplot to use those fonts when generating plots.
Next, select **Tools > Global Options** from RStudio’s main menu bar. Click the **Graphics** menu at the top of the interface and, under the Backend option, select **AGG**. This change should ensure that RStudio renders the previews of any plots with the `ragg` package. With these changes in place, you should be able to use any fonts you’d like (assuming you have them installed) in the same way that the b`bc_style()` function uses Helvetica.
After specifying the font to use, the code calls ggplot’s `theme()` function. Rather than first loading ggplot with `library(ggplot2)` and then calling its `theme()` function, the `ggplot2::theme(`) syntax indicates in one step that the `theme()` function comes from the ggplot2 package. You’ll write code in this way when making an R package in @sec-packages-chapter.
Nearly all of the code in `bbc_style()` exists within this `theme()` function. Remember from @sec-data-viz-chapter that `theme()` makes additional tweaks to an existing theme; it isn’t a complete theme like `theme_light()`, which will change the whole look and feel of your plot. In other words, by jumping straight into the `theme()` function, `bbc_style()` makes adjustments to the ggplot defaults. As you’ll see, the `bbc_style()` function does a lot of tweaking.
### Text
The first code section within the `theme()` function formats the text:
```{r}
#| eval: false
#| echo: true
plot.title = ggplot2::element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = ggplot2::element_text(
family = font,
size = 22,
margin = ggplot2::margin(9, 0, 9, 0)
),
plot.caption = ggplot2::element_blank(),
```
To make changes to the title, subtitle, and caption, it follows this pattern:
```{r}
#| eval: false
#| echo: true
AREA_OF_CHART = ELEMENT_TYPE(
PROPERTY = VALUE
)
```
For each area, this code specifies the element type: `element_text()`, `element_line()`, `element_rect()`, or `element_blank()`. Within the element type is where you assign values to properties—for example, setting the font family (the property) to Helvetica (the value). The `bbc_style()` function uses the various `element_` functions to make tweaks, as you’ll see later in this chapter.
::: {.callout-tip}
For additional ways to customize pieces of your plots, see the ggplot2 package documentation (<https://ggplot2.tidyverse.org/reference/element.html>), which provides a comprehensive list.
:::
One of the main adjustments the `bbc_style()` function makes is bumping up the font size to help with legibility, especially when plots made with the bbplot package are viewed on smaller mobile devices. The code first formats the title (with `plot.title`) using Helvetica 28-point bold font in a nearly black color (the hex code #222222). The subtitle (`plot.subtitle`) is 22-point Helvetica.
The `bbc_style()` code also adds some spacing between the title and subtitle with the `margin()` function, specifying the value in points for the top (9), right (0), bottom (9), and left (0) sides. Finally, the `element_blank()` function removes the default caption (set through the `caption` argument in the labs() function), “Data from palmer penguins package.” (As mentioned earlier, the `finalise_plot()` function in the `bbplot` package adds elements, including an updated caption and the BBC logo, to the bottom of the plots.)
@fig-penguins-plot-text-formatting-plot shows these changes.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-plot-text-formatting-plot
#| fig-cap: "The penguin chart with only the text formatting changed"
penguins_plot +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank()
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
With these changes in place, you’re on your way to the BBC look.
### Legend
Next up is formatting the legend, positioning it above the plot and leftaligning its text:
```{r penguins-plot-legend}
#| echo: true
#| eval: false
legend.position = "top",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
),
```
This code removes the legend background (which would show up only if the background color of the entire plot weren’t white), the title, and the legend key (the borders on the boxes that show the island names, just barely visible in @fig-penguins-plot-text-formatting-plot). Finally, the code sets the legend’s text to 18-point Helvetica with the same nearly black color. @fig-penguins-plot-legend-plot shows the result.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-plot-legend-plot
#| fig-cap: "The penguin chart with changes to the legend"
penguins_plot +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank(),
legend.position = "top",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
)
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
The legend is looking better, but now it’s time to format the rest of the chart so it matches.
### Axes
The code first removes the axis titles because they tend to take up a lot of chart real estate, and you can use the title and subtitle to clarify what the axes show:
```{r}
#| echo: true
#| eval: false
axis.title = ggplot2::element_blank(),
axis.text = ggplot2::element_text(
family = font,
size = 18,
color = "#222222"
),
axis.text.x = ggplot2::element_text(margin = ggplot2::margin(5, b = 10)),
axis.ticks = ggplot2::element_blank(),
axis.line = ggplot2::element_blank(),
```
All text on the axes becomes 18-point Helvetica and nearly black. The text on the x-axis (Biscoe, Dream, and Torgersen) gets a bit of spacing around it. Finally, both axes’ ticks and lines are removed. @fig-penguins-plot-axes-plot shows these changes, although the removal of the axis lines doesn’t make a difference to the display here.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-plot-axes-plot
#| fig-cap: "The penguin chart with axis formatting changes"
penguins_plot +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank(),
legend.position = "top",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.title = ggplot2::element_blank(),
axis.text = ggplot2::element_text(
family = font,
size = 18,
color = "#222222"
),
axis.text.x = ggplot2::element_text(margin = ggplot2::margin(5, b = 10)),
axis.ticks = ggplot2::element_blank(),
axis.line = ggplot2::element_blank()
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
The axis text matches the legend text, and the axis tick marks and lines are gone.
### Grid Lines
Now for the grid lines:
```{r}
#| echo: true
#| eval: false
panel.grid.minor = ggplot2::element_blank(),
panel.grid.major.y = ggplot2::element_line(color = "#cbcbcb"),
panel.grid.major.x = ggplot2::element_blank(),
```
The approach here is fairly straightforward: this code removes minor grid lines for both axes, removes major grid lines on the x-axis, and keeps major grid lines on the y-axis but makes them a light gray (the #cbcbcb hex code). @fig-penguins-plot-gridlines-plot shows the result.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-plot-gridlines-plot
#| fig-cap: "Our chart with tweaks to the grid lines"
penguins_plot +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank(),
legend.position = "top",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.title = ggplot2::element_blank(),
axis.text = ggplot2::element_text(
family = font,
size = 18,
color = "#222222"
),
axis.text.x = ggplot2::element_text(margin = ggplot2::margin(5, b = 10)),
axis.ticks = ggplot2::element_blank(),
axis.line = ggplot2::element_blank(),
panel.grid.minor = ggplot2::element_blank(),
panel.grid.major.y = ggplot2::element_line(color = "#cbcbcb"),
panel.grid.major.x = ggplot2::element_blank()
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
### Background
The previous iteration of our plot still had a gray background. The `bbc_style()` function removes this with the following code.
```{r}
#| echo: true
#| eval: false
panel.background = ggplot2::element_blank(),
```
The plot without the gray background is seen in Figure \@ref(fig:penguins-plot-no-bg).
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-plot-no-bg
#| fig-cap: "The chart with the gray background removed"
penguins_plot +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank(),
legend.position = "top",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.title = ggplot2::element_blank(),
axis.text = ggplot2::element_text(
family = font,
size = 18,
color = "#222222"
),
axis.text.x = ggplot2::element_text(margin = ggplot2::margin(5, b = 10)),
axis.ticks = ggplot2::element_blank(),
axis.line = ggplot2::element_blank(),
panel.grid.minor = ggplot2::element_blank(),
panel.grid.major.y = ggplot2::element_line(color = "#cbcbcb"),
panel.grid.major.x = ggplot2::element_blank(),
panel.background = ggplot2::element_blank()
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
You’ve nearly re-created the penguin plot using the bbc_style() function.
### Small Multiples
The `bbc_style()` function contains a bit more code to modify `strip.background` and `strip.text`. In ggplot, the *strip* refers to the text above faceted charts like the ones discussed in @sec-data-viz-chapter. Next, you’ll turn your penguin chart into
a faceted chart to see these components of the BBC’s theme. I’ve used the code from the `bbc_style()` function, minus the sections that deal with small multiples, to make @fig-penguin-facetted-plot.
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguin-facetted-plot
#| fig-cap: "The faceted chart with no changes to the strip text formatting"
penguins %>%
group_by(island, sex) %>%
summarize(avg_weight = mean(body_mass_g, na.rm = TRUE)) %>%
drop_na(sex) %>%
mutate(sex = fct_recode(sex,
"F" = "female",
"M" = "male")) %>%
ggplot(aes(
x = sex,
y = avg_weight,
fill = island
)) +
geom_col() +
labs(title = "Penguin Weight",
subtitle = "By Island and Sex") +
facet_wrap(~island) +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank(),
legend.position = "none",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.title = element_blank(),
axis.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.text.x = element_text(margin = margin(5, b = 10)),
axis.ticks = element_blank(),
axis.line = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.y = element_line(color = "#cbcbcb"),
panel.grid.major.x = element_blank(),
panel.background = element_blank()
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
Using the `facet_wrap()` function to make a small multiples chart leaves you with one chart per island, but by default, the text above each small multiple is noticeably smaller than the rest of the chart. What’s more, the gray background behind the text stands out because you’ve already removed the gray background from the other parts of the chart. The consistency you’ve worked toward is now compromised, with small text that is out of proportion to the other chart text and a gray background that sticks out like a sore thumb.
The following code changes the strip text above each small multiple:
```{r}
#| eval: false
#| echo: true
strip.background = ggplot2::element_rect(fill = "white"),
strip.text = ggplot2::element_text(size = 22, hjust = 0)
```
This code removes the background (or, more accurately, colors it white). Then it makes the text larger, bold, and left-aligned using hjust = 0. Note that I did have to make the text size slightly smaller than in the actual chart to fit the book, and I added code to make it bold. @fig-penguins-plot-facetted-bbc shows the result.
```{r}
penguins_plot_weight <- penguins %>%
group_by(island, sex) %>%
summarize(avg_weight = mean(body_mass_g, na.rm = TRUE)) %>%
drop_na(sex) %>%
mutate(sex = fct_recode(sex,
"F" = "female",
"M" = "male")) %>%
ggplot(aes(
x = sex,
y = avg_weight,
fill = island
)) +
geom_col() +
labs(title = "Penguin Weight",
subtitle = "By Island and Sex") +
facet_wrap(~island) +
theme(
plot.title = element_text(
family = font,
size = 28,
face = "bold",
color = "#222222"
),
plot.subtitle = element_text(
family = font,
size = 22,
margin = margin(9, 0, 9, 0)
),
plot.caption = element_blank(),
legend.position = "none",
legend.text.align = 0,
legend.background = element_blank(),
legend.title = element_blank(),
legend.key = element_blank(),
legend.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.title = element_blank(),
axis.text = element_text(
family = font,
size = 18,
color = "#222222"
),
axis.text.x = element_text(margin = margin(5, b = 10)),
axis.ticks = element_blank(),
axis.line = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.y = element_line(color = "#cbcbcb"),
panel.grid.major.x = element_blank(),
panel.background = element_blank()
)
```
```{r}
#| results: asis
print_nostarch_file_name()
```
```{r}
#| label: fig-penguins-plot-facetted-bbc
#| fig-cap: "The small multiples chart in the BBC style"
penguins_plot_weight +
theme(
strip.background = element_rect(fill = "white"),
strip.text = element_text(size = 17, hjust = 0, face = "bold")
)
```
```{r}
#| results: asis
save_figure_for_nostarch(figure_height = 5)
```
If you look at any chart on the BBC website, you’ll see how similar it looks to your own. The tweaks in the `bbc_style()` function to the text formatting, legends, axes, grid lines, and backgrounds show up in charts viewed by millions of people worldwide.
## Color
You might be thinking, *Wait, what about the color of the bars? Doesn’t the theme change those?* This is a common point of confusion, but the answer is that it doesn’t. The documentation for the `theme()` function explains why this is the case: “Themes are a powerful way to customize the non-data components of your plots: i.e. titles, labels, fonts, background, gridlines, and legends.” In other words, ggplot themes change the elements of the chart that aren’t mapped to data.
Plots, on the other hand, use color to communicate information about data. In the faceted chart, for instance, the `fill` property is mapped to the island (Biscoe is salmon, Dream is green, and Torgersen is blue). As you saw in @sec-data-viz-chapter, you can change the fill using the various `scale_fill_` functions. In the world of ggplot, these `scale_` functions control color, while the custom themes control the chart’s overall look and feel.
## Summary
When Stylianou and Guibourg started developing a custom theme for the BBC, they had one question: Would they be able to create graphs in R that could go directly onto the BBC website? Using ggplot, they succeeded. The `bbplot` package allowed them to make plots with a consistent look and feel that followed BBC standards and, most important, did not require a designer’s help.
You can see many of the principles of high-quality data visualization discussed in @sec-data-viz-chapter in this custom theme. In particular, the removal of extraneous elements (axis titles and grid lines, for instance) helps keep the focus on the data itself. And because applying the theme requires users to add only a single line to their ggplot code, it was easy to get others on board. They had only to append `bbc_style()` to their code to produce a BBC-style plot.
Over time, others at the BBC noticed the data journalism team’s production-ready graphs and wanted to make their own. The team members set up R trainings for their colleagues and developed a “cookbook” (<https://bbc.github.io/rcookbook/>) showing how to make various types of charts. Soon, the quality and quantity of BBC’s data visualization exploded. Stylianou told me, “I don’t think there’s been a day where someone at the BBC hasn’t used the package to produce a graphic.”
Now that you’ve seen how custom ggplot themes work, try making one of your own. After all, once you’ve written the code, you can apply it with only one line of code.
## Additional Resources
Consult the following resources to learn more about how the BBC created and used their custom theme:
- BBC Visual and Data Journalism cookbook for R graphics (2019), <https://bbc.github.io/rcookbook/>
- "How the BBC Visual and Data Journalism team works with graphics in R" by the BBC Visual and Data Journalism team (2019), <https://medium.com/bbc-visual-and-data-journalism/how-the-bbc-visual-and-data-journalism-team-works-with-graphics-in-r-ed0b35693535>