Introduciton
As of R 4.1.0 there is built-in support for patterns in grid
graphics. There
are 3 types of pattern:
grid::linearGradient()
for linear colour gradientsgrid::radialGradient()
for radial colour gradientsgrid::pattern()
repetition of any combination of graphic objects (grobs)
This quick post summarises a few more things which can be done with patterns:
- A mask with an alpha channel can be applied to the pattern to create some softer effects
- Patterns can be defined using:
- absolute units (like ‘mm’), in which case their rendered size does not change
- relative units (like ‘npc’) mean that the size and shape of the pattern renders differently depending on the viewport
Reading list:
- 14 July 2020 Catching up with R Graphics Gradients, Patterns, Clipping Paths, and Masks
- 15 July 2020 New Features in the R Graphics Engine Paul Murrell
library(grid)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Ensure that images are rendered using a device which understands patterns
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
knitr::opts_chunk$set(dev.args = list(png = list(type = "cairo")))
A simple mask
- Create a circle
- use the circl as the mask when drawing a rectangle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 1. Create a circle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mask <- circleGrob(
r = unit(23, 'mm'),
gp = gpar(fill='black')
)
grid.newpage()
grid.draw(mask)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 4. Create a rectangle using the patterned circle as a mask
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
small_rect <- rectGrob(
width = unit(40, 'mm'),
height = unit(40, 'mm'),
gp = gpar(
fill = 'lightblue',
col = 'darkblue'
),
vp = viewport(
mask = mask
)
)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Display the rectangle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
grid.newpage()
grid.draw(small_rect)
A mask can have a pattern
Rather than a mask being just a solid shape or something with an alpha channel, it is also possible to create a mask which itself contains a pattern.
- Create a tiny rectangle
- Make a pattern out of the tiny rectangle
- Fill a circle with this tiny rectangle pattern
- Create a rectangle using the patterned circle as a mask
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 1. Create a tiny rectangle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tiny_rect <- rectGrob(
width = unit(4, 'mm'),
height = unit(4, 'mm'),
gp = gpar(fill = 'pink')
)
grid.newpage()
grid.draw(tiny_rect)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 2. Make a pattern out of the tiny rectangle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tiny_rect_pattern <- grid::pattern(
tiny_rect,
width = unit(10, 'mm'),
height = unit(10, 'mm'),
extend = 'repeat'
)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 3. Fill a circle with this tiny rectangle pattern
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mask <- circleGrob(
r = unit(23, 'mm'),
gp = gpar(fill=tiny_rect_pattern)
)
grid.newpage()
grid.draw(mask)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 4. Create a rectangle using the patterned circle as a mask
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
small_rect <- rectGrob(
width = unit(40, 'mm'),
height = unit(40, 'mm'),
gp = gpar(
fill = 'lightblue',
col = 'darkblue'
),
vp = viewport(
mask = mask
)
)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Display the rectangle
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
grid.newpage()
grid.draw(small_rect)