"Plot.new has not been called yet" issue using plot() [duplicate] - r

Why does this happen?
plot(x,y)
yx.lm <- lm(y ~ x)
lines(x, predict(yx.lm), col="red")
Error in plot.xy(xy.coords(x, y), type = type, ...) :
plot.new has not been called yet

Some action, very possibly not represented in the visible code, has closed the interactive screen device.
It could be done either by a "click" on a close-button, or it could also be done by an extra dev.off() when plotting to a file-graphics device. (The second possibility might happen if you paste in a multi-line plotting command that has a dev.off() at the end of it, but had errored out at the opening of the external device. So the dangling dev.off() on a separate line accidentally closes the interactive device).
Some (most?) R implementations will start up a screen graphics device open automatically, but if you close it down, you then need to re-initialize it.
On Windows that might be window(); on a Mac, quartz(); and on a Linux box, x11(). You also may need to issue a plot.new() command. I just follow orders. When I get that error I issue plot.new() and if I don't see a plot window, I issue quartz() as well. I then start over from the beginning with a new plot(., ., ...) command and any further additions to that plot screen image.

In my case, I was trying to call plot(x, y) and lines(x, predict(yx.lm), col="red") in two separate chunks in Rmarkdown file. It worked without problems when running chunk by chunk, but the corresponding document wouldn't knit. After I moved all plotting calls within one chunk, problem was resolved.

As a newbie, I faced the same 'problem'.
In newbie terms :
when you call plot(), the graph window gets the focus and you cannot enter further commands into R. That is when you conclude that you must close the graph window to return to R.
However, some commands, like identify(), act on open/active graph windows.
When identify() cannot find an open/active graph window, it gives this error message.
However, you can simply click on the R window without closing the graph window. Then you can type more commands at the R prompt, like identify() etc.

plot.new() error occurs when only part of the function is ran.
Please find the attachment for an example to correct error
With error....When abline is ran without plot() above
Error-free ...When both plot and abline ran together

I had the same problem... my problem was that I was closing my quartz window after plot(x,y). Once I kept it open, the lines that previously resulted in errors just added things to my plot (like they were supposed to). Hopefully this might help some people who arrive at this page.

If someone is using print function (for example, with mtext), then firstly depict a null plot:
plot(0,type='n',axes=FALSE,ann=FALSE)
and then print with newpage = F
print(data, newpage = F)

I had the problem in an RMarkdown, and putting the offending line on the previous line of code helped.
Minimal Reproducible Example
This will error if run line by line in an Rmd:
x <- rbind(matrix(rnorm(100, sd = 0.3), ncol = 2),
matrix(rnorm(100, mean = 1, sd = 0.3), ncol = 2))
colnames(x) <- c("x", "y")
(cl <- kmeans(x, 2))
plot(x, col = cl$cluster)
points(cl$centers, col = 1:2, pch = 8, cex = 2)
but this works:
x <- rbind(matrix(rnorm(100, sd = 0.3), ncol = 2),
matrix(rnorm(100, mean = 1, sd = 0.3), ncol = 2))
colnames(x) <- c("x", "y")
(cl <- kmeans(x, 2))
plot(x, col = cl$cluster); points(cl$centers, col = 1:2, pch = 8, cex = 2)
The only change is that the offending line (the last one) is placed after the last succeeding line (placing a ; in between). You can do it for as many offending lines as desired.

Related

How to reduce the size of a plot in Jupyter Notebook?

I'm trying out R with Jupyter Notebook and for some reason the plots are huge. How can I reduce the size of the plot? I tried changing the plot_scale option via: options(jupyter.plot_scale=.25) but nothing happened. I've tried other numbers besides .25, but it has no effect.
I also tried
options(repr.plot.width = 1, repr.plot.height = 0.75, repr.plot.res = 100)
as well as options(jupyter.plot_mimetypes = c("text/plain", "image/png" )), but both gave the following error:
Error in value[[3L]](cond): invalid graphics state
Traceback:
plot without title
Ideally, I'm looking for a global solution (i.e. one that changes the default plot size, rather than having to individually scale each plot). Any suggestions?
Try the following:
options(repr.plot.width = 5, repr.plot.height = 5)
x = seq(0,2*pi, length = 50)
y = sin(x)
plot(x,y)
Then compare it to the output from the following in another cell or after restarting the kernel:
options(repr.plot.width = 15, repr.plot.height = 15)
x = seq(0,2*pi, length = 50)
y = sin(x)
plot(x,y)
You should see a difference.
If you set the width and height to you get plot without title error.
Should be good with 2 or above because ~1.8 or above worked in my tests.
Based on this post.
simply run
dev.off()
then rerun your code for plotting.
Alternativly use ggplot. If the error persists you should still try dev.off() and rerun your code.
Otherwise you still have the option to restart your notebook or reinstall R.

Safely restart graphics device if interactive

Sometimes we make plotting functions that alter graphical parameters, par. For instance if I want to combine base and grid I need to do some magic that alters par. Now I want to allow users to plot with such a function and not have the side effects in the next call to the same function. For example the following function if pressed twice results in the following two images each time:
library(ggplot2); library(grid); library(gridBase)
plotter <- function(){
#invisible(try(dev.off()))
layout(matrix(c(1, 2), nrow = 1, byrow = TRUE))
#Draw base plot
plot.new()
graphics::par(mar=c(1, 1, 1, 1), new = TRUE)
plot(1:10)
#Draw ggplot
plot.new()
vps <- baseViewports()
print( ggplot(mtcars, aes(mpg, hp)) + geom_point(), vp = vpStack(vps$figure,vps$plot))
}
plotter()
plotter()
Notice the smushed ggplot the second go round. Now I could fix this by uncommenting out the line invisible(try(dev.off())). But...when I then want to plot to an external device the call to pdf for example below, gets turned off. How can I restart the interactive device safely, or some other answer as I may be asking the wrong question.
pdf("test.pdf")
plotter()
dev.off()
I tried adding .pardefault <- par(no.readonly = T) at the beginning of the function call and par(.pardefault) at the end via: https://stackoverflow.com/a/9292673/1000343 but this does not work. This answer https://stackoverflow.com/a/5790430/1000343 does not work either.
Perhaps there's a way to use dev.cur against a list of internal plot devices to recognize if the plot device is RStudio or windows or such and only restart in those cases.

(R) Axis widths in gbm.plot

Hoping for some pointers or some experiences insight as i'm literally losing my mind over this, been trying for 2 full days to set up the right values to have a function spit out clean simple line plots from the gbm.plot function (packages dismo & gbm).
Here's where I start. bty=n in par to turn off the box & leave me with only left & bottom axes. Gbm.plot typically spits out one plot per explanatory variable, so usually 6 plots etc, but I'm tweaking it to do one per variable & looping it. I've removed the loop & lots of other code so it's easy to see what's going on.
png(filename = "whatever.png",width=4*480, height=4*480, units="px", pointsize=80, bg="white", res = NA, family="", type="cairo-png")
par(mar=c(2.6,2,0.4,0.5), fig=c(0,1,0.1,1), las=1, bty="n", mgp=c(1.6,0.5,0))
gbm.plot(my_gbm_model,
n.plots=1,
plot.layout = c(1,1),
y.label = "",
write.title=F,
variable.no = 1, #this is part of the multiple plots thing, calls the explanatory variable
lwd=8, #this controls the width of the main result line ONLY
rug=F)
dev.off()
So this is what the starting condition looks like. Aim: make the axes & ticks thicker. That's it.
Putting "lwd=20" in par does nothing.
Adding axes=F into gbm.plot() turns the axes and their numbers off. So I conclude that the control of these axes is handled by gbm.plot, not par. Here's where it get's frustrating and crap. Accepted wisdom from searches says that lwd should control this but it only controls the wiggly centre line as per my note above. So maybe I could add axis(side=1, lwd=8) into gbm.plot() ?
It runs but inexplicably adds a smoother! (which is very thin & hard to see on the web but it's there, I promise). It adds these warnings:
In if (smooth & is.vector(predictors[[j]])) { ... :
the condition has length > 1 and only the first element will be used
Fine, R's going to be a dick for seemingly no reason, I'll keep plugging the leaks as they come up. New code with axis as before and now smoother turned off:
png(filename = "whatever.png",width=4*480, height=4*480, units="px", pointsize=80, bg="white", res = NA, family="", type="cairo-png")
par(mar=c(2.6,2,0.4,0.5), fig=c(0,1,0.1,1), las=1, bty="n", mgp=c(1.6,0.5,0))
gbm.plot(my_gbm_model,
n.plots=1,
plot.layout = c(1,1),
y.label = "",
write.title=F,
variable.no = 1,
lwd=8,
rug=F,
smooth=F,
axis(side=1,lwd=8))
dev.off()
Gives error:
Error in axis(side = 1, lwd = 8) : plot.new has not been called yet
So it's CLEARLY drawing axes within plot since I can't affect the axes from par and I can turn them off in plot. I can do what I want and make one axis bold, but that results in a smoother and warnings. I can turn the smoother off, but then it fails because it says plot.new hadn't been called. And this doesn't even account for the other axis I have to deal with, which also causes the plot.new failure if I call 2 axis sequentially and allow the smoother.
Am I the butt of a big joke here, or am I missing something obvious? It took me long enough to work out that par is supposed to be before all plots unless you're outputting them with png etc in which case it has to be between png & plot - unbelievably this info isn't in ?par. I know I'm going off topic by ranting, sorry, but yeah, 2 full days. Has this been everyone's experience of plotting in R?
I'm going to open the vodka in the freezer. I appreciate I've not put the full reproducible code here, apologies, I can do if absolutely necessary, but it's such a huge timesuck to get to reproducible stage and I'm hoping someone can see a basic logical/coding failure screaming out at them from what I've given.
Thanks guys.
EDIT: reproducibility
core data csv: https://drive.google.com/file/d/0B6LsdZetdypkWnBJVDJ5U3l4UFU
(I've tried to make these data reproducible before and I can't work out how to do so)
samples<-read.csv("data.csv", header = TRUE, row.names=NULL)
my_gbm_model<-gbm.step(data=samples, gbm.x=1:6, gbm.y=7, family = "bernoulli", tree.complexity = 2, learning.rate = 0.01, bag.fraction = 0.5))
Here's what will widen your axis ticks:
..... , lwd.ticks=4 , ...
I predict on the basis of no testing because I keep getting errors with what limited code you have provided) that it will get handled correctly in either gbm.plot or in a subsequent axis call. There will need to be a subsequent axis call, two of them in fact (because as you noted 'lwd' gets passed around indiscriminately):
png(filename = "whatever.png",width=4*480, height=4*480, units="px", pointsize=80, bg="white", res = NA, family="", type="cairo-png")
par(mar=c(2.6,2,0.4,0.5), fig=c(0,1,0.1,1), las=1, bty="n", mgp=c(1.6,0.5,0))
gbm.plot(my_gbm_model,
n.plots=1,
plot.layout = c(1,1),
y.label = "",
write.title=F,
variable.no = 1,
lwd=8,
rug=F,
smooth=F, axes="F",
axis(side=1,lwd=8))
axis(1, lwd.ticks=4, lwd=4)
# the only way to prevent `lwd` from also affecting plot line
axis(2, lwd.ticks=4, lwd=4)
dev.off()
This is what I see with a simple example:
png(); Speed <- cars$speed
Distance <- cars$dist
plot(Speed, Distance,
panel.first = lines(stats::lowess(Speed, Distance), lty = "dashed"),
pch = 0, cex = 1.2, col = "blue", axes=FALSE)
axis(1, lwd.ticks=4, lwd=4)
axis(2, lwd.ticks=4, lwd=4)
dev.off()

Inconsistent results saving png() and jpeg() in R

I am saving some complicated graphs off in an R program that include plot(), lines(), points() and abline() function calls and have tried using both png() and jpeg(), but both are rendering very inconsistent results. In one run the grid will be saved in the background, in the next it will not. In one run, the points will be added at the correct lwd, in another they will be huge, or maybe not added at all. In another run, a line will added, and then disappear when I run it again. I am looping through hundreds of iterations, and getting different results with almost every run.
png(paste("/someFilePlace/pics/", propIn, ".png", sep = ""))
plot(plotDat$yhat, col = "white", ylim = c(0,max(plotDat$yhat)*1.1),xaxt='n')
fairlylightgray <- rgb(204/255, 204/255, 204/255, alpha=0.4)
abline(v=(seq(0,1700,100)), col=fairlylightgray, lty="dotted")
abline(h=(seq(0,10,0.5)), col=fairlylightgray, lty="dotted")
points(plotDat$y, cex = '*', lwd = 3, col= "gray")
lines(plotDat$yhat, col = "#08519C")
axis(1, at = c(1,500,1000,1500),
labels = c(plotDat$dt[1],plotDat$dt[500],plotDat$dt[1000],plotDat$dt[1500]))
dev.off()
Congratulations, I think you may have found an obscure almost-bug (at least, failure to intercept a user error). Try replacing cex="*" with something sensible in your code (it should be a number -- or maybe you meant pch="*").
I am able to get different results in different PNGs as follows (if I plot in an X11 window I can get funny things to happen as I resize the window).
for (i in 1:10) {
png(paste("tmp",i,"png", sep="."))
plot(1:10,1:10,cex="*");
dev.off()
}

How do I prevent Rplots.pdf from being generated?

I am working with some R code that generates a number of images as png files; however, a Rplots.pdf file keeps on being generated in the working directory, is there a way to prevent this from happening?
library(Cairo)
CairoPNG(file = "graphs.png")
nf <- layout(matrix(c(1:8), 2, 4, byrow=T), c(1, 1), c(1, 1, 1, 1), TRUE)
for (k in 1:num.k) {
plotMatrix(connect.matrix.ordered[k,,], log = F, main = paste("k=", k.vector[k]), sub = paste("Cophenetic coef.=", rho[k]), ylab = "samples", xlab ="samples")
}
y.range <- c(1 - 2*(1 - min(rho)), 1)
plot(k.vector, rho, main ="Cophenetic Coefficient", xlim=c(k.init, k.final), ylim=y.range, xlab = "k", ylab="Cophenetic correlation", type = "n")
lines(k.vector, rho, type = "l", col = "black")
points(k.vector, rho, pch=22, type = "p", cex = 1.25, bg = "black", col = "black")
dev.off()
I know this is a very old post and surely the OP has solved this. But I encountered this similar situation while working with plotly. Converting a ggplot output into a plotly output generated the similar error of not being able to open file 'Rplots.pdf'.
I solved it by simply including :
pdf(NULL)
I'm not sure of the reason for the error, have not been able to figure that out, but this small line helped removing the error and displaying my plots as I would expect in plotly and ggplot combinations.
I wonder if you have another command that opens a device before or after the code snippet you've given us. When you're all done run dev.cur() to see if there was a device left open. If not, it should return the null device.
Here are ways you can recreate getting a Rplots.pdf or a Rplot001.png; the layout and par commands open a device if one isn't open, and since no filename has been given, it uses the default filename.
options(device="pdf")
layout(1:4)
dev.off()
options(device="png")
par()
dev.off()
Maybe seeing that happen here will give you a clue as to what's happening with your code.
Here is the source code for CairoPNG:
function (filename = "Rplot%03d.png", width = 480, height = 480,
pointsize = 12, bg = "white", res = NA, ...)
{
Cairo(width, height, type = "png", file = filename, pointsize = pointsize,
bg = bg, ...)
}
This tells you that CairoPNG takes filename=... as a parameter, and passes this to Cairo as the file parameter.
I can see how this can lead to confusion, but the point is that your call to CairoPNG should be:
CairoPNG(filename="graphs.png")
See if that works...
I had a similar problem recently after upgrading to R-3.0.3 (yes we're a little behind!). It turns out that palette("default") opens a device now, though it didn't used to.

Resources