I am trying to summarize the Pearson correlation index between x and y per facet (grouping) z and per frame by transition_filter
data.frame(x = runif(300), y = runif(300), z = runif(300), g = rep(c("a", "b", "c"), each = 100)) %>%
ggplot(aes(x = x, y = y, color = z)) + geom_point() +
facet_wrap(. ~ g) +
transition_filter(transition_length = 1, filter_length = 1,
z >= 0.5 & z < 0.6,
z >= 0.6 & z < 0.7,
z >= 0.7 & z < 0.8,
z >= 0.8 & z < 0.9,
z >= 0.9 & z < 1) +
geom_text(aes(label = paste0("Cor = ", cor(x, y))), x = 0.25, y = 1) +
ggtitle('{closest_expression}')
I can get the correlation indexes displayed though they appear to be the same across facets and frames:
What is the correct way of doing this?
This sounds like an ambitious case for gganimate, which I don't think is currently set up to do by-facet calculations per frame. (Curious to see if anyone else knows a way.) My go-to approach for showing unusual things with gganimate is to calculate what we want to show before sending to ggplot2.
df1 <- data.frame(x = runif(300), y = runif(300), z = runif(300),
g = rep(c("a", "b", "c"), each = 100)) |>
mutate(case = case_when(
z < 0.5 ~ NA,
.default = cut(z, seq(0.5, 1, 0.1))
))
df1_cor <- df1 |>
summarise(cor = cor(x, y), .by = c(case, g))
df1 |>
ggplot(aes(x = x, y = y)) +
geom_point(aes(color = z)) +
facet_wrap(. ~ g) +
transition_manual(case) +
geom_text(aes(label = scales::number(cor, accuracy = 0.0001)),
x = 0.25, y = 1, data = df1_cor) +
ggtitle('{current_frame}')
Per the OP comment about to deal with overlapping cases, we could use a similar approach. We can construct our cases, join the data to match all the observations that go with each case, and plot that.
df <- data.frame(x = runif(1000), y = runif(1000), f = runif(1000))
df2 <- data.frame(low = seq(0.51, 0.8, 0.01), high = seq(0.71, 1, 0.01)) |>
mutate(nice_name = paste0("Filter: f >= ", low, " & f < ", high)) |>
left_join(df, join_by(low <= f, high > f))
df2 |>
ggplot(aes(x = x, y = y)) +
geom_point(aes(color = f)) +
transition_manual(nice_name) +
ggtitle('{current_frame}')