The term spatio-temporal data can incorporate various spatial and temporal characteristics and different data may require different data structures for wrangling and analysis. The spatio-temporal data that cubble addresses are those collected at unique fixed locations, allowing for irregularity in the temporal dimension, such as the weather station data.
Beyond data wrangling, cubble makes glyph maps native to ggplot2:
geom_glyph() draws each location’s time series as a small plot at that
location, so spatial and temporal patterns can be seen in a single plot.
You can install the released version of cubble from CRAN with:
install.packages("cubble")
And the development version from GitHub with:
# install.packages("remotes")
# remotes::install_github("huizezhang-sherry/cubble")
install.packages("cubble", repos = c('https://huizezhang-sherry.r-universe.dev', 'https://cloud.r-project.org'))
Cubble organises spatio-temporal data in two structures: In a nested
cubble (spatial cubble), spatial variables are organised as columns and
temporal variables are nested within a specialised ts column:
#> # cubble: key: id [3], index: date, nested form
#> # spatial: [144.83, -37.98, 145.1, -37.67], Missing CRS!
#> # temporal: date [date], prcp [dbl], tmax [dbl], tmin [dbl]
#> id long lat elev name wmo_id ts
#> <chr> <dbl> <dbl> <dbl> <chr> <dbl> <list>
#> 1 ASN00086038 145. -37.7 78.4 essendon airport 95866 <tibble [10 × 4]>
#> 2 ASN00086077 145. -38.0 12.1 moorabbin airport 94870 <tibble [10 × 4]>
#> 3 ASN00086282 145. -37.7 113. melbourne airport 94866 <tibble [10 × 4]>
In a long cubble (temporal cubble), the temporal variables are expanded into the long form, while the spatial variables are stored as a data attribute:
#> # cubble: key: id [3], index: date, long form
#> # temporal: 2020-01-01 -- 2020-01-10 [1D], no gaps
#> # spatial: long [dbl], lat [dbl], elev [dbl], name [chr], wmo_id [dbl]
#> id date prcp tmax tmin
#> <chr> <date> <dbl> <dbl> <dbl>
#> 1 ASN00086038 2020-01-01 0 26.8 11
#> 2 ASN00086038 2020-01-02 0 26.3 12.2
#> 3 ASN00086038 2020-01-03 0 34.5 12.7
#> 4 ASN00086038 2020-01-04 0 29.3 18.8
#> 5 ASN00086038 2020-01-05 18 16.1 12.5
#> 6 ASN00086038 2020-01-06 104 17.5 11.1
#> 7 ASN00086038 2020-01-07 14 20.7 12.1
#> 8 ASN00086038 2020-01-08 0 26.4 16.4
#> 9 ASN00086038 2020-01-09 0 33.1 17.4
#> 10 ASN00086038 2020-01-10 0 34 19.6
#> # ℹ 20 more rows
The two forms can be pivoted back and forth with the pair of verb:
face_spatial() and face_temporal().

A glyph map draws each location’s time series as a small plot, a glyph,
at that location. cubble provides geom_glyph(), with
geom_glyph_box() and geom_glyph_line() for reference boxes and
lines, as ggplot2 layers. They take four aesthetics: x_major and
y_major for the location, and x_minor and y_minor for the time
series inside each glyph. Below, each glyph shows the proportion of
water samples above the bacteria guideline in the 0–6 days after heavy
rain at Sydney swim sites: ocean beaches clear within two days, while
inner harbour sites stay polluted for longer.
library(ggplot2)
beach <- read.csv(system.file("extdata/sydney-beach.csv", package = "cubble"))
sydney <- sf::st_read(system.file("extdata/sydney-land.geojson", package = "cubble"),
quiet = TRUE)
ggplot(beach, aes(x_major = long, y_major = lat,
x_minor = days_after_rain, y_minor = unsafe,
colour = water, group = swim_site)) +
geom_sf(data = sydney, fill = "#ECEAE4", colour = NA, inherit.aes = FALSE) +
geom_glyph_box(width = 0.028, height = 0.012, colour = "#9CADB7") +
geom_glyph(width = 0.028, height = 0.012, linewidth = 0.6, key_glyph = "path") +
scale_colour_manual(values = c("#BF5700", "#005F86"), name = NULL) +
coord_sf(xlim = c(151.11, 151.32), ylim = c(-34.0, -33.72)) +
theme_void() +
theme(legend.position = "bottom",
panel.background = element_rect(fill = "#e8f3ff", colour = NA))

For summaries that are an interval rather than a single value, such as
the daily minimum and maximum temperature, the
sugarglider package extends
cubble’s glyph maps with geom_glyph_segment() and
geom_glyph_ribbon().
geom_glyph() syntax: 3.
Visualization: glyph map
basics