2015-09-07 5 views
2

Im пытается использовать пакет caTools для объединения нескольких графиков в gif.объединить несколько графиков в gif

Мой основной код выглядит следующим образом:

 for(i in 1:100){ 
    plot(....) // plots few points and lines, changes slightly with each i 
    } 

Я хотел бы объединить эти в формате GIF, чтобы увидеть «эволюцию» сюжета.

Однако для write.gif() из caTools мне нужно предоставить изображение в качестве ввода. Для каждого I, как преобразовать сюжет в изображение без

  1. сохранения на диск в качестве промежуточной стадии
  2. в зависимости от ImageMagick или аналогичных внешних зависимостей.

Не стесняйтесь указывать, является ли это дубликат. [Creating a Movie from a Series of Plots in R, похоже, не отвечает на этот вопрос]

EDIT: В основном это требует от нас преобразования графика в матрицу. Поскольку это очень вероятно происходит каждый раз, когда кто-то спасает сюжет, это не должно быть очень сложно. Однако я не могу понять, как это сделать.

+0

Почему ограничение на использование внешнего программного обеспечения? – hrbrmstr

+0

Возможно, пакет '' gridBase'' или функция ''? Par'' могут помочь. – holzben

+0

@hrbrmstr в основном по соображениям переносимости – Sujay

ответ

4

Я предлагаю использовать animation пакет и ImageMagick вместо:

library(animation) 
## make sure ImageMagick has been installed in your system 
saveGIF({ 
    for (i in 1:10) plot(runif(10), ylim = 0:1) 
}) 

В противном случае вы можете попробовать его в жилах этого (много места для оптимизации):

library(png) 
library(caTools) 
library(abind) 

# create gif frames and write them to pngs in a temp dir 
dir.create(dir <- tempfile("")) 
for (i in 1:8) { 
    png(file.path(dir, paste0(sprintf("%04d", i), ".png"))) 
    plot(runif(10), ylim = 0:1, col = i) 
    dev.off() 
} 

# read pngs, create global palette, convert rasters to integer arrays and write animated gif 
imgs <- lapply(list.files(dir, full.names = T), function(fn) as.raster(readPNG(fn))) 
frames <- abind(imgs, along = 3) # combine raster pngs in list to an array 
cols <- unique(as.vector(frames)) # determine unique colors, should be less then 257 
frames <- aperm(array(match(frames, cols) - 1, dim = dim(frames)), c(2,1,3)) # replace rgb color codes (#ffffff) by integer indices in cols, beginning with 0 (note: array has to be transposed again, otherwise images are flipped) 
write.gif(
    image = frames, # array of integers 
    filename = tf <- tempfile(fileext = ".gif"), # create temporary filename 
    delay = 100, # 100/100=1 second delay between frames 
    col = c(cols, rep("#FFFFFF", 256-length(cols))) # color palette with 256 colors (fill unused color indices with white) 
) 

# open gif (windows) 
shell.exec(tf) 
+0

Я ищет решение без ImageMagick. – Sujay

+0

Проверьте другую возможность, используя черно-белые временные изображения. – lukeA

+0

Как сохранить исходный цвет, если я импортирую .png? @lukeA – Iris

1

Это то, что вы ищем?

library(ggplot2) 
    a <- 0:10 
    df <- data.frame(a=a,b=a) 
    steps <-function(end){ 
     a <- ggplot(df[1:end,], aes(a,b)) + 
     geom_point() + 
     scale_x_continuous(limits=c(0,10)) + 
     scale_y_continuous(limits=c(0,10)) 
     print(a) 
    } 
    gif <- function() { 
     lapply(seq(1,11,1), function(i) { 
     steps(i) 
     }) 
    } 
    library(animation) 
    saveGIF(gif(), interval = .2, movie.name="test.gif") 
+0

Я получаю сообщение об ошибке 'Ошибка in_dir (owd, expr): не удалось найти функцию trace.animate. Где определена ваша функция 'trace.animate()'? @ttlngr – Iris

+0

Извините @Iris, скопировал это из скрипта ... используйте функцию 'gif()' (как определено) вместо 'trace.animate()' в 'saveGIF()'. Отредактировал свой ответ уже. – ttlngr

+0

К сожалению, я столкнулся с этой ошибкой с ответом http://stackoverflow.com/questions/28142300/r-gif-animation-with-imagemagick – Iris

0

мне понравился ответ @ ttlngr, но я хотел что-то немного проще (он все еще использует ImageMagick).

saveGIF({ 
    for (i in 1:10){ 
    a <- ggplot(df[1:i,], aes(a,b)) + 
     geom_point() + 
     scale_x_continuous(limits=c(0,10)) + 
     scale_y_continuous(limits=c(0,10)) 
    print(a)} 
}, interval = .2, movie.name="test.gif") 
Смежные вопросы