Create Stacked Density Plots in ggplot2 to Visualize Sunsplot Activities

In this article, we’ll leverage the ggridges package by Claus O. Wilke to visualize the sunspot activities using a list of density plots stacked in chronological order.


Packages and data cleanup

The dataset sunspot.month (time series) used is built-in base R.

library(ggplot2)library(dplyr)library(tidyr)library(TSstudio) # transform time series datalibrary(ggridges) # draw stacked density plots
s <- sunspot.month %>% # convert time series to data.frame ts_reshape() %>% # tidy up pivot_longer(-month, names_to = "year", values_to = "activity") %>% mutate(year = as.integer(year)) %>% filter(year %in% seq(1750, 2010, 2))
head(s, n = 3)

Output:

# A tibble: 3 × 3
month year activity
<dbl> <int> <dbl>
1 1 1750 73.3
2 1 1752 35
3 1 1754 0

Visualization

Create a list of stacked density plots.

p1 <- s %>%   ggplot(aes(x = activity, y = year, fill = after_stat(x))) +  # create density plots in stacked manner  geom_density_ridges_gradient(    aes(group = year), scale = 8, color = "white")p1

Adjust the color scale, axis scale, and titles.

p2 <- p1 +  scale_fill_viridis_c(option = "C") +  scale_y_continuous(breaks = seq(1750, 2010, 10), name = NULL) +  coord_cartesian(xlim = c(0, NA), expand = 0) +  labs(x = "Activity intensity") +  # add plot title  annotate(    geom = "text", x = 220, y = 1790,    label = "Sunspot\n yearly\n activity\n distribution\n\n1740 ~ 2013",     fontface = "bold", size = 4, color = "tomato3")p2

A final fine-tune of the theme.

p3 <- p2 +  theme_classic() +  theme(panel.grid = element_blank(),        axis.line = element_blank(),        legend.position = "none",        axis.ticks.y = element_line(color = "snow2"),        axis.text.y = element_text(margin = margin(r = 10)),        axis.title.x = element_text(margin = margin(t = 10))) p3
library(ggplot2)library(dplyr)library(tidyr)library(TSstudio) # transform time series datalibrary(ggridges) # draw stacked density plots
s <- sunspot.month %>% # convert time series to data.frame ts_reshape() %>% # tidy up pivot_longer(-month, names_to = "year", values_to = "activity") %>% mutate(year = as.integer(year)) %>% filter(year %in% seq(1750, 2010, 2))
head(s, n = 3) # ready for visualization!

# Create a list of stacked density plots. p1 <- s %>% ggplot(aes(x = activity, y = year, fill = after_stat(x))) + # create density plots in stacked manner geom_density_ridges_gradient( aes(group = year), scale = 8, color = "white")p1

# Adjust the color scale, axis scale, and titles. p2 <- p1 + scale_fill_viridis_c(option = "C") + scale_y_continuous(breaks = seq(1750, 2010, 10), name = NULL) + coord_cartesian(xlim = c(0, NA), expand = 0) + labs(x = "Activity intensity") + # add plot title annotate( geom = "text", x = 220, y = 1790, label = "Sunspot\n yearly\n activity\n distribution\n\n1740 ~ 2013", fontface = "bold", size = 4, color = "tomato3")p2

# A final fine-tune of the theme. p3 <- p2 + theme_classic() + theme(panel.grid = element_blank(), axis.line = element_blank(), legend.position = "none", axis.ticks.y = element_line(color = "snow2"), axis.text.y = element_text(margin = margin(r = 10)), axis.title.x = element_text(margin = margin(t = 10))) p3




Continue Exploring — 🚀 one level up!


In addition to the density plots, we can alternatively visualize the sunspot activities using a heatmap. In the following article, we’ll combine the heatmap with a line plot synchronized in position to vividly visualize the sunspot activities.



To visualize complicated chronological data like the sunspot activities, in addition to the density plot, heatmaps and line plot, animation is another powerful approach. Check out the following annual population pyramids in animation that vividly unveils the predicted changing dynamics in the population structure in Germany.