diff --git a/DESCRIPTION b/DESCRIPTION
index d592f31..795d8ea 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,7 +1,7 @@
Package: ggpattern
Type: Package
Title: 'ggplot2' Pattern Geoms
-Version: 1.1.0-8
+Version: 1.1.0-9
Authors@R: c(person("Mike", "FC", role = "aut"),
person("Trevor L.", "Davis", role = c("aut", "cre"),
email = "trevor.l.davis@gmail.com",
@@ -19,7 +19,7 @@ Imports:
ggplot2 (>= 3.5.1),
glue,
grid,
- gridpattern (>= 1.2.0-4),
+ gridpattern (>= 1.2.0-6),
lifecycle,
rlang (>= 1.1.3),
scales,
diff --git a/NAMESPACE b/NAMESPACE
index 4deca73..0dd3b6b 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -185,6 +185,10 @@ export(scale_pattern_type_continuous)
export(scale_pattern_type_discrete)
export(scale_pattern_type_identity)
export(scale_pattern_type_manual)
+export(scale_pattern_units_continuous)
+export(scale_pattern_units_discrete)
+export(scale_pattern_units_identity)
+export(scale_pattern_units_manual)
export(scale_pattern_xoffset_continuous)
export(scale_pattern_xoffset_discrete)
export(scale_pattern_xoffset_identity)
diff --git a/NEWS.md b/NEWS.md
index 2614481..30da591 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -39,6 +39,12 @@
(in addition to color strings) (#112).
Note using gradient/pattern fills will require R (>= 4.2) and a graphics device with support for the gradient/pattern fill feature.
Use of just color fills should continue to work on a wider variety of R versions and graphics devices.
+* {ggpattern} now supports the `pattern_units` aesthetic (#80).
+ Supported by most "geometry" patterns.
+ It sets the `grid::unit()` used by the `pattern_spacing`, `pattern_xoffset`, `pattern_yoffset`,
+ and (for the "wave" pattern) the `pattern_frequency` aesthetics.
+ Default is "snpc" while "cm" and "inches" are likely alternatives.
+
* `geom_bin_2d_pattern()` is now an alias for `geom_bin2d_pattern()`.
This matches `{ggplot2}` which has both `geom_bin_2d()` and `geom_bin2d()`.
diff --git a/R/geom-.R b/R/geom-.R
index fd212be..fa7f8c4 100644
--- a/R/geom-.R
+++ b/R/geom-.R
@@ -40,7 +40,8 @@ pattern_aesthetics <- aes(
pattern_grid = 'square',
pattern_rot = 0,
- pattern_res = getOption("ggpattern_res", NA)
+ pattern_res = getOption("ggpattern_res", NA),
+ pattern_units = 'snpc'
)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -57,47 +58,51 @@ create_key_pattern_grob <- function(data, params, size, aspect_ratio, boundary_d
data$size <- data$linewidth %||% data$size %||% 0.5
lwd <- min(data$size, min(size) / 4) * .pt
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # Convert the width/height of the key into npc sizes
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- key_native_x <- abs(as.numeric(grid::convertWidth (unit(size[1], 'mm'), 'native')))
- key_native_y <- abs(as.numeric(grid::convertHeight(unit(size[2], 'mm'), 'native')))
-
- vp <- grid::current.viewport()
- vp_native_x <- abs(diff(vp$xscale))
- vp_native_y <- abs(diff(vp$yscale))
-
-
- key_npc_x <- abs(as.numeric(grid::convertWidth (unit(size[1], 'mm'), 'npc')))
- key_npc_y <- abs(as.numeric(grid::convertHeight(unit(size[2], 'mm'), 'npc')))
-
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # What's the overall scale_factor?
- # The legend is actually drawn in its own viewport with an area of 1x1 npc.
- # I have to do some fancy scaling to draw the current pattern in this
- # scaled viewport as currently appears in the full viewport of the plot.
- # i.e. I need to make the pattern in the legend look like the pattern in the
- # plot.
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- denom <- sqrt(2) * (1/aspect_ratio) * 9/8
-
- if (vp_native_x/vp_native_y < aspect_ratio) {
- scale_factor <- 1/key_npc_x / aspect_ratio / denom
+ if (data$pattern_units == "snpc") {
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # Convert the width/height of the key into npc sizes
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ key_native_x <- abs(as.numeric(grid::convertWidth (unit(size[1], 'mm'), 'native')))
+ key_native_y <- abs(as.numeric(grid::convertHeight(unit(size[2], 'mm'), 'native')))
+
+ vp <- grid::current.viewport()
+ vp_native_x <- abs(diff(vp$xscale))
+ vp_native_y <- abs(diff(vp$yscale))
+
+
+ key_npc_x <- abs(as.numeric(grid::convertWidth (unit(size[1], 'mm'), 'npc')))
+ key_npc_y <- abs(as.numeric(grid::convertHeight(unit(size[2], 'mm'), 'npc')))
+
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # What's the overall scale_factor?
+ # The legend is actually drawn in its own viewport with an area of 1x1 npc.
+ # I have to do some fancy scaling to draw the current pattern in this
+ # scaled viewport as currently appears in the full viewport of the plot.
+ # i.e. I need to make the pattern in the legend look like the pattern in the
+ # plot.
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ denom <- sqrt(2) * (1/aspect_ratio) * 9/8
+
+ if (vp_native_x/vp_native_y < aspect_ratio) {
+ scale_factor <- 1/key_npc_x / aspect_ratio / denom
+ } else {
+ scale_factor <- 1/key_npc_y/denom
+ }
+
+ scale_factor <- scale_factor * data$pattern_key_scale_factor
+
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ # Compensate for box the key is rendered in being different aspect ratios
+ # i.e. theme(legend.key.width = unit(2, 'cm'),
+ # legend.key.height = unit(3, 'cm')
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ key_aspect_ratio <- key_native_x/key_native_y
+ scale_factor <- scale_factor / key_aspect_ratio
} else {
- scale_factor <- 1/key_npc_y/denom
+ scale_factor <- 1.00 * data$pattern_key_scale_factor
}
- scale_factor <- scale_factor * data$pattern_key_scale_factor
-
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # Compensate for box the key is rendered in being different aspect ratios
- # i.e. theme(legend.key.width = unit(2, 'cm'),
- # legend.key.height = unit(3, 'cm')
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- key_aspect_ratio <- key_native_x/key_native_y
- scale_factor <- scale_factor / key_aspect_ratio
-
this_params <- fill_default_params(data)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/R/scale-pattern-auto.R b/R/scale-pattern-auto.R
index f3f8bc3..b3952fc 100644
--- a/R/scale-pattern-auto.R
+++ b/R/scale-pattern-auto.R
@@ -1128,6 +1128,64 @@ scale_pattern_rot_discrete <- function(..., range = c(0, 360)) {
...
)
}
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#' @rdname scale_discrete
+#' @export
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+scale_pattern_units_continuous <- function(name = waiver(),
+ breaks = waiver(),
+ labels = waiver(),
+ limits = NULL,
+ choices = c('snpc', 'cm', 'inches'),
+ trans = deprecated(),
+ guide = 'legend',
+ ...,
+ transform = 'identity') {
+
+ if (is.null(choices)) {
+ abort('scale_pattern_units_continuous(): must specify "choices" argument')
+ }
+ if (lifecycle::is_present(trans)) {
+ lifecycle::deprecate_warn('1.1.1',
+ 'scale_pattern_units_continuous(trans)',
+ 'scale_pattern_units_continuous(transform)')
+ transform <- trans
+ }
+
+ ggplot2::continuous_scale(
+ aesthetics = 'pattern_units',
+ palette = function(x) choices[as.integer(x * (length(choices) - 1) + 1)],
+ name = name,
+ breaks = breaks,
+ labels = labels,
+ limits = limits,
+ transform = transform,
+ guide = guide,
+ ...)
+}
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#' @rdname scale_discrete
+#' @importFrom utils head
+#' @export
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+scale_pattern_units_discrete <- function(..., choices = c('snpc', 'cm', 'inches'), guide = 'legend') {
+ force(range)
+
+ if (is.null(choices)) {
+ abort('scale_pattern_units_discrete(): must specify "choices" argument')
+ }
+
+ ggplot2::discrete_scale(
+ aesthetics = 'pattern_units',
+ palette = function(n) {
+ idx <- cut(seq(n), length(choices), labels = FALSE, include.lowest = TRUE)
+ choices[idx]
+ },
+ guide = guide,
+ ...
+ )
+}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#' Create your own discrete scale
#'
@@ -1342,6 +1400,13 @@ scale_pattern_rot_manual <- function(..., values, breaks = waiver()) {
manual_scale('pattern_rot', values, breaks, ...)
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#' @rdname scale_pattern_manual
+#' @export
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+scale_pattern_units_manual <- function(..., values, breaks = waiver()) {
+ manual_scale('pattern_units', values, breaks, ...)
+}
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#' Use values without scaling
#'
#' @param ...,guide See \code{ggplot2} for documentation on identity scales.
@@ -1711,3 +1776,16 @@ scale_pattern_rot_identity <- function(..., guide = 'none') {
super = ScaleContinuousIdentity
)
}
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#' @rdname scale_pattern_identity
+#' @export
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+scale_pattern_units_identity <- function(..., guide = 'none') {
+ discrete_scale(
+ aesthetics = 'pattern_units',
+ palette = identity_pal(),
+ ...,
+ guide = guide,
+ super = ScaleDiscreteIdentity
+ )
+}
diff --git a/data-raw/config.R b/data-raw/config.R
index 5b7cb26..a2240ce 100644
--- a/data-raw/config.R
+++ b/data-raw/config.R
@@ -32,4 +32,5 @@ pattern_frequency | | continuous | NULL
pattern_grid | | discrete | c('square', 'hex')
pattern_res | | continuous | NULL
pattern_rot | | continuous | c(0, 360)
+pattern_units | | discrete | c('snpc', 'cm', 'inches')
", trim_ws = TRUE, delim = "|")
diff --git a/man/scale_discrete.Rd b/man/scale_discrete.Rd
index c8e86f3..43c0e06 100644
--- a/man/scale_discrete.Rd
+++ b/man/scale_discrete.Rd
@@ -16,6 +16,8 @@
\alias{scale_pattern_orientation_discrete}
\alias{scale_pattern_grid_continuous}
\alias{scale_pattern_grid_discrete}
+\alias{scale_pattern_units_continuous}
+\alias{scale_pattern_units_discrete}
\alias{scale_pattern_continuous}
\alias{scale_pattern_discrete}
\title{Scales for discrete pattern aesthetics}
@@ -136,6 +138,24 @@ scale_pattern_grid_discrete(
guide = "legend"
)
+scale_pattern_units_continuous(
+ name = waiver(),
+ breaks = waiver(),
+ labels = waiver(),
+ limits = NULL,
+ choices = c("snpc", "cm", "inches"),
+ trans = deprecated(),
+ guide = "legend",
+ ...,
+ transform = "identity"
+)
+
+scale_pattern_units_discrete(
+ ...,
+ choices = c("snpc", "cm", "inches"),
+ guide = "legend"
+)
+
scale_pattern_continuous(
name = waiver(),
breaks = waiver(),
diff --git a/man/scale_pattern_identity.Rd b/man/scale_pattern_identity.Rd
index 7c1477d..15e069c 100644
--- a/man/scale_pattern_identity.Rd
+++ b/man/scale_pattern_identity.Rd
@@ -29,6 +29,7 @@
\alias{scale_pattern_grid_identity}
\alias{scale_pattern_res_identity}
\alias{scale_pattern_rot_identity}
+\alias{scale_pattern_units_identity}
\alias{scale_pattern_color_identity}
\title{Use values without scaling}
\usage{
@@ -84,6 +85,8 @@ scale_pattern_res_identity(..., guide = "none")
scale_pattern_rot_identity(..., guide = "none")
+scale_pattern_units_identity(..., guide = "none")
+
scale_pattern_identity(..., guide = "none")
}
\arguments{
diff --git a/man/scale_pattern_manual.Rd b/man/scale_pattern_manual.Rd
index 9b17c8e..c5151e7 100644
--- a/man/scale_pattern_manual.Rd
+++ b/man/scale_pattern_manual.Rd
@@ -29,6 +29,7 @@
\alias{scale_pattern_grid_manual}
\alias{scale_pattern_res_manual}
\alias{scale_pattern_rot_manual}
+\alias{scale_pattern_units_manual}
\alias{scale_pattern_color_manual}
\title{Create your own discrete scale}
\usage{
@@ -84,6 +85,8 @@ scale_pattern_res_manual(..., values, breaks = waiver())
scale_pattern_rot_manual(..., values, breaks = waiver())
+scale_pattern_units_manual(..., values, breaks = waiver())
+
scale_pattern_manual(..., values, breaks = waiver(), na.value = "none")
}
\arguments{
diff --git a/tests/testthat/_snaps/geom/density.svg b/tests/testthat/_snaps/geom/density.svg
index c159f7c..3c094eb 100644
--- a/tests/testthat/_snaps/geom/density.svg
+++ b/tests/testthat/_snaps/geom/density.svg
@@ -20,241 +20,237 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-0.00
-0.05
-0.10
-0.15
-0.20
-0.25
-
-
-
-
-
-
-
-
-
-
-
-
-10
-15
-20
-25
-30
-35
+0.00
+0.05
+0.10
+0.15
+0.20
+0.25
+
+
+
+
+
+
+
+
+
+
+
+
+10
+15
+20
+25
+30
+35
mpg
-density
-
-as.factor(cyl)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-4
-6
-8
-ggpattern::geom_density_pattern()
+density
+
+as.factor(cyl)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4
+6
+8
+ggpattern::geom_density_pattern()
diff --git a/tests/testthat/_snaps/geom/violin.svg b/tests/testthat/_snaps/geom/violin.svg
index e1757af..6c18817 100644
--- a/tests/testthat/_snaps/geom/violin.svg
+++ b/tests/testthat/_snaps/geom/violin.svg
@@ -50,35 +50,35 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
@@ -106,11 +106,11 @@
-
+
-
-
-
+
+
+
diff --git a/tests/testthat/test-geom.R b/tests/testthat/test-geom.R
index 052f5f5..e155db9 100644
--- a/tests/testthat/test-geom.R
+++ b/tests/testthat/test-geom.R
@@ -116,7 +116,7 @@ test_that("geometry patterns work as expected", {
})
expect_doppelganger("histogram", {
- ggplot(diamonds, aes(carat)) +
+ ggplot(ggplot2::diamonds, aes(carat)) +
geom_histogram_pattern(pattern = "stripe", bins = 30)
})
diff --git a/vignettes/developing-patterns.Rmd b/vignettes/developing-patterns.Rmd
index 8fa390a..f47e486 100644
--- a/vignettes/developing-patterns.Rmd
+++ b/vignettes/developing-patterns.Rmd
@@ -90,11 +90,12 @@ so may make your pattern more useful for others:
| `pattern_scale` | Scale | 1 | Multiplier |
| `pattern_shape` | Plotting shape | 1 | shapes |
| `pattern_size` | Stroke linewidth | 1 | linewidth |
-| `pattern_spacing` | Spacing between repetitions of pattern | 0.05 | value in range [0, 1] (snpc units) |
+| `pattern_spacing` | Spacing between repetitions of pattern | 0.05 | value in `pattern_units` grid units |
| `pattern_subtype` | Generic control option | NA | pattern-dependent |
| `pattern_type` | Generic control option | NA | pattern-dependent |
-| `pattern_xoffset` | Shift pattern along x axis | 0 | value in range [0, 1] (snpc units) |
-| `pattern_yoffset` | Shift pattern along y axis | 0 | value in range [0, 1] (snpc units) |
+| `pattern_units` | Pattern grid unit | 'snpc' | `grid::unit()` unit i.e. 'snpc', 'cm', and 'inches' |
+| `pattern_xoffset` | Shift pattern along x axis | 0 | value in `pattern_units` grid units |
+| `pattern_yoffset` | Shift pattern along y axis | 0 | value in `pattern_units` grid units |
diff --git a/vignettes/patterns-points.Rmd b/vignettes/patterns-points.Rmd
index d1c7d8b..f6b6951 100644
--- a/vignettes/patterns-points.Rmd
+++ b/vignettes/patterns-points.Rmd
@@ -47,9 +47,10 @@ suppressPackageStartupMessages({
| pattern\_fill | Fill colour | 'grey80' | colour |
| pattern\_angle | Rotation angle | 30 | angle in degrees |
| pattern\_density | Approx. fraction of area the pattern fills | 0.2 | value in range [0, 1] (fraction) |
-| pattern\_spacing | Spacing between repetitions of pattern | 0.05 | value in range [0, 1] (snpc units) |
-| pattern\_xoffset | Shift pattern along x axis | 0 | value in range [0, 1] (snpc units) |
-| pattern\_yoffset | Shift pattern along y axis | 0 | value in range [0, 1] (snpc units) |
+| pattern\_spacing | Spacing between repetitions of pattern | 0.05 | value in `pattern_units` grid units |
+| pattern\_xoffset | Shift pattern along x axis | 0 | value in `pattern_units` grid units |
+| pattern\_yoffset | Shift pattern along y axis | 0 | value in `pattern_units` grid units |
+| pattern\_units | Pattern grid unit | 'snpc' | `grid::unit()` unit i.e. 'snpc', 'cm', and 'inches' |
| pattern\_alpha | Alpha | NA | value in range [0, 1] or NA |
| pattern\_linetype | Stroke linetype | 1 | linetype |
| pattern\_size | Stroke linewidth | 1 | linewidth |
diff --git a/vignettes/patterns-stripes.Rmd b/vignettes/patterns-stripes.Rmd
index 314feaa..9490ce4 100644
--- a/vignettes/patterns-stripes.Rmd
+++ b/vignettes/patterns-stripes.Rmd
@@ -47,9 +47,10 @@ suppressPackageStartupMessages({
| pattern\_fill | Fill colour | 'grey80' | colour |
| pattern\_angle | Rotation angle | 30 | angle in degrees |
| pattern\_density | Approx. fraction of area the pattern fills | 0.2 | value in range [0, 1] (fraction) |
-| pattern\_spacing | Spacing between repetitions of pattern | 0.05 | value in range [0, 1] (snpc units) |
-| pattern\_xoffset | Shift pattern along x axis | 0 | value in range [0, 1] (snpc units) |
-| pattern\_yoffset | Shift pattern along y axis | 0 | value in range [0, 1] (snpc units) |
+| pattern\_spacing | Spacing between repetitions of pattern | 0.05 | value in `pattern_units` grid units |
+| pattern\_xoffset | Shift pattern along x axis | 0 | value in `pattern_units` grid units |
+| pattern\_yoffset | Shift pattern along y axis | 0 | value in `pattern_units` grid units |
+| pattern\_units | Pattern grid unit | 'snpc' | `grid::unit()` unit i.e. 'snpc', 'cm', and 'inches' |
| pattern\_alpha | Alpha | NA | value in range [0, 1] or NA |
| pattern\_linetype | Stroke linetype | 1 | linetype |
| pattern\_size | Stroke linewidth | 1 | linewidth |
diff --git a/vignettes/patterns-tilings.Rmd b/vignettes/patterns-tilings.Rmd
index 647bbc4..09c5428 100644
--- a/vignettes/patterns-tilings.Rmd
+++ b/vignettes/patterns-tilings.Rmd
@@ -189,9 +189,10 @@ ggplot(df2, aes(x="", y = value, pattern_angle = group))+
| pattern\_colour | Stroke colour | 'grey20' | colour |
| pattern\_fill | Fill colour | 'grey80' | colour |
| pattern\_angle | Rotation angle | 30 | angle in degrees |
-| pattern\_spacing | Spacing between repetitions of pattern | 0.05 | value in range [0, 1] (snpc units) |
-| pattern\_xoffset | Shift pattern along x axis | 0 | value in range [0, 1] (snpc units) |
-| pattern\_yoffset | Shift pattern along y axis | 0 | value in range [0, 1] (snpc units) |
+| pattern\_spacing | Spacing between repetitions of pattern | 0.05 | value in `pattern_units` grid units |
+| pattern\_xoffset | Shift pattern along x axis | 0 | value in `pattern_units` grid units |
+| pattern\_yoffset | Shift pattern along y axis | 0 | value in `pattern_units` grid units |
+| pattern\_units | Pattern grid unit | 'snpc' | `grid::unit()` unit i.e. 'snpc', 'cm', and 'inches' |
| pattern\_alpha | Alpha | NA | value in range [0, 1] or NA |
| pattern\_linetype | Stroke linetype | 1 | linetype |
| pattern\_size | Stroke linewidth | 1 | linewidth |