Homage to the Square
Josef Albers
posit::conf(2023)
geom_rect()
Use arguments to map data to visual properties
xmin
, xmax
: minimum and maximum x
valuesymin
, ymax
: minimum and maximum y
valuesfill
: colorgeom_rect()
library(dplyr)
homage <- tribble(
~x0, ~y0, ~size, ~color,
0, 0, 10, "#5A9CBA",
1, 0.5, 8, "#919EA3",
2, 1, 6, "#F1EFDF",
3, 1.5, 4, "#F5BB1D"
) %>%
mutate(
x1 = x0 + size,
y1 = y0 + size
)
homage
# A tibble: 4 × 6
x0 y0 size color x1 y1
<dbl> <dbl> <dbl> <chr> <dbl> <dbl>
1 0 0 10 #5A9CBA 10 10
2 1 0.5 8 #919EA3 9 8.5
3 2 1 6 #F1EFDF 8 7
4 3 1.5 4 #F5BB1D 7 5.5
scale_fill_identity()
tells ggplot2 the variable in color
is a color value it can use directly, not a categorical variable that needs to be represented by a fill color
coord_fixed()
sets a fixed coordinate system, with an aspect ratio of 1, to ensure one unit on the x-axis is the same as one unit on the y-axis (aka: a square is a square)
theme_void()
is a completely empty theme, creating a blank canvas for us to work on
coord_fixed()
with expand = FALSE
removes any margin
“Generative art operates within a rule structure but has an element of chance that is crucial to what many artists enjoy about it. The final work is partly produced by an autonomous system, which may be strictly regulated by the rules or operate within parameters.”
— Charlotte Kent, Beyond the Janus-Faced Typologies of Art and Technology
make_homage <- function(colors = c("#5A9CBA", "#919EA3", "#F1EFDF", "#F5BB1D")) {
tribble(
~x0, ~y0, ~size,
0, 0, 10,
1, 0.5, 8,
2, 1, 6,
3, 1.5, 4
) %>%
mutate(
x1 = x0 + size,
y1 = y0 + size,
color = sample(colors, size = 4)
) %>%
ggplot() +
geom_rect(aes(
xmin = x0, xmax = x1,
ymin = y0, ymax = y1,
fill = color
)) +
scale_fill_identity() +
coord_fixed() +
theme_void()
}
set.seed()
Setting a seed controls the state of the random number generator in R
exercises/02-homage-to-the-square/exercise-1.Rmd
make_my_homage()
to take a seed
argument, and set the seed in the body of the functionmake_my_homage()
with the same seed
creates the same output, and that with a different seeds creates different outputs05:00
Deliberately simple and consistent in structure, the nested squares were a platform for exploring color.
Homages are all about mutability of color relationships and the malleability of subjective perceptions of colors.
An opaque but common format of representing color
“#5A9CBA” is one of the colors we used before - what is it?
How much red, green, and blue make up a color (0 to 255)
Color on the color wheel
(0 to 360)
Vividness, how much of the color is actually present
From grey to full saturation of the color (0% to 100%)
How light/bright the color is
From black to white (0% to 100%)
Desaturation generally makes things more interesting… compare to our palette in full saturation
# A tibble: 4 × 4
color h s l
<colors> <dbl> <dbl> <dbl>
1 #5A9CBAFF 199. 41.0 54.1
2 #919EA3FF 197. 8.91 60.4
3 #F1EFDFFF 53.3 39.1 91.0
4 #F5BB1DFF 43.9 91.5 53.7
Color in data visualization has constraints - representing distinct categories, accessibility
Color in art is different - what emotion are you trying to evoke? What are you trying to draw attention to? What period are you referencing?
How do you know what looks good?
Multiple tones of one color
“If one says ‘red’ (the name of a color) and there are 50 people listening, it can be expected that there will be 50 reds in their minds. And one can be sure that all these reds will be very different.”
— Josef Albers, Interaction of Color (1963)
Three colors side by side on the color wheel
That was a bit ugly - add contrast in other ways
Two colors on opposite sides of the color wheel
Having the same saturation and lightness doesn’t always work!
monochromatic_mini <- tribble(
~color,
mystery_color %>%
clr_lighten(shift = 0.75),
mystery_color
)
complementary <- bind_rows(
monochromatic_mini,
monochromatic_mini %>%
mutate(
color = clr_rotate(color,
degrees = 360 / 2
),
color = clr_desaturate(color,
shift = 0.5
)
)
)
plot(complementary[["color"]])
Having the same saturation and lightness doesn’t always work!
Three colors evenly spaced on the color wheel
exercises/02-homage-to-the-square/exercise-2.Rmd
make_my_homage()
to take your palette as the default value of the colors
argumentmake_my_homage()
with a few different seeds and pick your output10:00
10:00
geom_rect()
ggsave()
set.seed()
to control randomness