R v4.1.0 - {grid} graphics new feature - patterns (part 3)

Introduciton

As of R 4.1.0 there is built-in support for patterns in grid graphics. There are 3 types of pattern:

  1. grid::linearGradient() for linear colour gradients
  2. grid::radialGradient() for radial colour gradients
  3. grid::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:

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

  1. Create a circle
  2. 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.

  1. Create a tiny rectangle
  2. Make a pattern out of the tiny rectangle
  3. Fill a circle with this tiny rectangle pattern
  4. 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)