---
title: "gghdx"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{gghdx}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.showtext = TRUE,
warning = FALSE,
dpi = 300,
fig.retina = 1,
fig.align = "center"
)
```
## Using the package
The package is designed so the user just has to run `gghdx()` once a session
and mainly forget about it. This will automatically set your ggplot2
to use the HDX theme, palettes, fonts, and more by default. If you want more
control or want to better understand how the package works, please see the
details below!
### Theme
A quick and simple example would be plotting the `iris` dataset included in
base R.
```{r intro-plot, out.width = "90%", out.height = "10%", fig.height = 4, fig.width = 6}
library(ggplot2)
p <- ggplot(
iris,
aes(
x = Sepal.Length,
y = Petal.Length,
color = Species
)
) +
geom_point() +
labs(
title = "Iris species distributed by sepal and petal lengths",
y = "Petal length",
x = "Sepal length"
)
p
```
This output using the base ggplot style doesn't look particularly bad, but we
can use `theme_hdx()` to quickly adjust some of the styling to fit the style
guide.
```{r intro-hdx, out.width = "90%", out.height = "10%", fig.height = 4, fig.width = 6}
library(gghdx)
p + theme_hdx(base_family = "sans", title_family = "sans")
```
Now, axis lines have been cleaned up and the
plot better resembles recommendations from the visual guide with just that
single line of code.
### Color palettes
However, the color palette for the points is still using the base R palette. We
can use one of the many `scale_...hdx()` functions to use HDX colors. Let's just
use the primary discrete color scale that will align each species with one of
the 3 non-neutral colorramps from the 2025 HDX redesign (primary blue, brand
teal, and error red).
```{r intro-ramp, out.width = "90%", out.height = "10%", fig.height = 4, fig.width = 6}
p +
theme_hdx(base_family = "sans", title_family = "sans") +
scale_color_hdx_discrete()
```
You can check the documentation of any of the `scale_...hdx()` functions to see
all available scales, or directly access the colors using `hdx_colors()` or
the raw list in `hdx_color_list`. The available palettes can be easily
visualized using `hdx_display_pal()`. The original sapphire, mint, and tomato
colorramps are still available (e.g. `scale_color_hdx_sapphire()`) for
backwards compatibility.
### Adding fonts
We also would like to use the HDX font families. As of the 2025 redesign, HDX
uses Merriweather for titles and other display text, and Roboto for body
text. Since both are free Google fonts, they're relatively easy to access in
R. gghdx uses the
[sysfonts](https://CRAN.R-project.org/package=sysfonts) package
to load the Google fonts and then [showtext](https://CRAN.R-project.org/package=showtext)
to include them in our plot. You can also use the
[extrafont](https://CRAN.R-project.org/package=extrafont) package as an alternative if you
have the fonts installed locally. This requires ghostscript to be installed
locally and can run into other issues, such as
[font names](https://github.com/wch/extrafont/issues/32) not being found.
Below, I use the showtext package because it's simpler. `load_hdx_fonts()`
wraps exactly this for both fonts at once.
```{r extrafont, out.width = "90%", out.height = "10%", fig.height = 4, fig.width = 6}
library(showtext)
# fall back to sans if Google Fonts can't be reached while building this
# vignette (e.g. no internet connection)
fonts_ok <- tryCatch(
{
font_add_google("Merriweather")
font_add_google("Roboto")
TRUE
},
error = function(cond) FALSE
)
showtext_auto()
p +
theme_hdx(
base_family = if (fonts_ok) "Roboto" else "sans",
title_family = if (fonts_ok) "Merriweather" else "sans"
) +
scale_color_hdx_discrete()
```
### Streamlined plotting
As clear above, even though we have an HDX theme function, we still have to
separately call the scale function to adjust our colors. And we have to call
these every time we make a new plot. So, to make life simpler, `gghdx()` is
provided as a convenience function that sets ggplot to:
- automatically use the HDX theme by default;
- use default HDX primary blue for point and line colors, and HDX data-grid
blue for fill when not an aesthetic;
- use `scale_fill_hdx_discrete()` and `scale_color_hdx_discrete()` as the default discrete fill
and color respectively;
- use `scale_fill_gradient_hdx_primary()` and `scale_color_gradient_hdx_primary()`
as the default continuous fill and color;
- loads the Roboto and Merriweather fonts from Google and activates their
usage for the current session.
You just have to run `gghdx()` once a session, and then our plots will already
be where we would like!
```{r gghdx, out.width = "90%", out.height = "10%", fig.height = 4, fig.width = 6}
# fall back to sans if Google Fonts can't be reached while building this
# vignette (e.g. no internet connection)
fonts_ok <- tryCatch(
{
gghdx()
TRUE
},
error = function(cond) FALSE
)
if (!fonts_ok) {
gghdx(showtext = FALSE, base_family = "sans", title_family = "sans")
}
p
```
And voĆla, we have our graph without specifying the theme or color scale.
### COVID plots
As a final example, we can closely match the COVID plots referenced in the
original visual guide using the theme and color scales in the package. These
reference plots predate the 2025 redesign, so this example intentionally uses
the legacy `sapphire`/`tomato` colorramps (kept for backwards compatibility)
rather than the new `primary`/`error` scales, to match the published images.
```{r example-plots, echo = FALSE, out.width = "45%", out.height = "20%", fig.show = "hold", fig.align = "default"}
knitr::include_graphics(
c(
here::here("man", "figures", "covid_blue.png"),
here::here("man", "figures", "covid_red.png")
)
)
```
The inbuilt data `gghdx::df_covid` has aggregated COVID data we can use to
mirror this plot. To make the data start at the y-axis, we can use
`scale_y_continuous_hdx()` which sets `expand = c(0, 0)` by default, and the
`label_number_hdx()` function to create custom labels. Since `gghdx()` set
the 2025 theme globally above, we explicitly add
`theme_hdx(design = "legacy")` to each plot so it matches the pre-2025
reference images instead of inheriting the ambient 2025 look.
```{r covid-match, fig.height = 5, fig.width = 6, out.width = "45%", fig.show = "hold", fig.align = "default"}
# fall back to sans if Google Fonts can't be reached while building this
# vignette (e.g. no internet connection)
fonts_ok <- tryCatch(
{
load_source_sans_3()
TRUE
},
error = function(cond) FALSE
)
legacy_family <- if (fonts_ok) "Source Sans 3" else "sans"
p_blue <- ggplot(
df_covid,
aes(
x = date,
y = cases_monthly
)
) +
geom_bar(
stat = "identity",
width = 6,
fill = hdx_hex("sapphire-hdx") # use sapphire for fill
) +
scale_y_continuous_hdx(
labels = label_number_hdx()
) +
scale_x_date(
date_breaks = "1 month",
labels = function(x) toupper(strftime(x, "%b"))
) +
theme_hdx(design = "legacy", base_family = legacy_family) +
labs(
title = "Monthly global COVID-19 confirmed cases in 2020",
subtitle = "DATA | JUL 2022 | World Health Organization",
x = "",
y = ""
)
p_blue
# create red plot
p_blue +
geom_bar(
aes(
fill = flag
),
width = 6,
stat = "identity"
) +
scale_fill_hdx_tomato() +
theme(
legend.position = "none"
) +
labs(
title = "Monthly COVID-19 # of cases surpasses 8 million"
)
```
We've used relatively few lines of code to match fairly closely these examples
plots!