Chrismas is coming and you might ask yourself a question: Can I draw a Christmas tree in R? Well, at least I asked this question and not surprisingly the answer is yes. Here is my tip how to do it with just couple of lines of code:

For graphics we will use the brilliant ggplot2 package together with ggthemes, which is a nice set of presets for ggplot charts. In order to make R draw a tree we need some mathematical function that generates tree-like shape. Choice is really wide here and you can go crazy with complicated compound functions that will resemble a perfect Christmas tree shape. However I decided to stay basic and use a sinus function combined with absolute value:  f(x) = x * abs(sin(x)).  Now we can generate some random data points and run them through the function. It takes a little bit of trial and error to figure out right range and signs of the data, but once have it we can plot the data with ggplot and voila!

 

library(ggplot2)

x <- sort(runif(3000,-25,0), decreasing = TRUE)
y <- c(rep(runif(3000,-25,25)))
z <- func(x)

tree_data <- cbind(x, y, z)  
tree_df <- as.data.frame(subset(tree_data, abs(tree_data[,2]) <= abs(tree_data[,3])))

ggplot(tree_df, aes(x = x, y = y)) + 
  xlim(-25,0) + 
  ylim(-30,30) + 
  coord_flip() + 
  geom_line(color="green")

basic xmas tree

Not a bad result for just 11 simple lines of code. However I think it needs little bit of polishing. Most importantly the tree needs star on top and some nice decorations. Then we can add some nice to have features, such as colors we like the most, clean background and Xmas wishes. The end result can look like this:

library(ggplot2)
library(ggthemes)

func <- function(x){ return(x*abs(sin(x)))}

x <- sort(runif(15000,-25,0), decreasing = TRUE)
y <- c(rep(runif(15000,-25,25)))
z <- func(x)
  
tree_data <- cbind(x, y, z)  
tree_df <- as.data.frame(subset(tree_data, abs(tree_data[,2]) <= abs(tree_data[,3])))

decor1 <- tree_df[sample(1:nrow(tree_df), 40,replace=FALSE),]
decor2 <- tree_df[sample(1:nrow(tree_df), 30,replace=FALSE),]
decor3 <- tree_df[sample(1:nrow(tree_df), 20,replace=FALSE),]

decor1 <- as.data.frame(decor1)
decor2 <- as.data.frame(decor2)
decor3 <- as.data.frame(decor3)

tree <- ggplot(tree_df, aes(x = x, y = y)) + 
  xlim(-25,0) + 
  ylim(-30,30) + 
  coord_flip() + 
  theme_tufte((base_size = 18)) + 
  geom_point(x=0,y=0, size=8, color="goldenrod2",shape=8, lwd=2,fill="goldenrod2")+ 
  geom_point(color="chartreuse4", size=4,shape=1, alpha=0.25,position=position_jitter(width=.7,height=.7)) + 
  geom_point(data=decor1, color="lightsalmon2", size=3,shape=16,  alpha=0.7,position=position_jitter(width=2,height=2)) + 
  geom_point(data=decor2, color="lightblue4", size=5,shape=16,  alpha=0.7,position=position_jitter(width=1,height=1)) + 
  geom_point(data=decor3, color="plum3", size=7,shape=16,  alpha=0.6,position=position_jitter(width=1,height=1)) + 
  theme(legend.position="none") + 
  labs(x="PF 2019", y="") + 
  scale_y_continuous(breaks=c(-20, 0, 20),labels=c("Happy", "New", "Year")) + 
  theme(axis.ticks = element_blank(), axis.text.y = element_blank()) + 
  theme(axis.title.y = element_text(vjust=-7,size=25)) + 
  theme(text=element_text(size=16, family="Caviar Dreams"))

tree

Fancy xmas tree

 

I like it this way, so I am happy with this Christmas tree. Also I like the fact that every time you run the code, tree is little bit different thanks to the randomness present in the data. You can easily tweak the code and come up with your own version of the Christmas tree. Start experimenting with different text, colors, point shapes, more decorations etc. If you are a real die hard R enthusiast, I have also Xmas challenge for you: Can you figure out a way how to add presents under the tree? Please let us know if you manage to add them!

Christmas trees aside, this was in my opinion nice exercise that illustrates the freedom that gives you the ggplot2 graphic library. Its beauty is that you are allowed to modify each element of the chart endlessly. Enjoy your charting and holiday season. MeRRy Christmas.