Convert plot into pixels in R - r

Does anyone know how to convert a simple plot into png_format without saving the picture...? In other words, I look for the most straight forward and fastest way to convert a simple plot into pixels, if it is not already (see code below)...
EDIT: Suggestion given by #hrbrmstr implemented...
## SolutionOne
library(png)
testONE <- system.time({
## Save plot as .png
tmp <- tempfile()
png(tmp, width = 800, height = 600, res = 72)
plot(1:10, pch = 19, col = "yellowgreen", cex = 20)
dev.off()
## Read .png
asPixels <- readPNG(tmp)
## Information needed (e.g. RGB)
dim(asPixels)
pixONE <- asPixels[300, 400, 1:3]
})
## SolutionTwo
library(magick)
testTWO <- system.time({
## Produce image using graphics device
fig <- image_graph()
plot(1:10, pch = 19, col = "yellowgreen", cex = 20)
## Information needed
pixTWO <- image_data(fig)[1:3, 400, 300]
dev.off()
})
testONE # elapsed time: 0.064
testTWO # elapsed time: 0.164
Thanks for any hint...

Related

Multiple plots in one figure in a loop in R

I am trying to save 10 plots in PNG format, but it only shows me one plot. How can I fix the code below?
par(mfrow = c(3,4))
png(filename = "roc.png", width = 1200, height = 1200)
roc = list()
for(id in 1:10)
{
roc[[id]] = ModelCross[[id]]$roc
roc_ = ModelCross[[id]]$roc
coords_<- coords(roc_, best.method="closest.topleft") ## "youden", "closest.topleft"
par(pty = "s")
plot(roc_,col = "blue",print.thres="best", print.thres.best.method="closest.topleft")
print(paste0('roc',id))
}
dev.off()

Is there anyway to arrange plots using par () function?

I have created 3 rows with 3 figures each and would like to centre the last 2 figures to achieve visual representativity since they are aligned to the left side of my multiple plot. Is there any way of doing that without modifying the size of the graphs?
dat=read.csv("r1new.csv", header=TRUE, sep=",", dec="."); dat
par(mfrow=c(4,3))
par(mar=c(4,4,2,2))
############################################### WC 0.1 ###############################################
res.lm1 = lm(dat$wc_10_1~dat$m_wc_10_1, data=dat)
res.lm2 = lm(dat$wc_10_3~dat$m_wc_10_3, data=dat)
res.lm3 = lm(dat$wc_10_5~dat$m_wc_10_5, data=dat)
res.res1 = resid(res.lm1)
res.res2 = resid(res.lm2)
res.res3 = resid(res.lm3)
plot(dat$m_wc_10_1 [1:1731], res.res1,
ylab="Residuals",
xlab="modelled water content, 0.1 m",
main="",
xlim=c(0.05,0.55), ylim=c(-0.25,0.15),
type="p",
col="blue",
pch=16)
points(dat$m_wc_10_3 [1:814],res.res2, col="green3",pch=16)
points(dat$m_wc_10_5 [1:1768],res.res3, col="red",pch=16)
abline(0, 0, col="gold3", lwd=2)
You should check out layout. You need to define a matrix that shows the order and placement of graphs. Then these are filled in according to number. I believe the following example is approximately what you are looking for:
M <- matrix(rep(1:12, each = 2), nrow = 4, ncol = 3*2, byrow = T)
M[4,] <- c(0,10,10,11,11,0)
M
png("testplot.png", width = 6, height = 7, units = "in", res = 200)
layout(M)
layout.show(11)
op <- par(mar = c(3,3,0.5,0.5))
for(i in seq(11)){
plot(rnorm(10), rnorm(10))
}
par(op)
dev.off()

How to add logo on levelplot?

I want to make a plot from raster data using levelplot. How to add a header which contains logo.png and title, like showed on this picture?
Here is my data: SST
Here is my basic code to produce this map:
r<-crop(raster(flname, varname="sst"), extent(90, 144, -20, 25))
png('SST.png', height = 2000, width = 2500, res = 300)
print(levelplot(r, col.regions = sst, at=seq(20, 34, 0.1),
yscale.components=yscale.raster.subticks,
xscale.components=xscale.raster.subticks,
margin=FALSE, ylab='Latitude', xlab='Longitude',
main=paste0(flname,' (deg-C)')))
dev.off()
You can use package magick to compose images:
library(rasterVis)
library(magick)
header <- image_read("~/Desktop/headerWithLogo.png")
fig <- image_graph(width = 600, height = 600, res=96)
f <- system.file("external/test.grd", package="raster")
r <- raster(f)
levelplot(r, margin=F, main ="Test \n")
dev.off()
out <- image_composite(fig, header, offset = "+50-5")
print(out)

Produce par() panel plot with maps coming from 4 different raster stacks in R in a loop

I have four raster stacks and each one contains 228 layers. I want to plot the first step of each stack in a panel plot using par(2,2) in R, and finally produce 228 plots, each one containing 4 maps. I want to do this using a loop, but this is what I have come up this far. Could you please help me?
> to_dates = seq(as.Date('1990-01-01'), as.Date('2008-12-31'), by='month')
> dts <- format(as.Date(to_dates), "%Y-%m")
> #
> ex = expression(m^3 / m^-3)
> #
> for(k in 1:length(dts)){
> par(mfrow = c(2,2))
> #
> png(filename = paste("erai_land_soil_moisture_", dts[k], ".png", sep=""), width = 800, height = 800)
> setwd("F:/.../layer1")
> for(i in 1:length(file_list1#layers)){
> file_name = paste(names(file_list1)[i], "_layer1.png", sep="") png(file_name, width = 800, height = 800)
> plot(file_list1[[i]],
> main = "ERA-Interim/Land: Volumetric soil water - Layer 1: 0-7cm",
> cex.main = 0.8,
> sub = paste(dts[i]),
> cex.main = 1.7,
> cex.sub = 1.8, col = clrs,
> legend.shrink=1, legend.width=1, zlim=c(from=0, to=0.5)) grid.text(ex, x=unit(0.96, "npc"), y=unit(0.96, "npc"), just=1, rot=
> 0, gp=gpar(fontsize=13)) plot(afr, add=T) dev.off()
>}
> setwd("F:/.../layer2")
> for(i in 1:length(file_list2#layers)){
> file_name = paste(names(file_list2)[i], "_layer2.png", sep="") png(file_name, width = 800, height = 800)
> plot(file_list2[[i]], main =
> "ERA-Interim/Land: Volumetric soil water - Layer 2: 7-21cm",
> sub = paste(dts[i]),
> cex.main = 1.7,
> cex.sub = 1.8, col = clrs,
> legend.shrink=1, legend.width=1, zlim=c(from=0, to=0.5)) grid.text(ex, x=unit(0.96, "npc"), y=unit(0.96, "npc"), just=1, rot=
> 0, gp=gpar(fontsize=13)) plot(afr, add=T) dev.off()
> }
> setwd("F:/.../layer3")
> for(i in 1:length(file_list3#layers)){
> file_name = paste(names(file_list3)[i], "_layer3.png", sep="") > png(file_name, width = 800, height = 800)
> plot(file_list3[[i]],
> main = "ERA-Interim/Land: Volumetric soil water - Layer 3: 21-72cm",
> cex.main = 0.8,
> sub = paste(dts[i]),
> cex.main = 1.7,
> cex.sub = 1.8, col = clrs,
> legend.shrink=1, legend.width=1, zlim=c(from=0, to=0.5)) grid.text(ex, x=unit(0.96, "npc"), y=unit(0.96, "npc"), just=1, rot=
> 0, gp=gpar(fontsize=13)) plot(afr, add=T) dev.off()
>}
> setwd("F:/.../layer4")
> for(i in 1:length(file_list4#layers)){
> file_name = paste(names(file_list4)[i], ".png", sep="")
> png(file_name, width = 800, height = 800) plot(file_list4[[i]],
> main = "ERA-Interim/Land: Volumetric soil water - Layer 4: 72-189cm",
> cex.main = 0.8,
> sub = paste(dts[i]),
> cex.main = 1.7,
> cex.sub = 1.8, col = clrs,
> legend.shrink=1, legend.width=1, zlim=c(from=0, to=0.5)) grid.text(ex, x=unit(0.96, "npc"), y=unit(0.96, "npc"), just=1, rot=
> 0, gp=gpar(fontsize=13)) plot(afr, add=T) dev.off()
>}
> #
> title(paste(dts[k], "ERA-Interim/Land Soil Moisture", sep=""), cex.main=1.9, outer=TRUE)
> #
> dev.off()
> #
> }
It is very difficult to follow your code because of formatting.
I will place a template for your task.
# assuming that your rasters are stored in file_list3
for(k in 1:length(dts)) {
# Here code for file name generation
f_name = paste("erai_land_soil_moisture_", dts[k], ".png", sep="") # replace if needed
# Initiate png device
png(f_name, width = 800, height = 800)
par(mfrow = c(2, 2))
# iterate over each raster
for (i in c(1:4)){
# Prepare titles and anything else
# ... your code ...
# Actual plotting
plot(file_list3[i][[k]]) # raster i, layer k; add necessary arguments
# Here goes anything else (legend an so on)
# ... your code ...
# Close device
dev.off()
}
}
Hope this will help.
BTW, do not use setwd for a target folder. Just construct the propper file path:
f_name = paste("path/to/folder/", "erai_land_soil_moisture_", dts[k], ".png", sep="")
If you ask an R question here, you should always include some simple example data. Not code that refers to your real data and often is unnecessary complicated for the question at hand; because we do not have that data (nor do I want to download); because it often helps you solve your own problem by simplifying things; and it makes it easier to answer your question.
Example data
library(raster)
s1 <- stack(system.file("external/rlogo.grd", package="raster"))
s2 <- flip(s1, 'y')
s3 <- flip(s1, 'x')
s4 <- (s1 + s2 + s3) / 3
Here a way to look at the results without writing files. You can of course add arguments to the plot function to improve it.
par(mfrow=c(2,2), ask=TRUE)
for (i in 1:nlayers(s1)) {
plot(s1, i)
plot(s2, i)
plot(s3, i)
plot(s4, i)
}
If you want a single legend, it is easiest to use spplot
par(mfrow=c(2,2), ask=TRUE)
for (i in 1:nlayers(s1)) {
x <- stack(s1[[i]], s2[[i]], s3[[i]], s4[[i]])
print(spplot(x))
}
To write to files
path <- tempdir()
path
par(mfrow=c(2,2), ask=TRUE)
for (i in 1:nlayers(s1)) {
png(file.path(path, paste0("map_", i, ".png")))
x <- stack(s1[[i]], s2[[i]], s3[[i]], s4[[i]])
print(spplot(x))
dev.off()
}
list.files(path, pattern=".png$")
# and look at them in "path"

pictorial chart in r

I am trying to develop pictorial charts. Is it possible to develop such charts in R ?
myd <- data.frame (categories = c("Planes", "Ships", "Cars", "Trains"),
values = c(15, 18, 22, 11))
Component icons are here:
Hope that this would be helpful four your house / parliament floor
Edit: I forget to mention my reference and I add some explanations.
library(lattice)
library(grid)
imgs.names <- c('WNinq','7dqJM','9E3Wj','tStmx')
library(png)
images <- lapply(imgs.names, function(x)
readPNG(paste(mypath,x,'.png',sep=''),native=TRUE))
## I generate some data because we don't give a reproducible example
x <- c(rep(0,4),rep(10,9),rep(20,3),rep(5,8),rep(4,8),rep(15,4),rep(13,8))
barchart(1:4~x, origin=0, col="yellow",xlim=c(0,30),
xlab ='values',ylab='categories',title = 'Pictorial',
scales = list(
y = list(cex=2,col='blue', at = 1:4,labels = c('Trains','Cars','Ships','Planes')),
x = list(cex=2,col='blue',at=seq(0,30,by=10))
),
panel=function(x, y, ...) {
panel.fill(col = rgb(1,1,205/255)) ## I had to pick up the same yellow color!!
panel.grid()
lapply(1:4,function(id){
grid.raster(images[[id]], x=x[which(y==id)], y=y[which(y==id)],
default.units="native",
just="left",
width =unit(2, "native"),
height=unit(0.7, "native"))
}
)
}
)

Resources