convert series of pdf-files to gif in R - r

So far I created several pngs in R and used ani.options and im.convert from the animation package to create a gif animation (ImageMagick is installed on Windows). It works without any problems:
`ani.options(nmax = 100, loop = 1, interval = 0.1)
for(i in 1:100){
name = rename(i)
png(name)
plot(...)
dev.off()
}
im.convert("*.png", output ="animation.gif", convert = c("convert"),
cmd.fun = if (.Platform$OS.type == "windows") shell else system,
extra.opts = "",clean = TRUE)`
Insead of png-files I would like to convert pdfs to a gif animation. Again I generated and saved several pdfs in a for-loop without any problems. The challenge is now to convert these pdfs to a gif-animation. I tried different approaches but I can't figure out how to modify the im.convert command and how to set ani.options parameters to combine the pdfs in a gif-animation.
So far, I tried setting ani.type and ani.dev to pdf and changed ".png" in im.convert to ".pdf".
I am gratefull for any suggestions.

I found the answer here:
Error using magick R to import PDF
After installing the 64-bit version of GhostScript it worked.

Related

Can I save my R output (.jpeg) to an FTP server?

(optional read) Greater Objective: PowerBI Web doesn't support a few R packages when published on the internet. It throws the below error ("Missing R Package"). Hence, I am working towards saving the output from R as an image (.jpeg) to a remote location (such as FTP) or cloud storage (secure and open source) and then import it to PowerBI. This workaround might resolve the package conflict (hoping).
Specific Objective*: The below code illustrates a trivial way of saving an R output(.jpeg) image locally. However, is there a way to save the image directly to the FTP server, provided I have the username/password etc? (unfortunately, I cannot share the server details)
library(outbreaks)
library(incidence)
cases = subset(nipah_malaysia, select = c("perak", "negeri_sembilan", "selangor",
"singapore"))
i = as.incidence(cases, dates = nipah_malaysia$date, interval = 7L)
jpeg(file = "plot.jpeg")
plot(i)
dev.off()
I did come across this post on employing ftpUpload function from the "rcurl" package. However, to upload it to FTP, I might still need to save it locally which defeats my purpose in this use-case.
Any suggestions would be helpful.
If saving a temporary file (as you suggested in a comment) is an option, then you can do that with the following code:
library(outbreaks)
library(incidence)
library(RCurl)
cases = subset(nipah_malaysia, select = c("perak", "negeri_sembilan", "selangor",
"singapore"))
i = as.incidence(cases, dates = nipah_malaysia$date, interval = 7L)
jpeg(file = filename <- tempfile())
plot(i)
dev.off()
ftpUpload(filename, "ftp://User:Password#FTPServer/destfile.jpeg")
If you're ok with having the output in PNG format (EDIT: I updated the code to show output to JPEG format) try the code below, with chunks borrowed from this answer that discusses how to save an image in memory:
EDIT: Updated to output to jpeg format
library(outbreaks)
library(incidence)
cases = subset(nipah_malaysia, select = c("perak", "negeri_sembilan", "selangor",
"singapore"))
orig_i = as.incidence(cases, dates = nipah_malaysia$date, interval = 7L)
plot(orig_i)
#### This section adapted from
#### https://stackoverflow.com/questions/7171523/in-r-how-to-plot-into-a-memory-buffer-instead-of-a-fileinstead-of-a-file
#### loads image data to memory rather than a file
library(Cairo)
library(png)
library(ggplot2)
Cairo(file='/dev/null')
plot(orig_i) #your plot
# hidden stuff in Cairo
i = Cairo:::.image(dev.cur())
r = Cairo:::.ptr.to.raw(i$ref, 0, i$width * i$height * 4)
dev.off()
dim(r) = c(4, i$width, i$height) # RGBA planes
# have to swap the red & blue components for some reason
r[c(1,3),,] = r[c(3,1),,]
# now use the jpeg library to write the raw vector
library(jpeg)
p = writeJPEG(r, raw()) # raw JPEG bytes
#DEBUGGING - check that this actually works
#Note: Windows 10 has an error that might report this as a file system error
#In windows, drag and drop the file into an open chrome window to see the image
writeBin(p, con= "yourpathhere/check_output.jpg")
#adapted code from #tfehring's example for the updload
library(RCurl)
ftpUpload(p, "ftp://User:Password#FTPServer/destfile.jpg")

Skimr - cant seem to produce the histograms

came across this seemingly new package - skimr, which looks pretty nifty, and was trying it out and looks like I'm missing some package installation. Skim works fine except that it doesn't print the histogram, it is supposed to print for numeric variables. I am merely trying the examples given in the documentation.
Link to skimr documentation here - https://github.com/ropenscilabs/skimr#skimr
this is the code I'm using
devtools::install_github("hadley/colformat")
devtools::install_github("ropenscilabs/skimr")
library(skimr)
a<-skim(mtcars)
dim(a)
View(a)
instead of histograms being printed, I see some ASCII/unicode characters .
A solution that can be used to workaround the above problem is to set the locale of the R system to Chinese and to set the font of the R console to NSimSun.
temp <- tempfile()
cat("font = NSimSun\n", file = temp, append = TRUE)
loadRconsole(file = temp)
Sys.setlocale( locale='Chinese' )
library(skimr)
(a <- skim(mtcars))
View(a)
In RStudio this solution works only partially. Histograms generated by skim can be visualized only using View after setting the locale of R to Chinese
Sys.setlocale( locale='Chinese' )
library(skimr)
a <- skim(mtcars)
View(a)
Hope this can help you.

Create a gif from a series of Leaflet maps in R

I am looking for an automated method to convert leaflet R Studio plots into image files.
Seems like exporting a leaflet widget to HTML is straightforward (Saving leaflet output as html). However I cannot find any answers or docs about how to save the image produced by a leaflet widget as an image. It seems strange that I can do this manually in R Studio but that there isn't some function within R Studio that can be called to do the same thing.
I've tried the usual suspects, variations on the following:
png("test_png.png")
map
dev.off()
But these all just print white or print a file that can't even be opened. IF I understand this Git discussion correctly, seems like something in leaflet is not available but is desired by users.
In the meantime, R Studio clearly has a way to render this image into an image file, making me press a button to do it. Is there a way to automate this? How can I export the images plotted in R Studio to image files? I need image files and I need this to be programmatic because I want to make a gif out of a few hundred maps.
Alternately, I'd welcome suggestions for a workaround. I might try this: Python - render HTML content to GIF image but if someone has alternatibve suggestions, please share.
I've been trying to do this with a combination of the webshot package and saveWidget from htmltools, although it's pretty slow. For a few hundred maps, it's probably not too bad if you're only doing it here and there. But, for real-time application it is too slow.
There are two external applications you need for this workflow. webshot takes screenshots of webpages and requires you to install PhantomJS first (it's tiny and easy). I also use ImageMagick (and needs to be accessible from the command line) to create the .gif files, but I'm sure there many other programs you could use to make gifs.
The idea is just to create the maps in a loop, save them to a temporary html file with saveWidget and use webshot to turn it into a png (slow). Then, once you have all the pngs, use ImageMagick to convert them to a gif (fast).
Here is an example, I also load ggmap, but only to get a location to zoom in on.
library(webshot)
library(leaflet)
library(htmlwidgets)
library(ggmap)
loc <- geocode('mt everest') # zoom in everest
zooms <- seq(2,14,3) # some zoom levels to animate
## Make the maps, this will make some pngs called 'Rplot%02d.png'
## in your current directory
for (i in seq_along(zooms)) {
m <- leaflet(data=loc) %>%
addProviderTiles('Esri.WorldImagery') %>%
setView(lng=loc$lon, lat=loc$lat, zoom=zooms[i])
if (i==1)
m <- m %>% addPopups(popup="Going to see Mt Everest")
if (i==length(zooms))
m <- m %>%
addCircleMarkers(radius=90, opacity = 0.5) %>%
addPopups(popup = 'Mt Everest')
## This is the png creation part
saveWidget(m, 'temp.html', selfcontained = FALSE)
webshot('temp.html', file=sprintf('Rplot%02d.png', i),
cliprect = 'viewport')
}
Then, it is just converting pngs to gif. I did this on a Windows, so command might be slightly different on a mac/linux (I think just single quotes instead of double quotes or something). These commands are from a command line/shell, but you could also use system/system2 to call from R or try the animation package that has some wrapper functions for ImageMagick. To make a simle gif with nothing fancy is simply, convert *.png animation.gif. I used a slightly longer code to make the pngs smaller/add some delays/and have the sequence go in and out.
convert Rplot%02d.png[1-5] -duplicate 1,-2-1, -resize "%50" gif:- | convert - -set delay "%[fx:(t==0||t==4)?240:40]" -quiet -layers OptimizePlus -loop 0 cycle.gif
You can create a series of PNG files as answered by jenesaisquoi (first answer). Then create gif with the png files using the below code with magick package.
library(magick)
png.files <- sprintf("Rplot%02d.png", 1:20) #Mention the number of files to read
GIF.convert <- function(x, output = "animation.gif")#Create a function to read, animate and convert the files to gif
{
image_read(x) %>%
image_animate(fps = 1) %>%
image_write(output)
}
GIF.convert(png.files)
You don't require to install ImageMagick software on PC.
Code Link: Animation.R
I have table with 3 columns: lat,lon,day (376 days).
The process is: create the map -> save the map as HTML -> save the map as PNG -> import the pic -> plot it (with plot + ggimage)
All this process, will be in a loop
library(leaflet)
library(animation)
library(png)
library(htmlwidgets)
library(webshot)
library(ggmap)
saveGIF({
for (i in 1:376) {
map = leaflet() %>%
addTiles() %>%
setView(lng = lon_lat[1,2], lat = lon_lat[1,1], zoom = 5)%>%
addMarkers(lng = lon_lat[lon_lat$day == i,2],lat = lon_lat[lon_lat$day == i,1])
saveWidget(map, 'temp.html', selfcontained = FALSE) ## save the html
webshot('temp.html', file=sprintf('Rplot%02d.png', 1),cliprect = 'viewport') ## save as png
img = readPNG("Rplot01.png") ### read the png
plot(ggimage(img)) ###reading png file
}
})

export all the content of r script into pdf

I would want to export all the content of r script into pdf. Could it be possible?
I used these commands export, but what I see I just exported graphics
pdf(file = "example.pdf")
dev.off()
Thank you!
setwd("C:/Users/Prat/Desktop/c")
> dir()
[1] "script.R"
> knitr::stitch('script.r')
output file: script.tex
In my folder doesn't appears a script.pdf else a script.tex and a folder with the pictures in pdf
You can do this with the knitr package. Here's a workflow:
Save your script as a file (e.g., myscript.r)
Then run knitr::stitch('myscript.r')
The resulting PDF will be saved locally as myscript.pdf. You can use browseURL('myscript.pdf') to view it.
You can generate html file by using,
knitr::stitch_rhtml('filename.r')
As .tex file is not easily readable but html files can view in any browser easily.
For everyone who is looking for an easy and fast solution, I would propose using the function capture.output (https://www.rdocumentation.org/packages/utils/versions/3.6.2/topics/capture.output) from utils.
One only needs to 1.) capture what ever command one wants to run and assign it to a variable and 2.) then print that variable. Images can be printed along the way as you can see. The example on the webpage I linked above does not use markdown.
Here my example with markdown (this is really all one needs):
```{r, echo = F}
# fake data-set
x = rnorm(50, mean = 3.3, sd=1)
y = rnorm(50, mean = 3.1, sd=0.9)
z = rnorm(50, mean = 3.2, sd=1.1)
# create dataframe
df <- data.frame(x, y, z)
# adding a graphic
plot(df$x, df$y)
# create a model as example
linearMod <- lm(y ~ x + z, data=df)
# all one needs to capture the output!!:
bla <- capture.output(summary(linearMod))
print(bla)
```
Remark: if one also wants to print the command, that is also easy. Just replace "echo = F" with "warning = F" or remove the text altogether if you also wanna have the warnings printed, in case there are any.
I was having the same issue, but I realized I was working in R 4.1 and ignored the warning that knitr was created using R 4.2. However after updating my R version, I was also just getting a .tex file but when I read the .log file I found the error "sh: pdflatex: command not found."
I used this suggestion with success:
Have you installed a LaTeX distribution in your system? For rmarkdown,
tinytex is recommended, you would need to install the R package and
then the TinyTex distribution.
install.packages('tinytex')
tinytex::install_tinytex()
Make sure you not only install the package but also run that second command tinytex::install_tinytex() as I made that mistake also before finally getting the program to create a pdf file.
Here is the link to the site where I found this method.
https://community.rstudio.com/t/knitting-error-pdflatex-command-not-found/139965/3
Please use the below set of codes (you need to modify it according to your dataset/data-frame name).
library(gridExtra)
library(datasets)
setwd("D:\\Downloads\\R Work\\")
data("mtcars") # Write your dataframe name that you want to print in pdf
pdf("data_in_pdf.pdf", height = 11, width = 8.5)
grid.table(mtcars)
dev.off()
Thanks.

Generating PDF from multiple JPEGs in R

I have a folder with multiple JPEG files. How do I generate a PDF file from these JPEGs in R?
One JPEG = 1 PDF page. Images are of the same size.
Thanks a lot in advance.
You can do this easily using Latex. Which is nice, because then you can just use Sweave to do the whole thing.
You can do something along the lines of :
% This is some Sweave file
\documentclass{article}
\usepackage{graphicx}
\begin{document}
<<results=tex,echo=FALSE>>=
mypics <- dir('mypics')
for(i in mypics){
cat("\\includegraphics{", i, "}\n\n", sep = "")
}
#
\end{document}
OK, you'll have to set up your Sweave pipeline, but with a bit of tweaking you can automate the whole process easily.
if you insist on using R (other tools are more suitable), try something like this (slow, untested):
lf = list.files(pattern = "jpeg") # image filenames
library(jpeg)
jpegs = lapply(lf, readJPG)
library(grid)
pdf("output.pdf", width=8, height=4)
grid.raster(jpegs[[1]])
lapply(jpegs[-1], function(x) {grid.newpage() ; grid.raster(x)} ) -> bquiet
dev.off()
If you insist on using R to do this then you can open a pdf plotting device, par to set the margins (default will probably be to big and not centering), then in a loop use plot.new to start a new page and plot.window to set up the coordinates, etc. without plotting axes etc., use the read.jpeg function from the ReadImages package (or other tool/package to read, EBImage is another possibility) then rasterImage to plot the jpeg to the pdf device (or replace some of those steps with other image plotting functions, such as the plot method in ReadImages).
But overall it is probably easier/quicker/better/... to use a tool better designed for this type of thing. The ImageMagick suite of programs comes to mind, LaTeX has also been mentioned, and there are probably other tools as well.

Resources