Saya memiliki empat plot animasi dengan jumlah bingkai yang sama, di mana saya ingin tiga ditumpuk dan yang keempat di sebelah kanan dari tiga animasi bertumpuk. Biasanya saya akan menggunakan sesuatu seperti grid.arrange, tetapi itu sepertinya tidak bekerja dengan gganimate.

Saya mendapatkan potongan kode berikut berdasarkan kode dari sini: https://github.com /thomasp85/gganimate/wiki/Animation-Composition

a_mgif <- image_read(a_gif)
b_mgif <- image_read(b_gif)
c_mgif <- image_read(c_gif)
d_mgif <- image_read(d_gif)

new_gif <- image_append(c(a_mgif[1], b_mgif[1], c_mgif[1], d_mgif[1]), stack = TRUE)

for(i in 2:100){
  combined <- image_append(c(a_mgif[i], b_mgif[i], c_mgif[i], d_mgif[i]), stack = TRUE)
  new_gif <- c(new_gif, combined)
}

magick::image_write(new_gif, path="animation.1.gif")

Ini berfungsi dengan baik dan menghasilkan empat plot animasi bertumpuk. Saya mencoba memodifikasinya untuk memiliki plot keempat di sebelah kanan dari tiga plot pertama yang ditumpuk sebagai berikut:

new_gif.1 <- image_append(c(a_mgif[1], b_mgif[1], c_mgif[1]), stack = TRUE)
new_gif.2 <- image_append(c(new_gif.1, d_mgif[1]), stack = FALSE)

for(i in 2:100){
  combined.1 <- image_append(c(a_mgif[i], b_mgif[i], c_mgif[i]), stack = TRUE)
  combined.2 <- image_append(c(combined.1, d_mgif[i]), stack = FALSE)
  new_gif.2 <- c(new_gif.2,combined.2)
}

magick::image_write(new_gif.2, path="animation.2.gif")

Ini sepertinya berhasil, sampai pada titik penulisan file. Butuh waktu lama untuk menulis file, saya membiarkannya berjalan berjam-jam dan masih belum selesai, sementara versi pertama di mana mereka semua ditumpuk ditulis dalam satu menit, jadi jelas ada yang salah. Ini persis data/plot yang sama di kedua contoh. Ada ide tentang apa yang salah di sini?

10
Abdel 20 Mei 2020, 11:54

1 menjawab

Jawaban Terbaik

Apa yang berhasil bagi saya adalah membungkus panggilan image_append menjadi image_flatten. Saya juga pertama-tama menggabungkan img1 dan img4 secara horizontal dan kemudian menumpuknya dengan img2 dan img3.

Di sini saya hanya mendaur ulang dua animasi dari contoh, tetapi solusi ini juga harus bekerja dengan empat animasi independen - setidaknya bagi saya, pada R4.0 dengan ImageMagick 6.9.10.23 dan magick_2.3, meskipun dibutuhkan sekitar 3 menit dan mungkin 630 MB penyimpanan sementara:

library(dplyr)
library(ggplot2)
library(magick)
library(gganimate)

A <- rnorm(100,50,10)
B <- rnorm(100,50,10)
DV <- c(A,B)
IV <- rep(c("A","B"), each=100)
sims <- rep(rep(1:10, each=10), 2)
df <- data.frame(sims, IV, DV)

means_df <- df %>%
    group_by(sims,IV) %>%
    summarize(means=mean(DV),
              sem = sd(DV)/sqrt(length(DV)))

stats_df <- df %>%
    group_by(sims) %>%
    summarize(ts = t.test(DV~IV,var.equal=TRUE)$statistic)

a <- ggplot(means_df, aes(x = IV,y = means, fill = IV)) +
    geom_bar(stat = "identity") +
    geom_point(aes(x = IV, y = DV), data = df, alpha = .25) +
    geom_errorbar(aes(ymin = means - sem, ymax = means + sem), width = .2) +
    theme_classic() +
    transition_states(
        states = sims,
        transition_length = 2,
        state_length = 1
    ) + 
    enter_fade() + 
    exit_shrink() +
    ease_aes('sine-in-out')

a_gif <- animate(a, width = 240, height = 240)

b <- ggplot(stats_df, aes(x = ts))+
    geom_vline(aes(xintercept = ts, frame = sims))+
    geom_line(aes(x=x,y=y),
              data = data.frame(x = seq(-5,5, .1),
                                y = dt(seq(-5,5, .1), df = 18))) +
    theme_classic() +
    ylab("density") +
    xlab("t value") +
    transition_states(
        states = sims,
        transition_length = 2,
        state_length = 1
    ) +
    enter_fade() + 
    exit_shrink() +
    ease_aes('sine-in-out')

b_gif <- animate(b, width = 240, height = 240)

c_gif <- animate(b, width = 240, height = 240)
d_gif <- animate(a, width = 240, height = 240)

i=1
combined <- image_append(c(a_gif[i], d_gif[i]))
new_gif <- image_append(c(image_flatten(combined),
                          b_gif[i], c_gif[i]), stack=TRUE)

for(i in 2:100){
    combined <- image_append(c(a_gif[i], d_gif[i]))
    fullcombined <- image_append(c(image_flatten(combined), 
                                   b_gif[i], c_gif[i]), stack=TRUE)
    new_gif <- c(new_gif, fullcombined)
}

image_write(new_gif, format="gif", path="animation.2.gif")

Edit: Alternatif Atau, Anda bisa menggunakan cowplot untuk mengatur plot dan menghasilkan frame individu dalam satu lingkaran dan kemudian menggunakan gifski untuk membuat animasi; yang bahkan lebih fleksibel dalam hal penempatan gambar, karena Anda dapat menambahkan koordinat ke draw_image (lihat contoh cowplot yang sesuai). Di bawah ini adalah contoh kisi sederhana:

library(dplyr)
library(ggplot2)
library(magick)
library(gganimate)
library(cowplot)
library(gifski)

A <- rnorm(100,50,10)
B <- rnorm(100,50,10)
DV <- c(A,B)
IV <- rep(c("A","B"), each=100)
sims <- rep(rep(1:10, each=10), 2)
df <- data.frame(sims, IV, DV)

means_df <- df %>%
    group_by(sims,IV) %>%
    summarize(means=mean(DV),
              sem = sd(DV)/sqrt(length(DV)))

stats_df <- df %>%
    group_by(sims) %>%
    summarize(ts = t.test(DV~IV,var.equal=TRUE)$statistic)

a <- ggplot(means_df, aes(x = IV,y = means, fill = IV)) +
    geom_bar(stat = "identity") +
    geom_point(aes(x = IV, y = DV), data = df, alpha = .25) +
    geom_errorbar(aes(ymin = means - sem, ymax = means + sem), width = .2) +
    theme_classic() +
    transition_states(
        states = sims,
        transition_length = 2,
        state_length = 1
    ) + 
    enter_fade() + 
    exit_shrink() +
    ease_aes('sine-in-out')

a_gif <- animate(a, width = 240, height = 240)

b <- ggplot(stats_df, aes(x = ts))+
    geom_vline(aes(xintercept = ts, frame = sims))+
    geom_line(aes(x=x,y=y),
              data = data.frame(x = seq(-5,5, .1),
                                y = dt(seq(-5,5, .1), df = 18))) +
    theme_classic() +
    ylab("density") +
    xlab("t value") +
    transition_states(
        states = sims,
        transition_length = 2,
        state_length = 1
    ) +
    enter_fade() + 
    exit_shrink() +
    ease_aes('sine-in-out')

b_gif <- animate(b, width = 240, height = 240)

c_gif <- animate(b, width = 240, height = 240)
d_gif <- animate(a, width = 240, height = 240)

tdir <- tempdir()
for(i in 1:100){
    new_gif <- plot_grid(ggdraw() + draw_image(a_gif[i], scale = 0.9), 
                         ggdraw() + draw_image(d_gif[i], scale = 0.9),
                         ggdraw() + draw_image(b_gif[i], scale = 0.9),
                         ggdraw(),
                         ggdraw() + draw_image(c_gif[i], scale = 0.9),
                         ncol=2)
    ggsave(
        filename = file.path(tdir, paste0("out_", sprintf("%03d", i), ".png")),
        plot = new_gif, width = 2.4, height = 3.6, device = "png")
}

png_files <- sort(list.files(path = tdir, pattern = "out_", full.names = TRUE))
gifski(png_files, gif_file = "out.gif", width = 480, height = 720, delay = .1,
       progress = TRUE)
5
user12728748 1 Juni 2020, 11:54