How to resize and save plots in png format? - r

I would like to plot the results from a quantile regression, but am not able to:
control the dimensions/size of the plots and
save the plots as png.
Here is my code:
require(quantreg)
data(engel)
attach(engel)
xx <- income - mean(income)
zz <- c(120, diff(income))
fit1 <- summary(rq(foodexp~xx+zz, tau=2:98/100))
Then:
png('res.png')
plot(fit1, mfrow=c(1,2))
Only the zz plot is saved to the res.png file.. Is there any way I can save the plots in separate files (two and one)?
and how do I control the width/height of the plots? I like all the individual plots to have width=height (square) when i save them to the .png file?

You can control the image dimensions by png argument.
png("image.png", width = 800, height = 600)
plot(...)
dev.off()
To "finish" the image, use dev.off.

For subdividing the plots:
plot(fit1,parm=1:2)
plot(fit1,parm=3)
Note that you could have found the answer by careful reading of ?plot.summary.rqs, but this may not have been obvious: in order to know where to look you would need to do class(fit1) to figure out which plot method was being used.
Roman's answer takes care of the image dimension stuff.

Related

Plotted raster output in R won't eliminate legend margin

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.

Save grid plots drawn within a loop automatically in R

I have time-series data of 6 months and I want to plot it in grid manner like this
As a reproducible example, let us the following code:
library(xts)
seq <- seq(as.POSIXct("2015-03-01"),as.POSIXct("2015-03-30"), by = "60 mins")
timeseries_ob <- xts(data.frame(rnorm(length(seq),30,2)),seq)
looplength <- length(unique(.indexmday(timeseries_ob)))
par(mfrow=c(4,3))
pdf("temp.pdf")
for(i in 1:looplength){
daydata <- timeseries_ob[.indexmday(timeseries_ob)%in%i,]
plot(daydata,type="l",main="")
}
dev.off()
With this code, plots get automatically saved, but they are not in the grid manner. Each plot gets saved in different page of pdf. Is there any other way to save above plots in a grid manner automatically.
Note: I don't want to use facet_grid, because these plots are generated within a loop and I believe with ggplot it might become complex to draw.
You have to use the par(mfrow = c(4,3)) command between pdf(...) and dev.off().
This will lead to your desired result!

image raster R package - raster printing without background and border and legend

I am using raster function as shown on lines below. My last line produces some output. That output has a line that says dimensions : 240, 320, 76800 (nrow, ncol, ncell). I would like reprint that image but say only first 200 rows and first 300 columns. How can I do that? The second last line below plots the entire image
f <- "pictures/image1-1421787394.jpeg"
f
r <- raster(f)
plot(r);
r
=============================update1
I did png(filename = '~/x.png');par(mar=rep(0, 4), xpd = TRUE, oma=rep(0, 4),bty='n') ; plot(r,xlim=c(0,200),ylim=c(0,200),legend=FALSE,axes=FALSE); dev.off() to save the cropped image. I was able to get rid of the legend and axes and the black box. But the problem is that the saved image contains much more than cropped part - for example white part around the image. I want to save only the cropped part of the original (keep image size 200*200 pixels). Please let me know how to do that?
Moreover, how could i add a red square that corresponds to the above cropped part to the original image? I mean I would like to get a red square (only edges) on the top of the original image and then save this (original image+square) as a new image.
How could i do that?
update2++++++++++++++++++++++++++++++++++++++++++++++++
adding repeatable example to show what i mean by white background
the last line below plots cropped image. I want that image to be 100*100 as my xlim and ylim are 100. But i see a white background as shown in the example below. (you cannot see the background. But if you run the code on your machine and open the image, you will see it)
library(raster)
r <- raster(nrow=240, ncol=320)
values(r) <- 1:ncell(r)
plot(r)
plot(r,xlim=c(0,100),ylim=c(0,100),legend=FALSE,axes=FALSE,frame.plot=F)
You can do it by setting xlim and ylim:
plot(r,xlim=c(0,299),ylim=c(0,199))
[UPDATE]
To get rid of the white background, you can try useRaster=F parameter:
plot(r,xlim=c(0,100),ylim=c(0,100),legend=FALSE,axes=FALSE,frame.plot=F,useRaster=F)
If understand your question well, you have a RasterLayer r with dim(r) of c(240, 320, 1) and you want to crop that to the first 200 rows and 300 columns and then plot that without white space.
Always provide example data. In this case that is easy to do.
library(raster)
r <- raster(nrow=240, ncol=320)
values(r) <- 1:ncell(r)
There are different ways to crop by rows/columns. For example you can create an extent object and use that.
e <- extent(r, 1, 200, 1, 300)
rc <- crop(r, e)
Another way (for smaller sized rasters) would be to use indexing and drop=FALSE
rc <- r[1:200, 1:300, drop=FALSE]
To make a map you can use 'plot' or 'image'. Perhaps image is more of your liking (less white space, but no legend)
image(rc)
with plot you can set the size of the device before plotting.
dev.new(height=nrow(r), width=ncol(r))
plot(rc, legend=FALSE)
You can also plot to a file such as png to avoid whitespace; depending on how you set your 'par'ameters such as mai
png('test.png', width=450, height=275)
plot(rc)
dev.off()
Other ways to deal with this include using spplot, or levelplot in the rasterVis package
spplot(rc)
library(rasterVis)
levelplot(rc)
To get the red rectangle on the original image
plot(r)
plot(e, add=TRUE, col='red', lwd=2)

Exporting graphs in R

I have two graphs that I plotted in R and I want to export it as a high-resolution picture for publication.
For example:
a<-c(1,2,3,4,5,6,7)
b<-c(2,3,4,6,7,8,9)
par(mfrow=c(2,1))
plot (a,b)
plot(a,b)
I usually export this graph by:
dev.copy(jpeg,'test.jpeg',width=80,height=150,units="mm",res=200)
dev.off()
However I always find this process a bit troublesome. The graph that was plotted in R does not necessarily look like the one that I exported. Therefore, I am wondering if there is a way to specifiy the dimensions and resolution of graphs before I plot them so that I can visually inspect the graphs before I export them?
Thank you
You can try:
png('out.png')
a<-c(1,2,3,4,5,6,7)
b<-c(2,3,4,6,7,8,9)
par(mfrow=c(2,1))
plot (a,b)
plot(a,b)
dev.off()
As baptiste said, jpeg is the worst format you can choose. You should take a look at the help for the bmp and png functions (with ?bmp and ?png). Both bmp and png have height, width, and res arguments that you can use to specifiy the dimensions and resolution of the output. Also, I wouldn't recommend the use of dev.copy. As you could see, the result of the output is not always what you expect.
To add to Bonifacio2's answer, you if you call the function first to make the plot, you can also define your margins and window size etc before doing any actual plotting. That way you have full control over all fig specs.
pdf(file='test.jpeg',width=80,height=150,units="mm") #I prefer pdf, because they are editable files
a<-c(1,2,3,4,5,6,7)
b<-c(2,3,4,6,7,8,9)
par(mfrow=c(2,1))
plot (a,b)
plot(a,b)
dev.off()
You can use cowplot package to combine multiple panels in several different ways. For example, in your case, we export one plot with two panels arranged in two rows and one column. I assume that you prefer to use base-R 'plot' function instead of ggplot.
library(cowplot)
p1 <- ~{
plot(a,b)
}
p2 <- ~{
plot(b,a)
}
png("plot.png",
width = 3.149606, # 80 mm
height = 5.905512, # 150 mm
units = 'in',
res = 500)
plot_grid(p1, p2, labels = "AUTO", nrow = 2, ncol = 1)
dev.off()
Note that you can either remove the labels if not needed or print small letters by using "auto". Regarding size of the text, axis-labels etc, use the standard arguments for generic plot function of base-R. I hope this answer helps you. Best wishes.

automatically adjust R plot size in a PDF output

When using the pdf() function in R for saving a plot in an external file, we can specify width and/or height to adjust the size of the plot. However, there are situations when we obtain multiple plot (say using par(mfrow=c(2,4))). In this situation, it's kind of difficult to determine what is the best width and height for the PDF file in order to have all plots displayed properly. Is there a way to let R automatically "fit the plots" in the PDF file? I searched the arguments in pdf() and tried some, but the results are not satisfactory. Thank you very much!
How about something using ggplot?
require(ggplot2)
# Bogus data
x <- rnorm(10000)
y <- as.factor(round(rnorm(10000, mean=10, sd=2), 0))
df <- data.frame(vals=x, factors=y)
myplot <- ggplot(data=df, aes(x=vals)) +
geom_density() +
facet_wrap(~ factors)
ggsave(filename="~/foo.pdf", plot=myplot, width=8, height=10, units="in")
EDIT: Should you need to print over multiple pages, see this question.

Resources