ggblanket is a package of wrapper functions around the fantastic ggplot2 package.
The primary objective is to simplify ggplot2 visualisation.
Secondary objectives relate to:
It is intended to be useful for all levels of experience from beginner to expert.
library(ggblanket)
library(ggplot2)
library(dplyr)
library(stringr)
library(palmerpenguins)To simplify ggplot2 visualisation, the ggblanket package provides:
gg_* wrapper functions to plot a single geomcol
argumentpal argument consistentlyfacet argument to facet in a “wrap” or “grid”
layoutfacet2 argument to support facetting by
two variablessnakecase::to_sentencegeom_* arguments via
...theme argument for customisationgg_theme function to create a quick themeplotly::ggplotly tooltips with
add_tooltip_textgg_* wrapper functions to plot a single geomThese gg_*functions each wrap a ggplot2
ggplot(aes(...)) function with the applicable ggplot2
geom_*() function.
Always pipe in your data, so that you can access variable names from the Rstudio autocomplete.
iris |>
mutate(Species = str_to_sentence(Species)) |>
gg_point(
x = Sepal.Width,
y = Sepal.Length,
col = Species)col
argumentThere is no fill concept in ggblanket. Instead,
col relates to both the col and
fill concepts of ggplot2. A message is provided to users in
the console to remind them of this.
penguins |>
gg_histogram(
x = body_mass_g,
col = species) pal argument
consistentlyThese arguments work in the same way regardless of whether a
col variable is specified or not. This is therefore one
less thing for users to remember. The alpha argument is
also available.
penguins |>
mutate(sex = str_to_sentence(sex)) |>
group_by(species, sex) |>
summarise(body_mass_g = mean(body_mass_g, na.rm = TRUE)) |>
gg_col(
x = species,
y = body_mass_g,
col = sex,
position = position_dodge2(preserve = "single"),
pal = c("#1B9E77", "#9E361B"))facet argument to facet in a “wrap” or “grid”
layoutFacetting is treated as if it is an aesthetic, where the users just provide an unquoted variable to facet by.
If a single facet (or facet2) variable is provided, it’ll default to
a “wrap” layout. But you can change this with a
facet_layout = "grid" argument.
Both layouts have facet_scales and
facet_labels arguments available. The “wrap” layout also
has facet_ncol and facet_nrow arguments
available, while the “grid” layout also has the
facet_space,
penguins |>
tidyr::drop_na(sex) |>
mutate(sex = str_to_sentence(sex)) |>
gg_violin(
x = sex,
y = body_mass_g,
facet = species,
y_include = 0,
y_breaks = scales::breaks_width(1000),
pal = "#1B9E77")facet2 argument to support facetting
by two variablesFaceting by two variables is often useful. If both
facetand facet2 variables are provided, then
the gg_* function will default to a “grid” layout of facet
by facet2. But you can change this with a
facet_layout = "wrap" argument.
penguins |>
tidyr::drop_na(sex) |>
mutate(sex = str_to_sentence(sex)) |>
gg_density(
x = flipper_length_mm,
col = sex,
facet = species,
facet2 = island
)There is lots of customisation available through carefully named arguments with consistent prefixes.
This is designed to work with the Rstudio autocomplete to help you
find the adjustment you need. Press the tab key after typing
x,y, col or facet to
access the list from autocomplete. Then use arrow keys, and press tab
again to select.
Available arguments are:
*_breaks: Adjust the breaks of an axis*_expand: Adjust the padding beyond the limits*_include: Include a value within a scale*_labels: Adjust the labels on the breaks*_limits: Adjust the limits*_trans: Transform an axis*_sec_axis: Add a secondary axis*_title: Add a titlecol_continuous How to colour a continuous variable
(e.g. “steps”)col_legend_place: Place to put the legend
(e.g. “r”)col_legend_ncol: Number of columns to arrange legend
elements intocol_legend_nrow: Number of rows to arrange legend
elements intocol_legend_rev: Whether to reverse the legendfacet_layout: Whether the layout is to be “wrap” or
“grid”facet_scales: How facet scales are to be treatedfacet_space: Whether facet space is to be allocated
proportionallyfacet_ncol: How many columns to wrap facets intofacet_nrow: How many rows to wrap facets intoNote that ggblanket keeps out-of-bound values (i.e. it uses
scales::oob_keep under the hood). However, you can zoom in using
coord = coord_cartesian(xlim = ..., ylim = ...) (or by
filtering the data).
penguins |>
gg_jitter(
x = species,
y = body_mass_g,
col = flipper_length_mm,
col_continuous = "steps",
y_include = 0,
y_breaks = scales::breaks_width(1500),
y_labels = scales::label_number()
)snakecase::to_sentenceThis will make quicker to get to a plot that has titles that are good
for external people to see, and will often work nicely for your
snakecase column names.
For titles that you need to change manually, you can change manually
using x_title, y_title, or
col_title.
To remove titles, you can use x_title = "" within the
gg_* function and equivalent for the y and col titles. Or
add a
+ ggplot2::labs(x = NULL, y = NULL, col = NULL, fill = NULL)
layer as applicable.
penguins |>
group_by(species, sex) |>
summarise(across(body_mass_g, ~ round(mean(.x, na.rm = TRUE)), 0)) |>
gg_tile(
x = sex,
y = species,
col = body_mass_g,
x_labels = snakecase::to_sentence_case,
pal = pals::brewer.blues(9),
width = 0.9,
height = 0.9,
col_legend_place = "r",
title = "Average penguin body mass",
subtitle = "Palmer Archipelago, Antarctica",
theme = gg_theme(grid_h = FALSE,
bg_plot_pal = "white",
axis_pal = "white",
ticks_pal = "white")) +
geom_text(aes(label = body_mass_g), col = "#232323", size = 3.5) When plots are horizontal, ggblanket ensures y labels, colours and legends are generally in the right order.
penguins |>
tidyr::drop_na(sex) |>
group_by(species, sex, island) |>
summarise(body_mass_kg = mean(body_mass_g) / 1000) |>
gg_col(
x = body_mass_kg,
y = species,
col = sex,
facet = island,
width = 0.75,
col_labels = snakecase::to_sentence_case,
position = "dodge")The default x and y scales have been designed to create symmetry and balance.
If the y is numeric, the y limits will default to the max of the y breaks with zero y expanding. It will do similar with the x scale, if y is character/factor/logical and x is numeric.
The default theme has a clean look designed to draw attention to the patterns of the data in the panel.
Note if you use default theme, ggblanket guesses the gridlines you
want based on the type of data provided to the gg_*
function. If you provide a theme, you will need that theme to provide
any gridlines that you want.
storms |>
group_by(year) |>
filter(between(year, 1980, 2020)) |>
summarise(wind = mean(wind, na.rm = TRUE)) |>
gg_line(
x = year,
y = wind,
x_labels = scales::label_number(big.mark = ""),
y_include = 0,
title = "Storm wind speed",
subtitle = "USA average storm wind speed, 1980\u20132020",
y_title = "Wind speed (knots)",
caption = "Source: NOAA"
) +
geom_point()geom_* arguments via
...This relates to all other arguments other than the mapping argument with aesthetics.
Common arguments to add are size, linewidth
and width. All arguments and can be identified through the
help on the relevant ggplot2::geom_* function.
penguins |>
tidyr::drop_na(sex) |>
gg_smooth(
x = flipper_length_mm,
y = body_mass_g,
col = sex,
size = 0.5,
level = 0.99,
col_legend_place = "t",
col_title = "",
col_labels = snakecase::to_sentence_case
) theme argument for customisationThis allows you to utilise the simplicity of ggblanket, while making content that has your required look and feel.
By using the theme argument, your theme will control all
theme aspects, other than the legend position, direction and
justification.
These are controlled within the gg_* function, so that
legend positions can be adjusted easily with the
col_legend_place argument
(e.g. `col_legend_place = "r").
If you prefer to have your theme adjust everything
including the legend, then add your theme as a layer instead
(e.g. + theme_grey()).
penguins |>
mutate(sex = str_to_sentence(sex)) |>
gg_point(x = bill_depth_mm,
y = bill_length_mm,
col = sex,
facet = species,
pal = c("#1B9E77", "#9E361B"),
theme = theme_grey())gg_theme function to create a quick themeThe gg_theme function allows you to create a theme that
looks similar to the ggblanket look and feel.
This includes the following arguments for adjusting gridlines, background colours, text and axis lines and ticks.
Use the grid_h and grid_v logical arguments
to add gridlines. Otherwise this function defaults to no gridlines.
There is a void = TRUE argument that is useful for
maps.
storms |>
group_by(year) |>
filter(between(year, 1980, 2020)) |>
summarise(wind = mean(wind, na.rm = TRUE)) |>
gg_col(
x = year,
y = wind,
x_labels = scales::label_comma(big.mark = ""),
x_expand = c(0, 0),
width = 0.75,
theme = gg_theme(
bg_plot_pal = "white",
bg_panel_pal = "white",
grid_h = TRUE))This is because the ... argument can allow you to access
all arguments within the ggblanket gg_
function.
gg_point_custom <- function(data, x, y, col,
size = 3,
pal = pals::brewer.dark2(9),
col_title = "",
col_legend_place = "t",
...) {
data |>
gg_point(x = {{ x }}, y = {{ y }}, col = {{col}},
size = size,
pal = pal,
col_title = col_title,
col_legend_place = col_legend_place,
...)
}
iris |>
mutate(Species = str_to_sentence(Species)) |>
gg_point_custom(
x = Sepal.Width,
y = Sepal.Length,
col = Species,
title = "Edgar Anderson's iris data",
subtitle = "Iris sepal length by width and species",
caption = "Edgar Anderson, 1935"
)plotly::ggplotly tooltips with
add_tooltip_textThe add_tooltip_text function allows users to create
nice tooltips in combination with the gg_*()
text argument, and the tooltip = "text"
argument in ggplotly.
theme_custom <- gg_theme(
"helvetica",
bg_plot_pal = "white",
bg_panel_pal = "white",
grid_h = TRUE
)
iris |>
mutate(Species = str_to_sentence(Species)) |>
add_tooltip_text(titles = snakecase::to_sentence_case) |>
gg_point(
x = Sepal.Width,
y = Sepal.Length,
col = Species,
text = text,
col_legend_place = "r",
theme = theme_custom) |>
plotly::ggplotly(tooltip = "text")Like everything, ggblanket has it’s limitations.
You cannot easily plot:
alpha, size,
linewidth, shape, and
linetypedensity in geom_histogram)geom_bin2d)For aesthetics of alpha, size,
linewidth, shape, and linetype,
you can use gg_blank in addition to a col
argument and then add the title of your new aesthetic to align with the
col_title.
penguins |>
gg_blank(x = flipper_length_mm, y = body_mass_g, col = species) +
geom_point(aes(shape = species)) +
labs(shape = "Species")If you wish to use non-default computed x or
y variables, you need to use ggplot2. You can
mimic the ggblanket look and feel if you would like using
gg_theme and other scale_* modifications.
Alternatively, you could instead settle for using the default
computed variable with ggblanket.
diamonds |>
ggplot() +
geom_histogram(aes(x = carat, y = after_stat(density)),
col = pal_viridis_mix(1),
fill = pal_viridis_mix(1),
alpha = 0.9) +
gg_theme(grid_h = TRUE) +
scale_y_continuous(expand = expansion(mult = c(0, 0.05)),
breaks = scales::breaks_pretty(5)) +
labs(x = "Carat", y = "Density")All geom’s that use a computed col variable are
not supported by ggblanket, and you will have to use ggplot2 for these
plots.
diamonds |>
ggplot() +
geom_bin_2d(aes(x = carat, y = price, fill = after_stat(count))) +
gg_theme(grid_h = TRUE) +
scale_fill_gradientn(colours = viridis::viridis(9)) +
scale_y_continuous(expand = c(0, 0),
breaks = scales::breaks_pretty(5),
limits = range(scales::breaks_pretty(5)(diamonds$price))) +
labs(x = "Carat", y = "Price", fill = "Count")For some ggplot2 functionality unsupported by ggblanket, you will be
able to add a ggplot2 layer to your ggblanket code. For example, using
+ labs(x = NULL) or
+ facet_grid(..., switch = "y").