Visualizing Time: How to Build a Yearly Calendar Heatmap in R
- Bernard Kilonzo

- Aug 25
- 2 min read

Overview
A Yearly Calendar Heatmap is a data visualization technique that maps daily values across an entire year onto a calendar-like grid, using color gradients to represent the magnitude or intensity of each data point. Each day is displayed as a cell within its corresponding month and week, allowing viewers to quickly identify patterns, trends, and anomalies over time. This format is especially effective for time-series data such as website traffic, energy usage, sales figures, or personal habits, where fluctuations across days, weeks, and seasons are important. By encoding numerical values as colors - typically with warmer tones indicating higher values and cooler tones indicating lower ones - the heatmap transforms raw data into an intuitive visual summary that highlights periods of peak activity, consistency, or irregularity.
In R, this type of visualization can be created using packages like ggplot2, calendR, or custom scripts that structure date-based data into calendar layouts, making it a valuable tool for both exploratory analysis and storytelling with data.
Step-by-Step Guide
Load libraries
# load libraries
library(tidyverse)
library(paletteer)
library(ggthemes)Load the data set
# load data set
superstore<-read.csv("https://raw.githubusercontent.com/bernardkilonzo-rigor/dataviz/main/data/Sample%20-%20Superstore.csv")Covert Order Date to a date object
# convert order date to a date object
superstore$Order.Date<-as.Date(superstore$Order.Date, format = "%d/%m/%Y")Compute the required fields (in this case; month, weekday, and week).
# Computing the required fields
superstore<-superstore%>%filter(year(Order.Date)==2020)%>%
mutate(month = month(Order.Date, label = TRUE),
weekday =wday(Order.Date, label = TRUE),
week = floor_date(Order.Date, unit = "week", week_start = 7))Compute the average discount by Order Date
# computing the average discount by order date
superstore_comp<-superstore%>%select(Order.Date,month,week,weekday,Sales,Discount)%>%
group_by(Order.Date,month,week,weekday)%>%
summarise(discount = mean(Discount))Create a heatmap calendar.
# creating heatmap calendar
superstore_comp%>%ggplot(aes(x = weekday, y = week, fill = discount))+geom_tile(color = "white")+facet_wrap(~month,scales = "free", ncol = 3)Executing the above code results to the view below.

Declutter the viz.
# creating heatmap calendar
superstore_comp%>%ggplot(aes(x = weekday, y = week, fill = discount))+geom_tile(color = "white")+facet_wrap(~month,scales = "free", ncol = 3)+
scale_fill_gradientn(colors = paletteer_c("ggthemes::Temperature Diverging", 30))+
labs(title = "Heatmap Calendar",caption = "Viz by: Bernard Kilonzo")+
theme(panel.background = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.title = element_blank(),
axis.text.x.bottom = element_text(family = "serif", size = 8, color = "gray30"),
axis.ticks.x = element_line(linewidth = 0.2, color = "gray35"),
axis.ticks.length.x = unit(0.05,"cm"),
legend.title = element_text(family = "serif", face="bold", size = 10, color = "gray25"),
legend.text = element_text(family = "serif", size = 9, color = "gray30"),
plot.title = element_text(family = "serif", face = "bold", color = "gray20", size = 13),
plot.caption = element_text(family = "serif", face = "italic", color = "gray35", size = 9))Executing the above code results to the view below.

Conclusion
Creating a yearly calendar heatmap in R using ggplot2 offers a visually compelling way to explore time-based data, uncover seasonal patterns, and communicate insights with clarity. By transforming daily values into a structured calendar format, this technique bridges the gap between raw data and intuitive storytelling. Whether you're tracking productivity, analyzing sales trends, or visualizing environmental metrics, calendar heatmaps provide a powerful lens through which to observe fluctuations across the year. With the flexibility of ggplot2 and the richness of R’s data manipulation tools, you can tailor these visualizations to suit any dataset or audience.
If you like the work we do and would like to work with us, drop us an email on our contacts page and we’ll reach out!
Thank you for reading!!
