The gridpattern
package supports heraldic color hatching via
grid.pattern_hatch(). Hatching encodes color information
using patterns of lines and dots, allowing images to be reproduced in
black and white while retaining color identity.
Four systems are supported via the subtype argument:
"combinatorial" (default): extends the seven
standard Petra Sancta tinctures with systematically derived mixed-color
combinations following three rules:
"fox-davies": contains the sixteen hatchings from
Fox-Davies’ A
Complete Guide to Heraldry covering the seven standard Petra
Sancta tinctures plus nine extensions from German heraldry.
"goodman": contains all the hatchings from David
Goodman’s Heraldic
Tincture reference (v2.0, 2024).
"unicode": the system used in the official Unicode
character chart pdfs to render “colored” (emoji) glyphs in
black-and-white.
Use names_hatch() to query supported tincture names for
a given subtype. The “hatch” pattern will also coerce some of the more
common color names to the right tincture e.g. “gold” and “yellow” will
be both coerced to “or” and vice versa.
names_hatch()
#> [1] "black" "blue" "brown" "green" "grey"
#> [6] "lavender" "light blue" "lime green" "magenta" "mint green"
#> [11] "olive" "orange" "pink" "purple" "red"
#> [16] "rose" "slate" "teal" "umbre" "violet"
#> [21] "white" "yellow"
names_hatch("fox-davies")
#> [1] "argent" "azure" "bleu celeste" "brunatre" "carnation"
#> [6] "cendree" "eisenfarbe" "gules" "or" "orange"
#> [11] "proper" "purpure" "sable" "sanguine" "tenne"
#> [16] "vert"
names_hatch("goodman")
#> [1] "argent" "azure" "bleu celeste" "bronze" "brunatre"
#> [6] "carnation" "cendree" "copper" "gules" "lead"
#> [11] "murrey" "or" "orange" "purpure" "rose"
#> [16] "sable" "sanguine" "steel" "tenne" "vert"
names_hatch("unicode")
#> [1] "black" "blue" "brown" "green" "grey"
#> [6] "light blue" "orange" "pink" "purple" "red"
#> [11] "white" "yellow"The default "combinatorial" subtype starts from the set
of five Munsell
primary colors of red, yellow, green, blue, and purple plus black
and white and the standard Petra Sancta color hatching system and then
systematically derives additional color hatchings via three rules:
Note: The mixed display colors shown above can be sensitive to the exact hex values chosen for the primaries. The results are fairly consistent when the primaries are the saturated, high-chroma colors typical of heraldry combined with Munsell pigment mixing but softer or more neutral primaries can shift some secondaries noticeably (for example, mixing yellow and blue can yield anything from olive-grey to muted purple depending on the blue’s hue angle).
The "fox-davies" hatching subtype includes the seven
standard tinctures plus nine extensions from German heraldry whose
hatchings were included in Fox-Davies’ A
Complete Guide to Heraldry.
The "goodman" hatching subtype includes all the
hatchings in David Goodman’s Heraldic
Tincture reference (v2.0, 2024). This shares most hatchings with
Fox-Davies but differs in few ways:
\ crossing lines.The "unicode" hatching subtype provides each of the
hatching used in the official Unicode character chart pdfs to assign a
distinct pattern to each color to render “colored” (emoji) glyphs in
black-and-white. Notably Unicode has twelve different colored
heart emoji (red, blue, green, yellow, purple, black, white, brown,
orange, light blue, grey, pink) that each needed a separate
hatching.
One of the techniques to meet Web Content Accessibility Guidelines (WCAG) is to use color and pattern to ensure things are accessible to the color-blind.
The Okabe-Ito palette is a widely used colorblind-friendly palette. Here is an example of adding a simple hatching scheme to go with this palette to provide visual redundancy:
oi_names <- c(
"black", "orange", "sky blue", "bluish green",
"yellow", "blue", "vermilion", "reddish purple", "white"
)
oi_hex <- c(
"#000000", "#E69F00", "#56B4E9", "#009E73",
"#F0E442", "#0072B2", "#D55E00", "#CC79A7", "#FFFFFF"
)
oi_hatch <- c(
NA, "orange", "bleu celeste", "vert",
"or", "azure", "gules", "purpure", NA
)
sx <- c(0, 0, 1, 1)
sy <- c(1, 0, 0, 1)
n <- length(oi_names)
grid.newpage()
grid.rect(gp = gpar(fill = "white", col = NA))
pushViewport(viewport(width = 0.90, height = 0.94))
grid.text(
"Okabe-Ito Palette with Heraldic Hatching",
y = unit(1, "npc") - unit(0.25, "cm"),
just = "top",
gp = gpar(fontsize = 13, fontface = "bold")
)
pushViewport(viewport(
y = 0.46, height = 0.88,
layout = grid.layout(
n, 3,
widths = unit(c(3, 2.5, 4), "null"),
heights = unit(rep(1, n), "null")
)
))
for (i in seq_len(n)) {
grid.text(oi_names[i], x = 0.90, just = "right",
gp = gpar(fontsize = 12, col = "black"),
vp = viewport(layout.pos.row = i, layout.pos.col = 1))
grid.text(oi_hex[i],
gp = gpar(fontsize = 12, fontfamily = "mono", col = "black"),
vp = viewport(layout.pos.row = i, layout.pos.col = 2))
pushViewport(viewport(layout.pos.row = i, layout.pos.col = 3))
grid.rect(gp = gpar(fill = oi_hex[i], col = "black", lwd = 3.0))
if (!is.na(oi_hatch[i])) {
grid.pattern_hatch(sx, sy, type = oi_hatch[i],
colour = "black", spacing = 0.18, linewidth = 0.8)
}
popViewport()
}
popViewport()
popViewport()