Consider the following:
dev.off()
dev.cur() # null device
par("las") # opens a new device
dev.cur() # default device
My problem is identical to the one described in this question, I do not want to open a new device but the library I'm calling has unavoidable calls to par(). Also, I'd prefer a better solution than the hack described there.
My idea for solving it was the following:
change options("device") via
options(device = function(){}) # WARNING CHRASHES R WHEN CALLING PAR()
so that no new device get's opened. However as the comment indicates, this chrashes R. My question is, what should I change options("device") to such that no new device get's opened, but also R doesn't chrash when calling par.
Related
My question: How to let grDevices::dev.new() work well ?
To avoid the error Error in plot.new() : figure margins too large coursing the small plot region,
I wrote the code grDevices::dev.new() in the front of plot().
However this code does not work in the first time (or after pushing the button .clean all plot button )
And this cause the errors (e.g., in the R CMD check).
Do I misunderstand the function grDevices::dev.new() ?
REF?:
R: Open new graphic device with dev.new() does not work
Answer
Using grDevices::windows() instead of grDevices::dev.new(), I overcome the issues.
Unfortunately, we cannot use grDevices::windows() , because the following error occurs in the R CMD check:
Error in grDevices::windows() :
screen devices should not be used in examples etc
I'm an Octave noob but I'm trying to display a graph at the same time as an input in the terminal however the graphics only update after the input therefore I get an unloaded graph:
This is the code:
f=figure;
imshow(img);
pause(1); % FIX THIS!
in=input('Input required:', 's');
Pausing for 1 second is sketchy because it doesn't always the graph but without a pause it doesn't even enter the graphics loop. Is there someway to block until the graph is loaded before continuing? I wasn't able to find the required function in the documentation.
You can use drawnow to force the graphics to render and the event queue to be flushed.
f = figure();
imshow(img);
drawnow
in = input('Input required:', 's');
I am closing the device (here: pdf() ) I am plotting to at the end of my function with dev.off(). However, if the function/loop terminates due to an error the device stays open. When a function gets repeatedly called, this can lead to quite a lot of open devices; and file handles.
How can I make sure the device gets closed even if the function fails?
I do remember that I once saw how to do this, but I cannot remember.
on.exit() is made for situations just like this. It's good practice to use it whenever opening a (file or other) connection in a non-interactive setting.
f <- function() {
pdf(tempfile()) # tempfile() so example doesn't clutter up working directory.
on.exit(dev.off())
plot(randomNonExistentObjectName)
}
f()
# Error in plot(randomNonExistentObjectName) :
# object 'randomNonExistentObjectName' not found
dev.list()
# NULL
Wrap your whole plotting expression into a tryCatch like so:
tryCatch(expr={pdf(...); plot(...)}, finally=dev.off())
I've made a gui with a button, the handler of which executes a plot method of a class I made, it uses ggplot2 and grid/gridExtra in a normal R session to put together the plot. It works fine using the plot() function in console. My button/handler is below:
Plotbutton <- gbutton("Plot!", container=MainWindow,
handler=function(h,...){
plot(analysis, linesplot=svalue(linecheck), lineplot.legend=svalue(linelegcheck), baseannotate=svalue(bpcheck), bpfreq=as.numeric(svalue(bpspin)), mosaic.bars=svalue(mosaiccheck), mosaic.scale=as.numeric(svalue(mosaicspin)), combine.plots=svalue(combinecheck), condense.mosaics=svalue(condensecheck), labfontsize=as.numeric(svalue(fontspin1)), legfontsize=as.numeric(svalue(fontspin2)))
})
I'm not sure of the reason, but loading gWidgets, gWidgetstcltk, and the package required for my plot method, and then clicking the button, nothing is plotted to the R graphics environment, however in RStudio the plot panel is not updated until the GUI is exited. The graphic does appear in a window in the normal Windows RGui though.
Can anyone suggest why this is happening?
The reason why it works from the R-console and not from a function is that the R-console will invoke print() automatically if nothing else is stated. Within a function R does not do this, so if you want to print a graph, you must explicitly state print(graph). Try
print(plot(analysis, linesplot=svalue(linecheck), lineplot.legend=svalue(linelegcheck), baseannotate=svalue(bpcheck), bpfreq=as.numeric(svalue(bpspin)), mosaic.bars=svalue(mosaiccheck), mosaic.scale=as.numeric(svalue(mosaicspin)), combine.plots=svalue(combinecheck), condense.mosaics=svalue(condensecheck), labfontsize=as.numeric(svalue(fontspin1)), legfontsize=as.numeric(svalue(fontspin2)))
to simplify my daily R interactions, I'd like to set up default colors for all my plots. For example, let's say I want to have all plots made with red lines (like in gnuplot...:-) )
So far, here is a snippet of my .Rprofile
setHook(packageEvent("grDevices", "onLoad"),
function(...)
grDevices::X11.options(width = 14, height = 8, type = "Xlib", xpos = 600, ypos = 30, canvas = "grey87"))
suppressPackageStartupMessages( require(Defaults) )
suppressPackageStartupMessages( require(utils) )
suppressPackageStartupMessages( require(graphics) )
setDefaults("plot.default",frame.plot=FALSE, type='l', col=2)
What I do here is the following:
when the grDevices package is loaded (by loading the graphics package), I call the X11.options with my prefered parameters: a wider box, light gray background, xlib calls (because I'm doing distant calls, and cairo in my current environment is just too slow (another problem to solve))
Then I silently load 3 packages, Defaults, utils and graphics. The second one is needed to avoid a find function error message.
Finally, the magic function setDefaults set-up 3 parameters to the scatter plot function plot.default. The 3rd parameter col is not a parameter of plot.default but one from the par() function.
But, doing a setDefaults call with par doesn't work either.
Any solution is welcome...
You can use the "plot.new" hook to set default par values each time a new graphics frame is opened. (The hook's workings are documented in ?plot.new and ?setHook)
In your case, just add this line to your .Rprofile:
setHook("plot.new", function() par(col = "red"))
The parameters such as color are set on a per device basis, so when you close one device and create a new one all the parameters are set back to their default values. To do this I would create your own device function that opens the device then sets the parameters, something like:
mydev.new <- function(...) {
dev.new(...)
par(col='red')
}
You could obviously replace dev.new with x11 or something else, but this is probably the most portable. Now you can open a new device using mydev.new and the default color will be set to red.
Further if you run the command
options(device=mydev.new)
Then when you don't have a graphics device open and you run a plotting command, your function will be the one run to open a new plotting device and so the default will be red in that case as well. You could expand the mydev.new function (or whatever you want to call it) to set other options, take arguments, etc. for different cases you may want to work with.