Problems generating gif using raster package and google map images R - r

I want to generate a gif from raster images using imagemagick convert.
I use as a background a google map so I need to call plot() twice and this generated a flickering in the resulting gif, because a blank image is inserted in each cycle. How can I eliminate this blank image and generate a smooth gif?
An example follows:
require(raster)
require(dismo)
bk<-gmap(c(" DR Congo"))
png(file="Rplot%03d.png", width=500, height=500)
for(i in 1:4){
rnd <-matrix(rnorm(100*100),100,100)
s_rnd<-raster(rnd)
extent(s_rnd)<-extent(bk)/i
crs(s_rnd) <- crs(bk)
plot(bk, legend=FALSE, axes=FALSE, box=FALSE)
plot(s_rnd, legend=FALSE, axes=FALSE, box=FALSE,add=TRUE)
}
dev.off()
system(paste0("convert -delay 40 Rplot*.png ","Test.gif" ))
file.remove(list.files(pattern="^Rplot.*\\.png$"))

Related

Why does my plot of a raster in R blur in saved file?

I'm hoping to export a map with a raster plotted on it as a .pdf or some other vector file. For some reason, when I save it as a .pdf or .ps file, the raster is blurry/fuzzy/smeared and unusable. Any tips for fixing this? A .png saves with the desired resolution, but can't be manipulated layer-by-layer in post-processing.
library(maps)
library(raster)
ra<-raster(nrows=40,ncols=35,xmn=-110,xmx=-75,ymn=7,ymx=47)
ra2 <- rasterize(cbind(runif(1000,min=-109,max=-76),runif(1000,min=8,max=46)), ra,fun=function(x,...)log10(length(x)))
pal <- colorRampPalette(c("grey90","grey40"))
map(database="world",regions=c("US","Mexico","El Salvador","Honduras","Costa Rica","Guatemala","Belize","Nicaragua","Panama"),myborder=0.0000001,xlim=c(-110,-75),ylim=c(0,50))
plot(ra2,add=T,col=pal(7))
Here is a screenshot of the saved .pdf file
Here is a screenshot of the Quartz window with desired resolution
I just found that adding 'useRaster=FALSE' to the plot() function fixes this.
You can use the following code to save high-resolution image as pdf file
pdf(file = "My Plot.pdf",
width = 14, # The width of the plot in inches
height = 8.5) # The height of the plot in inches
pal <- colorRampPalette(c("grey90","grey40"))
map(database="world",regions=c("US","Mexico","El Salvador","Honduras","Costa Rica","Guatemala","Belize","Nicaragua","Panama"),myborder=0.0000001,xlim=c(-110,-75),ylim=c(0,50))
plot(ra2,add=T,col=pal(7))
#Run dev.off() to create the file!
dev.off()

How can I View the output of this animation code in Rstudio

This R code is to create an animated plot, I have run it and it did run but I have not been able to view it. it is said to save it output on pdf file though I saw the file but unable to open it. I got the code at How do I transfer output of animation R package on a beamer frame
because I want to learn how to input R animated plot on latex thus I was given this as an example. can you show me how I can view its output either on Rstudio or where the code saves it to? If you mean that the output can be viewed on pdf that is originally saved to, show me how? I am using Acrobat Reade Dc.
brownianMotion <- function(n=10,xlim=c(-20,20),ylim=c(-20,20),steps=50)
{
x=rnorm(n)
y=rnorm(n)
for (i in 1:steps) {
plot(x,y,xlim = xlim,ylim = ylim)
text(x,y)
# iterate over particles
for(k in 1:n){
walk=rnorm(2); # random move of particle
x[k]=x[k]+walk[1] # new position
y[k]=y[k]+walk[2]
# simple model for preventing a particle from moving past the limits
if(x[k]<xlim[1]) x[k]=xlim[1]
if(x[k]>xlim[2]) x[k]=xlim[2]
if(y[k]<ylim[1]) y[k]=ylim[1]
if(y[k]>ylim[2]) y[k]=ylim[2]
}
}
}
pdf("frames.pdf") # output device and file name
par(xaxs="i", yaxs="i", pty="s") # square plot region
par(mai=c(0.9,0.9,0.2,0.2)) # plot margins
brownianMotion(n=20, steps=400) # 20 particles, 400 time steps
There are two things here :
you need to add dev.off() after plotting so that the current plot is saved to the output device
the loop over step is rewriting the same filename for each plot, so that you end-up in having only the last frame in frames.pdf. Following this tutorial, you should rather write separate pdf files to an output folder, then animate them within LaTeX.
brownianMotion <- function(n=10,xlim=c(-20,20),ylim=c(-20,20),steps=50){
x=rnorm(n)
y=rnorm(n)
for (i in 1:steps) {
pdf(paste0("out/frames", i, ".pdf")) # save frames{i}.pdf to 'out' folder
plot(x,y,xlim = xlim,ylim = ylim)
text(x,y)
dev.off() # Adding dev.off()
...
}
}
par(xaxs="i", yaxs="i", pty="s") # square plot region
par(mai=c(0.9,0.9,0.2,0.2)) # plot margins
if (!dir.exists("out")) dir.create("out") # create 'out' folder if it doesn't exist
brownianMotion(n=20, steps=4) # 20 particles, 4 steps
The out folder will be located where your working directory is (use getwd() to see it).

How can I export my data as a png using R

Edit: adding link to the data being used (https://drive.google.com/open?id=0B0PKu0-SX1JPRW94SXFybFd6N2c)
Before I begin, I apologize if this is a duplicate but I cannot seem to find the answer after hours of research (though it likely exists...). I want to read in data from a .csv file and produce a .png showing the density and data points from a specified working directory. This should be able to run from an isolated environment (e.g. usb drive).
I have my data in a .csv file. I have produced some images, but not like that found in the following example (See "Figure 2A" from https://www.r-bloggers.com/reproducible-art-with-r/):
ORIGINAL EXAMPLE
set.seed(16211)
rc <- rpoispp(function(x,y){50 * exp(-3*(max(y)-y))}, 100, win=W23)
rcdist <- distmap(rc, dimyx=c(1200, 800))
rc2 <- rpoispp(1/rcdist*50)
rcd <- dirichlet(rc2)
png(filename = "Figure_2A.png", width=6000, height=4000, res=400)
par(mai=c(0,0,0,0))
plot(rcdist, legend=FALSE, main="", frame=FALSE, box=FALSE, ribbon=FALSE)
plot(rcd, add=T)
plot(rc, add=T, col="black", pch=19, cex=2.5)
plot(rjitter(rc, 0.01), add=T, col="white", pch=19, cex=0.4)
contour(rcdist, add=T, col="white")
dev.off()
I however want my code to produce a similar graph but not using random points. As I sit here delirious from lack of sleep... the best I have come up with is below (and I know it is probably hideous). Any corrections would be much appreciated.
CURRENT ATTEMPT
# load workspace ----------------------------------------------------------
getwd()
setwd("D:/AH_DataToPng_Test/")
# install packages --------------------------------------------------------
install.packages("spatstat")
# load library ------------------------------------------------------------
library(spatstat)
# import my data ----------------------------------------------------------
my.data=read.csv("Figure.csv")
# view in table -----------------------------------------------------------
grid.table(my.data) #Visually confirms data input
# print the data using ppp ------------------------------------------------
# TODO: Answer - Is ppp(xdata, ydata, xrange, yrange) strictly for use in the "Plots" view window?
my.pattern <- ppp(my.data[,1],
my.data[,2],
c(-6,6),
c(-5.1,4.13))
# plot(my.pattern) #TODO: DOESN'T WORK... needed to plot the points?
# plot(density(my.pattern)) #TODO: DOESN'T WORK... needed to produce the neat color graph?
#TODO: Answer - How do I get both the points and density to display simultaneously?
# print the data to png ---------------------------------------------------
png(filename="AH_FinalProjectOutput.png",
units="in",
width=11,
height=8.5,
pointsize=12,
res=72)
# plot(my.data) DOESN"T WORK... NOT NEEDED FOR png()?
# pause for review --------------------------------------------------------
for(i in 1:9){
Sys.sleep(1)
}
dev.off()
png(file="example%02d.png", width=200, height=200)
for (i in c(10:1, "G0!")){
plot.new()
text(.5, .5, i, cex = 6)
}
dev.off()
For me this will create 11 png files in the working directory.

fast way to read in png, add grid & coords, and output

I have a lot of png files of a floor plan (mapping) layout that I want to:
read into R
Add grid lines
Add coordinates per cell in grid
Output
There are 1000 of these files so I'm looking for a speedy method. What would be a fast way to accomplish this task. These don't need to be publication quality as I'm looking for certain behavior clusters within cells and want recording the coordinated for these events for each of the 100 frames (pngs).
Here is a MWE that produces 10 png files:
x <- y <- seq(-4*pi, 4*pi, len = 27)
r <- sqrt(outer(x^2, y^2, "+"))
dir.create("delete_me")
wd <- getwd()
setwd("delete_me")
lapply(1:10, function(x){
png(sprintf("file_%s.png", x))
image(z = z <- cos(r^2)*exp(-r/x))
dev.off()
})
setwd(wd)
The final output will look like this for each png (with all the coords filled in).
I assume grid will be the way to create the gridlines quickly but am not sure about reading the png in quickly or plotting the coordinates (assume we'll use a 10 x 10 grid on each png).
How about using ggplot() and annotation_custom() to plot the image across the entire plot area, then manually overplot the grid lines.
(In the image, I trimmed the excess whitespace and axis from the png file in advance)
# pre-req libraries
require(ggplot2)
require(grid) # rasterGrob function
require(png) # to read the PNG file
width<-10
height<-10
# generate the points and labels for the grid
points<-data.frame(expand.grid(w=1:width,h=1:height))
points$labs<-paste0("(",points$w,",",points$h,")")
points$x<-points$w-0.5 # center
points$y<-points$h-0.5
# make the gridline co-ordinates
gridx<-data.frame(x=0:width,xend=0:width,y=rep(0,width+1),yend=rep(height,width+1))
gridy<-data.frame(x=rep(0,height+1),xend=rep(width,height+1),y=0:height,yend=0:height)
grids<-rbind(gridx,gridy)
# function to plot using ggplot with annotation_custom for the image
plotgrid<-function(file){
g<-ggplot(points)+theme_bw()+
annotation_custom(rasterGrob(readPNG(file),0,0,1,1,just=c("left","bottom")),0,width,0,height)+
geom_text(aes(x=x,y=y,label=labs))+
geom_segment(aes(x=x,xend=xend,y=y,yend=yend),data=grids) +
coord_cartesian(c(0,width),c(0,height))
return(g)
}
# run the function for each file in the folder
setwd("delete_me")
lapply(list.files(),function(x)plotgrid(x))
setwd(wd)

Creating animation in R

I'm looking at the possibilities for animation creation in R. The {Animation} package seems to be mainly an R platform for ffmpeg and imagemagick. The only reference I found to creating individual image frames is to nest plot() inside a loop. But this seems an unfeasibly slow process for producing more complex plots given the poor speed performance of the png() renderer, particularly for plots including map objects - for example:
library(maptools)
data(wrld_simpl)
starttime = Sys.time()
for(i in 1:10){
png(paste('frames/', i, '.png', sep=''))
plot(wrld_simpl, col='grey85', bg = 'white', border='white')
points(sample(-180:180, 50), sample(-90:90, 50), col='red', pch=16, cex=2)
title('poxy map')
dev.off()
}
print(Sys.time() - starttime)
yielding 10 frames and:
Time difference of 9.763794 secs
I don't understand why R is so slow at rendering - at this rate it would take 45 mins or so to render a 2 minute video at 25fps, which seems slow for this relatively simple map example. Wrapping with apply is no quicker. Does anyone know of a way to wrap plot more efficiently, or perhaps to save a plot midway after the unchanging elements have been rendered?
Plotting the map as an image with just enough resolution should be more efficient than the plot method for SpatialPolygonsDataFrame.
require(maps) # save the world
png("world.png", width=500, height=200)
map("world", col="grey90", fill=TRUE, border="grey90", mar=c(0,0,0,0))
dev.off()
library(png); library(grid)
img = readPNG("world.png")
animation::saveGIF( {
for( ii in 1:100) {
grid.newpage()
grid.raster(img)
grid.points(default.units="npc")
}
}, ani.height=200, ani.width=500)

Resources