How to set a color by default in R for all plot.default, plot or lines calls - r

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.

Related

R creates empty pdf from ggplot graphic when I source script but not when I run it [duplicate]

Let's assume I have 2 source files, the first one named example1.r and the second one example2.r (given below).
example1.r
plot(1:10,1:10)
example2.r
qplot(1:10,1:10)
When I source example1.r, the graph is drawn. It does not, however, when I source example2.r. What is the solution here?
(qplot in example2.r is ggplot2's function)
Update:
.R files: source's option print.eval=TRUE will lead to printing behaviour of the evaluation result like in the interactive command line.
source("Script.R", print.eval=TRUE)
.Rnw files: knitr by default emulates the behaviour of the interactive command line wrt. printing. Note that knitr can be specified as Sweaving engine also for R package vignettes.
This is my original answer. But note that this workaround is IMHO completely obsolete now (and it always was good for a small lazy niche only).
This is the famous FAQ 7.22: Why do lattice/trellis graphics not work?.
For grid graphics like ggplot2 or lattice, you need to print the graphics object in order to actually draw it.
Interactively on the command line this is done automatically. Everywhere else (inside files to be sourced, loops, functions, Sweave chunks) you need to print it explicitly.
print (qplot (1 : 10, 1 : 10))
Alternatively, you can redefine qplot to do the printing:
qplot <- function (x, y = NULL, z = NULL, ...) {
p <- ggplot2::qplot (x = x, y = y, z = z, ...)
print (p)
}
(this changes the axis labels to x and y).
I use this approach in vignettes where I want to write code exactly as a user in an interactive session would type it.

R: Suppress base graphics plot but return plot as object

I have a function that both returns some statistics and makes a plot using R base graphics. I want to suppress the plotting from that function and instead return the plot as an object, so that plotting or not can be controlled from outside the function.
I've tried:
Using the gridGraphics package I can convert a base graphics plot to an object as suggested in this question:
plot(1:10)
grid.echo()
a = grid.grab()
grid.draw(a)
The remaining problem is that plot() command draws the plot that I want to suppress. Thus I tried to suppress it by plotting to a device in a temp file like answer here suggests. Code becomes:
ff = tempfile()
svg(filename = ff)
plot(1:10)
grid.echo()
a = grid.grab()
dev.off()
unlink(ff)
but now, grid.echo() can not find any graphics to echo, and throws warning:
Warning message:
In grid.echo.recordedplot(recordPlot(), newpage, prefix, device) :
No graphics to replay
I've traced this problem back to grid.echo() not being able to echo graphics from other devices than the Rstudio default device, regardless of being in a temp file or not. This is in itself strange, since grid.echo() docs says it echoes graphics from the current device, not mentioning any restrictions.
Can anyone help me to solve the problem of suppressing base graphics plot and returning it as object, either by suggesting how to fix my broken attempt, or with another approach?
LocoGris solved the problem in this related question about the behaviour of grid.echo.
The following code will plot the unwanted graphics output into a tempfile, save the plot as a grid object using grid.echo and grid.grab before unlinking the tempfile so that only the plot object remains, thereby producing the besired behaviour:
ff = tempfile()
svg(filename = ff)
plotfun <- function() plot(1:10)
grid.echo(plotfun)
a = grid.grab()
dev.off()
unlink(ff)
The difference to code in question is that the plotting in R base graphics is put into a function and passed to grid.echo, instead of relying on grid.echo to automatically find what it needs from the current device.
Potentially useful note: grid.echo will plot two times, which can be seen if using regular svg() without tempfiles, as two files will appear with the same plot. I assume that the first plot is in R base graphics and the second one is the echo using the grid system.

why ggplot source code doesn't display the plot? [duplicate]

Let's assume I have 2 source files, the first one named example1.r and the second one example2.r (given below).
example1.r
plot(1:10,1:10)
example2.r
qplot(1:10,1:10)
When I source example1.r, the graph is drawn. It does not, however, when I source example2.r. What is the solution here?
(qplot in example2.r is ggplot2's function)
Update:
.R files: source's option print.eval=TRUE will lead to printing behaviour of the evaluation result like in the interactive command line.
source("Script.R", print.eval=TRUE)
.Rnw files: knitr by default emulates the behaviour of the interactive command line wrt. printing. Note that knitr can be specified as Sweaving engine also for R package vignettes.
This is my original answer. But note that this workaround is IMHO completely obsolete now (and it always was good for a small lazy niche only).
This is the famous FAQ 7.22: Why do lattice/trellis graphics not work?.
For grid graphics like ggplot2 or lattice, you need to print the graphics object in order to actually draw it.
Interactively on the command line this is done automatically. Everywhere else (inside files to be sourced, loops, functions, Sweave chunks) you need to print it explicitly.
print (qplot (1 : 10, 1 : 10))
Alternatively, you can redefine qplot to do the printing:
qplot <- function (x, y = NULL, z = NULL, ...) {
p <- ggplot2::qplot (x = x, y = y, z = z, ...)
print (p)
}
(this changes the axis labels to x and y).
I use this approach in vignettes where I want to write code exactly as a user in an interactive session would type it.

Modifying an R package function for current R session; assignInNamespace not behaving like fixInNamespace?

I would like to be able to modify a hidden function inside an R package in an "automated" way, like using fixInNamespace, but where I can write the code in advance, and not in an "edit" window which fixInNamespace does. I think assignInNamespace could do the job, but currently it's not working. Here's an example of the problem.
require(quantmod)
getSymbols("AAPL")
chartSeries(AAPL) # Works fine up to here.
Now say I want to yaxis ticks to be drawn on the left side of the plot, instead of the right. This can be done by modifying the source code in the quantmod package. The relevant code for modifying the plot layout is in a hidden quantmod function called chartSeries.chob.
This could be done by doing this:
fixInNamespace("chartSeries.chob", ns = "quantmod")
and in the edit window, manually modify line 117 from axis(4) to axis(2), click OK, and again run chartSeries(AAPL) (now the y axis labels will plot on the left side of the plot). Everything is good, the plot is generated as expected, no problems.
But ... now suppose I want to modify chartSeries.chob in advance (in an automated way), presumably by sourcing a modified version of the chartSeries.chob function, without using the edit window. I might want modify dozens of lines in the function for example, and opening the edit window each time for a new R session is not practical.
How can I do this?
Right now I am doing this, which is not working:
assignInNamespace("chartSeries.chob", value = chartSeries.chob2, ns = "quantmod")
where I source from the console a full copy of chartSeries.chob with the modified code on line 117.
chartSeries.chob2 <- function (x)
{
old.par <- par(c("pty", "mar", "xpd", "bg", "xaxs", "las",
"col.axis", "fg"))
on.exit(par(old.par))
....
[Edit On 117:] axis(2)
...
}
When I run from the console:
chartSeries(AAPL)
or
quantmod:::chartSeries(AAPL)
I get errors -- the calls to other functions in quantmod from within the chartSeries.chob function are not found, presumably because the edited chartSeries.chob function is not in the quantmod namespace?
I notice that when typing quantmod:::chartSeries.chob from the console after the assignInNamespace command, there is no environment: namespace:quantmod at the end of the function definition.
But if I do the fixInNamespace modification approach, when I type quantmod:::chartSeries.chob, then I do see environment: namespace:quantmod appended to the end of the function definition.
Since fixInNamespace calls assignInNamespace you should be able to get it to work, the problem is probably that the environment is not the same and possibly some other attributes. If you change those to match then I would expect it to work better, possibly using code like:
tmpfun <- get("chartSeries.chob", envir = asNamespace("quantmod"))
environment(chartSeries.chob2) <- environment(tmpfun)
attributes(chartSeries.chob2) <- attributes(tmpfun) # don't know if this is really needed
assignInNamespace("chartSeries.chob", chartseries.chob2, ns="quantmod")
Another option for some changes would be to use the trace function. This would make temporary changes and would be fine for inserting code, but I don't know if it would be reasonable for deleting commands or modifying in place (specifying an editor that changed the code rather than letting you change it might make this possible).

How to call plot.xts when using RScript

UPDATE: Thanks to Joshua's comment I realized the problem wasn't being inside a function, but inside a script. So I've edited the question and also provided my own answer.
When I use plot.xts() interactively it pops up a graphics window. I just tried it from inside a function (I'm troubleshooting a unit test and wanted some visual help) but nothing appeared. Aha, says I, I know the trick, just use print.
But print(plot.xts(x)) still shows no chart and instead prints my xts object! I.e. it does exactly the same as print(x).
The script I use to run unit tests is:
#!/usr/bin/Rscript --slave
library('RUnit')
options(warn=2) #Turn warnings into errors
#By naming the files runit.*.R, and naming the functions test*(), we can use
# all the defaults to defineTestSuite().
#NOTE: they have a weird default random number generator, so changed here
# to match the R defaults instead.
test.suite=defineTestSuite('tests',dirs=file.path('tests'),
rngKind = "Mersenne-Twister", rngNormalKind = "Inversion")
test.result <- runTestSuite(test.suite)
printTextProtocol(test.result)
The script below does two things:
plot to a device file, as you would in headless setting such as a webserver,
plot a screen device, I use x11() but you could use win().
There is no limitation imposed by Rscript. And this has nothing to do with xts as you could just as easily plot an xts object.
#!/usr/bin/Rscript
set.seed(42)
x <- cumsum(rnorm(100))
png("/tmp/darren.png")
plot(x)
dev.off()
x11()
plot(x)
Sys.sleep(3) # could wait for key pressed or ...
You cannot use graphics (or input functions like readline) when using RScript. However an RScript is still just R, so when you want to add something interactive (e.g. for troubleshooting) start R, then type:
source('run_tests.R')
When run this way, a line like this shows the chart:
plot(x$High);cat("Press a key");readline()
When run directly from the commandline with ./run_tests.R that line gets quietly ignored.

Resources