Округление frame_time и плавные переходы для gganimate - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть следующий фрейм данных:

# Seed RNG
set.seed(33550336)

# Create data frame
df <- data.frame(x = runif(100), 
                 y = runif(100), 
                 t = runif(100, min = 0, max = 10))

Я бы хотел построить точки (т.е. в x и y координаты), появляющиеся и исчезающие как функция t. gganimate круто, так что я использовал это.

# Load libraries
library(gganimate)
library(ggplot2)

# Create animation
g <- ggplot(df, aes(x = x, y = y))
g <- g + geom_point(colour = "#FF3300", shape = 19, size = 5, alpha = 0.25)
g <- g + labs(title = 'Time: {frame_time}')
g <- g + transition_time(t)
g <- g + enter_fade() + exit_fade()
animate(g, fps = 1)

Этот код выдает следующее:

enter image description here

Есть пара вещей, которые мне не нравятся в этом.

  1. Переходы очень резкие. Я надеялся, используя enter_fade и exit_fade, что точки исчезнут, а затем отступят. Ясно, что это не так, но как будет Я достигну этого результата?
  2. Я бы хотел округлить {frame_time}, чтобы, в то время как точки увеличивались и уменьшались с долями t, фактическое время t, которое было бы показано, было бы целым числом. Если бы frame_time была обычной переменной, это было бы достаточно просто, используя что-то вроде bquote и round, но, похоже, это не так. Как я могу округлить frame_time в моем названии?

1 Ответ

0 голосов
/ 13 ноября 2018

Это сравнительно ручной подход, который основывается на предварительной подготовке большего количества и подаче этого в gganimate. Я хотел бы посмотреть, есть ли более простой способ сделать это внутри gganimate более автоматически.

Сначала я делаю копию кадра данных для каждого кадра, который я хочу показать. Затем я вычисляю разницу между временем, которое я сейчас просматриваю (time), и t, когда я хочу показать каждую точку данных. Я использую cos, чтобы справиться с замедлением, чтобы появление каждой точки в данный момент времени описывалось display. В вызове ggplot я затем отображаю альфа и размер на display и использую transition_time(time) для перемещения по кадрам.

# Create prep table
fade_time = 1
frame_count = 100
frames_per_time = 10
df2 <- map_df(seq_len(frame_count), ~df, .id = "time") %>%
  mutate(time = as.numeric(time)/frames_per_time,
         delta_norm = (t - time) / fade_time,
         display = if_else(abs(delta_norm) > 1, 0, cos(pi / 2 * delta_norm)))


# Create animation
g <- ggplot(df2, aes(x = x, y = y, alpha = display, size = display))
g <- g + geom_point(colour = "#FF3300", shape = 19)
g <- g + scale_alpha(range = c(0, 1)) + scale_size_area(max_size = 5)
g <- g + labs(title = "{round(frame_time, 1)}") 
g <- g + transition_time(time)
animate(g)

enter image description here

...