I am doing some time series clustering, and would like to align the dendrogram with the time series shapes. This is almost there:
library(ggplot2)
library(reshape2)
library(stats)
library(patchwork)
library(ggdendro) # Added ggdendro library
# ---- Example data: 4 time series ----
set.seed(1)
time <- 1:50
data <- data.frame(
time = time,
A = cumsum(rnorm(50, 0, 1)),
B = cumsum(rnorm(50, 0, 1)),
C = cumsum(rnorm(50, 0.2, 1)),
D = cumsum(rnorm(50, -0.2, 1))
)
# Melt to long format for ggplot
df_long <- melt(data, id.vars = "time", variable.name = "series", value.name = "value")
# ---- Dendrogram (right panel) ----
# Compute hierarchical clustering on series
mat <- t(as.matrix(data[ , -1])) # series as rows
d <- dist(mat)
hc <- hclust(d)
# Convert dendrogram to a ggplot-friendly format and adjust orientation
# We'll create the dendrogram first so we can order the time series plots accordingly
dendro_plot <- ggdendrogram(hc, rotate = TRUE, theme_dendro = FALSE) +
scale_x_reverse() + # Reverse the x-axis to put leaves on the left
theme_minimal() +
theme(axis.text.y = element_blank(), axis.ticks.y = element_blank(), # Remove y-axis labels and ticks on dendrogram
plot.margin = margin(t = 0, r = 0, b = 0, l = 0)) # Adjust margins
# Reorder the data based on dendrogram order
ordered_series <- hc$labels[hc$order]
df_long$series <- factor(df_long$series, levels = ordered_series, ordered = TRUE)
# ---- Time series plots (left panel) ----
# Create a single ggplot object with facets for each series, ordered by the dendrogram
time_series_plot <- ggplot(df_long, aes(x = time, y = value)) +
geom_line(linewidth = 1) +
geom_hline(yintercept = 0, linetype="dashed") +
facet_grid(series ~ ., switch = "y") + # Facet by series with free y-scales and y-axis on the left
theme_minimal() +
labs(x = "Time", y = "Value") +
theme(axis.text.y = element_blank(), axis.ticks.y = element_blank(), # Remove y-axis labels and ticks on individual facets
axis.title.y = element_blank(), # Remove overall y-axis title
strip.text.y.left = element_text(angle = 0), # Orient facet labels horizontally on the left
panel.spacing.y = unit(0.1, "lines"), # Reduce space between facets
plot.margin = margin(t = 0, r = 0, b = 0, l = 0)) # Adjust margins
# ---- Combine ----
time_series_plot + dendro_plot + plot_layout(widths = c(3, 1), heights = unit(1,"null")) # Use heights = unit(1,"null") to make them proportional
Is there some easier way to do this that I'm just missing?


