I think I may have discovered a bug. I'm using levelplot in rasterVis, when I plot the rasters they show up fine in the raster window, however when I try and save them using png() the raster has lines through it.
library(raster)
library(rasterVis)
library(RColorBrewer)
col<-rasterTheme(region=brewer.pal(8,"YlOrRd"))
r<-raster(ncol=40,nrow=20)
r[] <- rnorm(n=ncell(r))
b<-"Title"
png(file=paste0(path,"\\",b,".png"), width=1800, height=1800, res=300)
plot<-levelplot(r,main=b,par.settings=col, margin=FALSE, scales=list(draw=FALSE))
print(plot)
dev.off()
In the plot window it shows up as it should:
But saved using png():
I figured it out, the margins parameter needs to be in the form of a list. Resolves the lines in the images.
plot<-levelplot(r,main=b,par.settings=col, margin=list(draw=FALSE,scales=list(draw=FALSE)))
Related
I have a simple raster, that running through the filledContour function in the raster package, to give a filled contour plot.
I am trying to overlay the outline of a polygon over the top of this filled contour plot but having trouble.
reading the notes in filled.contour - adding lines to a filled contour plot has to be done in the plot.axis section, but not having any luck.
So far i have something like this:
library(raster)
library(rgdal)
test_raster <- raster("test_raster.grd")
test_Shapefile <- readOGR("test_shapefile.shp")
test_filled_contour <- filledContour(test, maxpixels=100000, plot.axes = {
axis(1)
axis(2)
map(test_Shapefile, add=T)
})
Both the raster and shapefile use the same coordinate system.
Any help welcome, i can provide the data if needed.
The following code is a minimal example of what I have and what I am trying to achieve. The idea is I have a large chunk of code that builds up a plot in many steps. I want to save the plot as a png at different steps along the way.
This chunk works...
x<-runif(10)
y<-runif(10)
png(filename="Plot0.png")
plot(y~x)
abline(h=mean(y))
dev.off()
but when I split the plot chunks yet want to save each step individually there's a problem.
x<-runif(10)
y<-runif(10)
png(filename="Plot1.png")
plot(y~x)
dev.off()
png(filename="Plot2.png")
abline(h=mean(y))
dev.off()
The problem is plot.new has not been called yet. This I have searched but I can't seem to find the bits that make it work.
R handles basic plot that plot creates a new "sheet of paper" and other function such as abline can draw on top of it. Thus you cannot use abline without calling a plot first. You called dev.off which clears the previous plot, and therefore you don't have any plot to use abline with -> plot.new has not been called yet.
Basically you need to switch to the grid system to enable this.
You might want to consider switching to ggplot and saving the object along the way, or using ggsave.
Here's a solution using graphics which basically captures your base R plot on grid:
library(graphics)
x<-runif(10)
y<-runif(10)
plot(y~x)
pl <- recordPlot()
png(filename="Plot1.png")
grid::grid.newpage()
pl
dev.off()
abline(h=mean(y))
pl <- recordPlot()
png(filename="Plot2.png")
grid::grid.newpage()
pl
dev.off()
In ggplot, you can simply do:
library(ggplot2)
df = data.frame(
x<-runif(10),
y<-runif(10)
)
g = ggplot(df,aes(x=x,y=y))+geom_point()+theme_bw()
ggsave(g,file="Plot1.png")
g = g + geom_hline(yintercept=mean(y))
ggsave(g,file="Plot2.png")
Following the link given by duckmayr in the original question comments I was able to achieve the desired result. Throughout a construction one can simply include say p1<-recordplot() and then create the png of p1 at the end. I think that this is rather elegant.
x<-runif(10)
y<-runif(10)
dev.control(displaylist="enable")
plot(y~x)
p1 <- recordPlot()
abline(h=mean(y))
p2 <- recordPlot()
invisible(dev.off())
png(filename="Plot1.png")
p1
dev.off()
png(filename="Plot2.png")
p2
dev.off()
In R, I have a raster object generated from a kernel density analysis using the ks package. I convert this into a raster object (from the raster package) and try to draw that raster object to a PNG using plot(). I want the png to have exactly one pixel for every pixel in the raster object. Simple enough, right? By default of course, I get all sorts of extraneous junk added to the plot. I can remove most of this using the various settings in plot() or par(), but no matter what I do, I don't seem able to get rid of the space formerly taken up by the legend on the right side of the plot.
library('ks')
library('raster')
# generate the data
set.seed(1)
x = matrix(rnorm(1000,1,0.5),500)
xpix = 100
ypix = 100
# calculate the density function
k = kde(
x,
H=matrix(c(0.1,0,0,0.1),2),
xmin=c(0,0),
xmax=c(1,1),
gridsize=c(xpix,ypix)
)
# convert to raster
r = raster(k)
# plot the image to PNG
png('file.png',width=xpix,height=ypix)
par(
mar=c(0,0,0,0),
bty='n',
bg='black',
plt=c(0,1,0,1)
)
plot(
r,
legend=FALSE,
axes=FALSE,
plt=c(0,1,0,1)
)
# see that 'plt' did not change
print(par())
dev.off()
If I check par before closing the device, I can see that the 'plt' value is not what I set it to; it shows the right margin, where the plotting area has been nudged over to make space for the non-legend. Sample code is above, and the image it generates is linked to here.
Incidentally, I was able to achieve the correct effect with the image() function instead of plot(), though that introduced it's own problems, namely that transparency no longer worked. Can I solve this with plot()? It's very frustrating that I'm so close but just can't seem to change the size of the plot area! I don't want to use another graphics package if there is any way to make the base function work.
I have been building a small GUI for climate analysis using gWidgets in R. Progress has been slow but steady until I hit a problem trying to display my raster stack of results using spplot().
The issue is that only the first raster in the stack is plotted and the rest are not. This issue occurs regardless if:
I produce the plot using a handler within the GUI.
If the plot is produced using a handler within a addHandlerChanged/addHandlerClicked function.
If the plot is loaded to the GUI directly from the R console.
As above but using using levelplot().
If plot() is used, results are displayed correctly but only the first 16 are displayed (I have 24 graphs) and the scales are not merged producing difficulty in interpreting the results.
Here is some example code to illustrate the issue:
require(gWidgets)
require(raster)
## create example GUI plot area
win = gwindow("Graph test")
nb = gnotebook(container=win,expand=T)
plots = ggraphicsnotebook(container=nb)
## create raster stack
rs=list()
for(i in 1:24){
rs1=raster()
rs1[]=rnorm(3600)
rs[i]=rs1
}
rs=stack(rs)
## attempt to plot stack
spplot(rs) ##plot is not produced correctly with only the first raster plotted
##compare this to plotting in a normal window
windows()
spplot(rs)
Here is an example of the expected plot (left) and the actual (right) using the above code.
If anybody has any ideas how to get around this or any alternative plotting options for raster stacks I would love to hear them.
(please note that similar results are produced if I open a separate window using windows() within the GUI or if I use levelplot())
Cheers
To those who may be interested. After 3.5 years and a many trials, including recordPlot(), the gridGraphics package and imager::capture.plot(), the only solution that I found was to save the graph as an image and then plot it in the window using rasterImage()
require(gWidgets)
require(gWidgetsRGtk2)
require(RGtk2)
require(raster)
require(png)
options(guiToolkit="RGtk2")
## create raster stack
rs=list()
for(i in 1:24){
rs1=raster(nrow=2,ncol=2)
rs1[]=rnorm(4)
rs[i]=rs1
}
rs=stack(rs)
##save plot as png
png("out.png")
spplot(rs)
dev.off()
img = readPNG("out.png")
## create example GUI plot area
win = gwindow("Graph test")
nb = gnotebook(container=win,expand=T)
plots = ggraphicsnotebook(container=nb)
##plot
par(mar=rep(0,4))
plot(1, type="n", axes=F, xlab="", ylab="")
usr = par("usr")
rasterImage(img, usr[1], usr[3], usr[2], usr[4])
This has certainly been asked before, but I can't find a solution. I would like to plot some data with a perfect square as bounding box. With par(pty="s") this is easy, but once I save the plot as a pdf file, the square is lost. As I understand, this is because pdf() uses paper="special" as default and thus respects width and height (which does not give a perfect square since we have axis labels). But specifying other paper options did not help.
## the bounding rectangle in the following plot is a perfect square...
U <- matrix(runif(1000), ncol=2)
par(pty="s")
plot(U, type="p", xlab="U_1", ylab="U_2")
## ... however, not anymore if the plot is generated as a .pdf
pdf(file="U.pdf", width=6, height=6)
par(pty="s")
plot(U, type="p", xlab="U_1", ylab="U_2")
dev.off()