How do you save matplot in R as eps? - r

I am trying to save a matplot as eps on R. So far all the instructions I have been able to find online were either for the matplotlib in Python or they were something along the lines of saving the graph by right clicking directly, or by using the lines of code:
jpeg("name.jpg")
matplot(t, r[,1:n], type="l", lty=1, ylab="",xlab="Year")
dev.off()
But the quality/resolution of these saved graphs are dreadful. I was hoping something similar to
setEPS()
postscript("name.eps")
matplot(t, r[,1:n], type="l", lty=1, ylab="",xlab="Year")
dev.off()
But unfortunately this does not seem to work for matplot.

A jpeg file is a highly compressed file that loses information. It is never useful for graphics that will be printed or edited. In addition the default size and quality is small and low so you could have improved your results by printing a larger image at higher quality (see ?jpeg for details).
A postscript file (EPS) preserves the information lost by creating a jpeg file and stores the instructions for drawing the image, not a bitmap of the image. It is not clear what you problems were, but here is a simple example:
First, always provide reproducible data:
set.seed(42)
t <- 1950:1975
r1 <- rnorm(26, 35, 5)
r2 <- rnorm(26, 50, 5)
r3 <- rnorm(26, 65, 5)
r <- cbind(r1, r2, r3)
Now the plot:
setEPS()
postscript("name.eps")
matplot(t, r[, 1:3], type="l", lty=1, ylab="",xlab="Year")
dev.off()
readLines("name.eps", 10) # Check the results
# [1] "%!PS-Adobe-3.0" "%%DocumentNeededResources: font Helvetica" "%%+ font Helvetica-Bold"
# [4] "%%+ font Helvetica-Oblique" "%%+ font Helvetica-BoldOblique" "%%+ font Symbol"
# [7] "%%DocumentMedia: a4 595 841 0 () ()" "%%Title: R Graphics Output" "%%Creator: R Software"
# [10] "%%Pages: (atend)"

Related

R graphics: output to several file formats

In a number of scripts I first develop a graph on screen, and then need to save it as several file formats with particular height/width/resolution. Using png(), pdf(), svg(), ... to open a device, and then dev.off() to close it, I'm forced to put all the device open calls into my script and comment them out & re-run the code one device at a time.
I do know that for ggplot graphics, ggsave() makes this easier.
Is there any thing I can do to simplify this for base-R and lattice graphics?
One example:
png(filename="myplot.png", width=6, height=5, res=300, units="in")
# svg(filename="myplot.svg", width=6, height=5)
# pdf(filename="myplot.pdf", width=6, height=5)
op <- par() # set graphics parameters
plot() # do the plot
par(op)
dev.off()
The graphics devices are part of the grDevices package. The documentation on working with multiple open devices might be worth reading through. From what I understand, a circular array of open devices is stored, but only the current device is active. For that reason, opening all the desired devices and then looping over them with dev.list() is likely your best bet.
# data for sample plot
x <- 1:5
y <- 5:1
# open devices
svg(filename="myplot.svg", width=6, height=5)
png(filename="myplot.png", width=6, height=5, res=300, units="in")
pdf()
# devices assigned an index that can be used to call them
dev.list()
svg png pdf
2 3 4
# loop through devices, not sure how to do this without calling plot() each time
# only dev.cur turned off and dev.next becomes dev.cur
for(d in dev.list()){plot(x,y); dev.off()}
# check that graphics device has returned to default null device
dev.cur()
null device
1
dev.list()
NULL
file.exists("myplot.svg")
[1] TRUE
file.exists("myplot.png")
[1] TRUE
file.exists("Rplots.pdf") # default name since none specified in creating pdf device
[1] TRUE
There's quite a bit more in the documentation that you can work with.
You could use the cowplot package to convert your base or lattice graphics into ggplot2 objects that you can then save via ggsave(). This is not entirely foolproof but will work for most plots. You'll also need to install the gridGraphics package for this to work. See more here.
library(ggplot2)
library(cowplot)
#>
#> ********************************************************
#> Note: As of version 1.0.0, cowplot does not change the
#> default ggplot2 theme anymore. To recover the previous
#> behavior, execute:
#> theme_set(theme_cowplot())
#> ********************************************************
# define a function that emits the desired plot
p1 <- function() {
par(
mar = c(3, 3, 1, 1),
mgp = c(2, 1, 0)
)
boxplot(mpg ~ cyl, xlab = "cyl", ylab = "mpg", data = mtcars)
}
# the plot using base graphics
p1()
# the plot converted into a ggplot2 object
p2 <- ggdraw(p1)
p2
# save in different formats
ggsave("plot.pdf", p2)
#> Saving 7 x 5 in image
ggsave("plot.png", p2)
#> Saving 7 x 5 in image
ggsave("plot.svg", p2)
#> Saving 7 x 5 in image
Created on 2020-01-05 by the reprex package (v0.3.0)

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.

Copying plot with type=n in R to PDF doesn't copy plot points, only it's lines are shown in output pdf

I've encountered a small complication with copying following example of random data to pdf. I realized that it is possible to copy it to png and probably to other bitmap formats as well but not to pdf.
I was trying to learn via this example how to plot "Males" and "Females" on a plot and show them all with different colors, etc.
My device is windows.
x<- rnorm(100)
y<- x+rnorm(100)
g<- gl(2,50)
g<- gl(2,50, labels = c("Male","Female"))
str(g)
plot(x,y)
# Plot function of (x,y) above will display it but it's not clear who is women and who is men, so I do following steps to plot it with different colors.
# Plotting it with type="n".
plot(x,y, type="n")
points(x[g=="Female"], y[g=="Male"], col = "blue")
points(x[g=="Male"], y[g=="Female"], col = "green", pch=19)
fit<- lm(x~y)
abline(fit)
# Now I try to Copy it to png and that works fine.
dev.copy(png,"myfile.png",width=8,height=6,units="in",res=100)
dev.off()
# Now to pdf. This example doesn't work at all abd pdf won't even open in my pdf viewer.
pdf("myfile.pdf",width=8,height=6)
dev.off()
# So I try this and I am able to open it but only "abline" and "x" and "y" are present not the points I specified for males and females.
dev.copy2pdf(file="Examp1.pdf",out.type = "pdf")
dev.off()
Do you have any idea why is this happening? PNG would be sufficient probably but it has it's flaws. So any idea how to copy it to pdf in R?
Thank you for your answers.
Just use:
pdf("myfile.pdf",width=8,height=6)
plot(x,y, type="n")
points(x[g=="Female"], y[g=="Male"], col = "blue")
points(x[g=="Male"], y[g=="Female"], col = "green", pch=19)
fit<- lm(x~y)
abline(fit)
dev.off()
Explanation: This opens a pdf device, plots to it and closes the device.
As I reported in my comment, This works fine, because I copy the original screen device and not the copied png device into pdf device. Note that device copy functions can copy only screen device and when you copy a device this becomes the current one.
windows()
x<- rnorm(100)
y<- x+rnorm(100)
g<- gl(2,50)
g<- gl(2,50, labels = c("Male","Female"))
str(g)
plot(x,y)
plot(x,y, type="n")
points(x[g=="Female"], y[g=="Male"], col = "blue")
points(x[g=="Male"], y[g=="Female"], col = "green", pch=19)
fit<- lm(x~y)
abline(fit)
dev.copy(png,"myfile.png",width=8,height=6,units="in",res=100)
dev.off()
# How many devices are in list?
print (dev.list())
# I must copy only screen device, that there is the previous one
dev <- dev.prev()
# Now it works
dev.copy2pdf(file="Examp1.pdf",out.type = "pdf")
dev.off()

In R, how to prevent blank page in pdf when using gridBase to embed subplot inside plot

As explained here, it is easy to embed a plot into an existing one thanks to gridBase, even though both plots use the base graphics system of R. However, when saving the whole figure into a pdf, the first page is always blank. How to prevent this?
Here is an example:
require(gridBase)
## generate dummy data
set.seed(1859)
x <- 1:100
y <- x + rnorm(100, sd=5)
ols <- lm(y ~ x)
pdf("test.pdf")
## draw the first plot
plot.new() # blank page also happens when using grid.newpage()
pushViewport(viewport())
plot(x, y)
## draw the second plot, embedded into the first one
pushViewport(viewport(x=.75,y=.35,width=.2,height=.2,just=c("center","center")))
par(plt=gridPLT(), new=TRUE)
hist(ols$residuals, main="", xlab="", ylab="")
popViewport(2)
dev.off()
I think it's a bit of a hack but setting onefile=FALSE worked on my machine:
pdf("test.pdf", onefile=FALSE)
In searching for an answer (which I didn't really find so much as stumbled upon in the forest) I came across this post to Rhelp from Paul Murrell who admits that mixing grid and base graphics is confusing even to the Master.
A work around solution I found was to initiate the pdf file inside the for loop; then insert an if clause to assess whether the first iteration is being run. When the current iteration is the first one, go ahead and create the output device using pdf(). Put the dev.off() after closing the for loop. An quick example follows:
for(i in 1:5){
if (i == 1) pdf(file = "test.pdf")
plot(rnorm(50, i, i), main = i)}
dev.off()

Graphic of binary variable in R

I would like to plot a simple graphic. I have a dat set with n rowns and k columns, in which each row has a a sequence of 0 and 1. I would like to plot exactly this sequence for all rows.
Actually I want to reproduce the figure 24.1, p. 516, of Gelman and Hill's book (Data aAnalysis Using Regression and Multilevel/Hierarchical Models). I suspect that he made the graphic in Latex, but it seems quite ridiculous that I'm not able to repplicate this simple graphic in R. The figue is something like this. As you can see from the link, the "ones" are replaced by "S" and "zeros" by ".". It's a simple graphic, but it shows each individual response by time.
I would go with a formatted text output using sprintf. Much cleaner and simpler. If you still want a plot, you could go with the following:
Given matrix tbl containing your data:
tbl <- matrix(data=rep(0:1,25), nrow=5)
You can generate a plot as:
plot(1, 1, xlim=c(1,dim(tbl)[2]+.5), ylim=c(0.5,dim(tbl)[1]), type="n")
lapply(1:dim(tbl)[1], function(x) {
text(x=c(1:dim(tbl)[2]), y=rep(x,dim(tbl)[2]), labels=tbl[x,])
})
Using this as a base you can play around with the text and plot args to stylize the plot the way you wish.
Here are two possible solutions, based on fake data generated with this helper function:
generate.data <- function(rate=.3, dim=c(25,25)) {
tmp <- rep(".", prod(dim))
tmp[sample(1:prod(dim), ceiling(prod(dim)*rate))] <- "S"
m <- matrix(tmp, nr=dim[1], nc=dim[2])
return(m)
}
Text-based output
x <- generate.data()
rownames(x) <- colnames(x) <- 1:25
capture.output(as.table(x), file="res.txt")
The file res.txt include a pretty-printed version of the console output; you can convert it to pdf using any txt to pdf converter (I use the one from PDFlib). Here is a screenshot of the text file:
Image-based output
First, here is the plotting function I used:
make.table <- function(x, labels=NULL) {
# x = matrix
# labels = list of labels for x and y
coord.xy <- expand.grid(x=1:nrow(x), y=1:ncol(x))
opar <- par(mar=rep(1,4), las=1)
plot.new()
plot.window(xlim=c(0, ncol(x)), ylim=c(0, nrow(x)))
text(coord.xy$x, coord.xy$y, c(x), adj=c(0,1))
if (!is.null(labels)) {
mtext(labels[[1]], side=3, line=-1, at=seq(1, ncol(x)), cex=.8)
mtext(labels[[2]], side=2, line=-1, at=seq(1, nrow(x)), cex=.8, padj=1)
}
par(opar)
}
Then I call it as
make.table(x, list(1:25, 1:25))
and here is the result (save it as png, pdf, jpg, or whatever).
As far as I can see, this is a text table. I am wondering why you want to make it a graph? Anyway, quick solutions are (either way)
make the text table (by programming or typing) and make its screenshot and embed the image into the plot.
make a blank plot and put the text on the plot by programming R with "text" function. For more info on "text", refer to http://cran.r-project.org/doc/contrib/Lemon-kickstart/kr_adtxt.html

Resources