---
title: "A Very Merry Christmas"
date: 2023-12-08
categories: [fun, code, visualisation]
#image:
description: "Ho, Ho, Ho"
---
This figure was made using `ggplot2` and while I can't take credit for coming up with the idea ([ source ](https://t-redactyl.io/blog/2016/12/a-very-ggplot2-christmas.html "https://t-redactyl.io/blog/2016/12/a-very-ggplot2-christmas.html") {style="color: #1f7de6"}), I have added a couple of flourishes including the animated lights.
I hope everyone has a safe, happy and enjoyable holiday period.
```{r}
#| warning: false
#| message: false
library (ggplot2)
library (gganimate)
library (gifski)
library (extrafont)
loadfonts ()
# Read in the base Christmas tree data
ChristmasTree <- read.csv ("https://raw.githubusercontent.com/t-redactyl/Blog-posts/master/Christmas%20tree%20base%20data.csv" )
# Change tree colour
ChristmasTree$ Tree.Colour[ChristmasTree$ Tree.Colour == "#143306" ] <- "green4"
# Generate the "lights"
Desired.Lights <- 100
Total.Lights <- sum (round (Desired.Lights * 0.35 ) + round (Desired.Lights * 0.20 ) +
round (Desired.Lights * 0.17 ) + round (Desired.Lights * 0.13 ) +
round (Desired.Lights * 0.10 ) + round (Desired.Lights * 0.05 ))
Lights <- data.frame (Lights.X = c (round (runif (round (Desired.Lights * 0.35 ), 4 , 18 ), 0 ),
round (runif (round (Desired.Lights * 0.20 ), 5 , 17 ), 0 ),
round (runif (round (Desired.Lights * 0.17 ), 6 , 16 ), 0 ),
round (runif (round (Desired.Lights * 0.13 ), 7 , 15 ), 0 ),
round (runif (round (Desired.Lights * 0.10 ), 8 , 14 ), 0 ),
round (runif (round (Desired.Lights * 0.05 ), 10 , 12 ), 0 )))
Lights$ Lights.Y <- c (round (runif (round (Desired.Lights * 0.35 ), 4 , 6 ), 0 ),
round (runif (round (Desired.Lights * 0.20 ), 7 , 8 ), 0 ),
round (runif (round (Desired.Lights * 0.17 ), 9 , 10 ), 0 ),
round (runif (round (Desired.Lights * 0.13 ), 11 , 12 ), 0 ),
round (runif (round (Desired.Lights * 0.10 ), 13 , 14 ), 0 ),
round (runif (round (Desired.Lights * 0.05 ), 15 , 17 ), 0 ))
Lights$ Lights.Colour <- c (round (runif (Total.Lights, 1 , 3 ), 0 ))
# Generate the "baubles"
Baubles <- data.frame (Bauble.X = c (6 , 9 , 15 , 17 , 5 , 13 , 16 , 7 , 10 , 14 , 7 , 9 , 11 , 14 , 8 , 14 , 9 , 12 , 11 , 12 , 14 , 11 , 17 , 10 ))
Baubles$ Bauble.Y <- c (4 , 5 , 4 , 4 , 5 , 5 , 5 , 6 , 6 , 6 , 8 , 8 , 8 , 8 , 10 , 10 , 11 , 11 , 12 , 13 , 10 , 16 , 7 , 14 )
Baubles$ Bauble.Colour <- factor (c (1 , 2 , 2 , 3 , 2 , 3 , 1 , 3 , 1 , 1 , 1 , 2 , 1 , 2 , 3 , 3 , 2 , 1 , 3 , 2 , 1 , 3 , 3 , 1 ))
Baubles$ Bauble.Size <- c (6 , 18 , 6 , 6 , 12 , 6 , 12 , 12 , 12 , 6 , 6 , 6 , 18 , 18 , 18 , 12 , 18 , 6 , 6 , 12 , 12 , 18 , 18 , 12 )
# Generate the plot
p <- ggplot () +
geom_tile (data = ChristmasTree, aes (x = Tree.X, y = Tree.Y, fill = Tree.Colour)) +
scale_fill_identity () +
geom_point (data = Lights, aes (x = Lights.X, y = Lights.Y), color = "lightgoldenrodyellow" , shape = 8 ) +
geom_point (data = Baubles, aes (x = Bauble.X, y = Bauble.Y, colour = Bauble.Colour), size = Baubles$ Bauble.Size, shape = 16 ) +
scale_colour_manual (values = c ("firebrick2" , "gold" , "blue3" )) +
scale_size_area (max_size = 12 ) +
theme_bw () +
scale_x_continuous (breaks = NULL ) +
scale_y_continuous (breaks = NULL ) +
geom_segment (aes (x = 2.5 , xend = 4.5 , y = 1.5 , yend = 1.5 ), colour = "blueviolet" , size = 2 ) +
geom_segment (aes (x = 5.5 , xend = 8.5 , y = 1.5 , yend = 1.5 ), colour = "dodgerblue3" , size = 2 ) +
geom_segment (aes (x = 13.5 , xend = 16.5 , y = 1.5 , yend = 1.5 ), colour = "blueviolet" , size = 2 ) +
geom_segment (aes (x = 17.5 , xend = 19.5 , y = 1.5 , yend = 1.5 ), colour = "dodgerblue3" , size = 2 ) +
geom_segment (aes (x = 3.5 , xend = 3.5 , y = 0.5 , yend = 2.5 ), colour = "blueviolet" , size = 2 ) +
geom_segment (aes (x = 7.0 , xend = 7.0 , y = 0.5 , yend = 2.5 ), colour = "dodgerblue3" , size = 2 ) +
geom_segment (aes (x = 15.0 , xend = 15.0 , y = 0.5 , yend = 2.5 ), colour = "blueviolet" , size = 2 ) +
geom_segment (aes (x = 18.5 , xend = 18.5 , y = 0.5 , yend = 2.5 ), colour = "dodgerblue3" , size = 2 ) +
annotate ("text" , x = 11 , y = 20 , label = "Merry Christmas!" ,family = "Luminari" , color = "white" , size = 12 ) +
transition_states (states= Lights.Colour, transition_length = 0 , state_length = 0.0001 ) +
labs (x = "" , y = "" ) +
theme (legend.position = "none" ) +
theme (panel.background = element_rect (fill = 'midnightblue' , colour = "yellow" ))
# Animate
animate (p, nframe = 20 , fps = 20 )
```