Create Heatmap and Line Plot in ggplot2 to Visualize Sunspot Activities

In this work, we’ll use ggplot2 to create a heatmap and a synchronized line plot to visualize the sunspot activities in the past ~270 years. Major techniques covered in this work include:


Packages and data cleanup

The dataset sunspot.month we use in this work is built in base R。

library(ggplot2)library(dplyr)library(tidyr)library(TSstudio)  # to work with time series typelibrary(patchwork) # combine plots together
# data cleanupsunspot.month.tidy <- sunspot.month %>% ts_reshape() %>% # convert the time series to "data.frame" format as_tibble() %>% # convert "data.frame" to "tibble" format # restructure the dataset to a tidy format pivot_longer(-month, values_to = "activity", names_to = "year")
head(sunspot.month.tidy, 4)

Output:

# A tibble: 4 × 3
month year activity
<dbl> <chr> <dbl>
1 1 1749 58
2 1 1750 73.3
3 1 1751 70
4 1 1752 35

Visualization

Set up the default theme. This ensures that both the heatmap and the line plot will be created in the same style.

theme_set(  theme_light(base_size = 13) +    theme(panel.border = element_blank(),          panel.grid = element_blank(),          panel.background = element_rect(fill = "black"),          plot.background = element_rect(fill = "black", color = NA),          legend.background = element_rect(fill = "black"),          text = element_text(color = "lightyellow"),          axis.text = element_text(color = "lightyellow")))

Create a heatmap showing the monthly sun spot activity from 1750 to 2000s.

p.heatmap <- sunspot.month.tidy %>%   ggplot(aes(x = month, y = year,              fill = activity)) +  geom_raster() +  scale_y_discrete(breaks = seq(1750, 2010, 50)) +  scale_x_continuous(breaks = seq(1, 12, 1)) +  scale_fill_viridis_c(option = "B", begin = .1) +   coord_cartesian(expand = 0)
p.heatmap


Create a line plot showing the monthly sun spot activity. Here We first reorder the rows in chronological order, and then use geom_path() to connect the dots of observations (rows) in order of their appearance in the dataset. In addition, mapping the color aesthetic to the activity variable renders a line with gradient color change.

p.line <- sunspot.month.tidy %>%  # define the order of observations to be connected into a line  arrange(year, month) %>%   ggplot(aes(x = year, y = activity,              color = activity)) +    # connect observations in order of appearance in data  geom_path(aes(group = 1)) +     coord_flip(expand = 0) +  scale_color_viridis_c(option = "B", begin = .1) +  theme(axis.title.y = element_blank(),        axis.text.y = element_blank(),        axis.ticks.y = element_blank()) +  labs(y = "activity") +  guides(    color = guide_colorbar(      barheight = unit(200, "pt"),       barwidth = unit(10, "pt"),       title = NULL)) 
p.line


Combine the heatmap and line plot together using the patchwork package.

p.combined <- (p.heatmap + theme(legend.position = "none")) +   p.line +  # relative width of the two plots  plot_layout(widths = c(3, 2)) +    # add plot title  plot_annotation(    title = "Sunspot Activities 1740 ~ 2013",    theme = theme(plot.title = element_text(      hjust = .5, face = "bold", size = 15, margin = margin(t = 5))))
p.combined


Save the plot.

ggsave(filename = "heatmap_sunspot_activities.pdf",       path = "graphics", # a relative path       width = 7, height = 7)
### Packages and data cleanuplibrary(ggplot2)library(dplyr)library(tidyr)library(TSstudio) # to work with time series typelibrary(patchwork) # combine plots together
# data cleanupsunspot.month.tidy <- sunspot.month %>% ts_reshape() %>% as_tibble() %>% pivot_longer( -month, values_to = "activity", names_to = "year")
head(sunspot.month.tidy, 30)

# global themetheme_set(theme_light(base_size = 13) + theme(panel.border = element_blank(), panel.grid = element_blank(), panel.background = element_rect(fill = "black"), plot.background = element_rect(fill = "black", color = NA), legend.background = element_rect(fill = "black"), text = element_text(color = "lightyellow"), axis.text = element_text(color = "lightyellow")))

# Create a heatmap showing the monthly sun spot activity from 1750 to 2000s. p.heatmap <- sunspot.month.tidy %>% ggplot(aes(x = month, y = year, fill = activity)) + geom_raster() + scale_y_discrete(breaks = seq(1750, 2010, 50)) + scale_x_continuous(breaks = seq(1, 12, 1)) + scale_fill_viridis_c(option = "B", begin = .1) + coord_cartesian(expand = 0)
p.heatmap

# Create a line plot.p.line <- sunspot.month.tidy %>% # define the order of observations to be connected into a line arrange(year, month) %>% ggplot(aes(x = year, y = activity, color = activity)) + # connect observations in order of appearance in data geom_path(aes(group = 1)) + coord_flip(expand = 0) + scale_color_viridis_c(option = "B", begin = .1) + theme(axis.title.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank()) + labs(y = "activity") + guides( color = guide_colorbar( barheight = unit(200, "pt"), barwidth = unit(10, "pt"), title = NULL))
p.line
# Combine the heatmap and line plot together.(p.heatmap + theme(legend.position = "none")) + p.line + # relative width of the two plots plot_layout(widths = c(3, 2)) + # add plot title of the combined graphic plot_annotation( title = "Sunspot Activities 1740 ~ 2013", theme = theme(plot.title = element_text( hjust = .5, face = "bold", size = 15, margin = margin(t = 5))))

# Save the plot. ggsave(filename = "heatmap_sunspot_activities.pdf", path = "graphics", # a relative path width = 7, height = 7)




Continue Exploring — 🚀 one level up!


Check out these beautiful heatmaps showing the disease incidences before and after the vaccine introduction throughout the U.S. history.



And check out this amazing heatmap visualizing the population distribution in Africa. In particular, it leverages magical mathematical transformations in the color scale (with a simple line of code) to unveil the underlying highly skewed data pattern.



All above heatmaps are generated using the generic function geom_tile() or geom_raster(). Alternatively, a heatmap can be created in the form of a 2D histogram using geom_bin2d() – check out the following awesome 2D histogram with a world map overlay that visualizes the hurricane activities in North Atlantic Ocean.