I'm setting the default device to PNG options(device="png").
For one plot, I can make a PNG in R with particular dimensions using png(...):
v <- 1:10
png("squared.png", width = 960, height = 480)
plot(v, v**2)
dev.off()
But I want to set the default height/width (just like I'm setting the default device) so that all plots come out with my desired height and width.
Ah, this is what I'm looking for:
options(device = function() png(width = 960))
The device argument should be
a character string giving the name of a function, or the function object itself, which when called creates a new graphics device of the default type for that session...
Using a function instead of the string "png" gives me the flexibility I need.
Why don't you re-define png? If you type png into the console, R will display the function code. You can copy and paste it into an R script, changing its defaults. Then, the autocomplete of the function arguments will still work.
Related
I'm using tibble's glimpse function that prints output adjusted to RStudio's console width. To get the most descriptive output, I want RStudio's console width to be large (something like 180).
How do I set the width using code and not manually? getOption("width") or options("width")[[1]] returns the width, but I cannot set it to a value as that throws an error.
Edit: I've even tried setting width using options("width" = 180). This step although edits width parameter but does not expand RStudio's console.
To change the width option, use
options(width = 180)
I prepared some bokeh plots to display as html.
To this end I prepared a gridplot containing the subplots, the legends and some headings. This all displays extremely nice in HTML and with sizing_mode='stretch_width' it's even kind of responsive.
webpage = gridplot([[header_col],[panel_grid_plot]], toolbar_location=None, sizing_mode='stretch_width')
show(webpage)
Now I also want to export this "webpage" to a PNG. To this end, I use
export_png(webpage, filename= png_filename, width=1800)
Unfortunately, the width parameter is ignored as the webpage is an object of type gridbox and not of type Plot. (This is checked in the bokeh/io/export.py in the method def get_layout_html())
The output is a png of a width of 800px which is kind of useless as the actual information is crushed (while the legends are nicely scaled):
Any ideas how to set the width of my PNG export to useful values?
Is there a way to convert a gridboxto a Plot?
Thanx!
You should've received a warning saying that the width argument will be ignored since you're passing into export_png something that's not a plot.
A way of achieving what you want:
webpage = gridplot(..., sizing_mode='stretch_width')
webpage.width = 1800
export_png(webpage)
I'm using tibble's glimpse function that prints output adjusted to RStudio's console width. To get the most descriptive output, I want RStudio's console width to be large (something like 180).
How do I set the width using code and not manually? getOption("width") or options("width")[[1]] returns the width, but I cannot set it to a value as that throws an error.
Edit: I've even tried setting width using options("width" = 180). This step although edits width parameter but does not expand RStudio's console.
To change the width option, use
options(width = 180)
Edit: This page provides the code: https://www.andrewheiss.com/blog/2017/09/27/working-with-r-cairo-graphics-custom-fonts-and-ggplot/
ggsave("test_cario.eps", device=cairo_ps)
ggsave("test_cario.pdf", device=cairo_pdf)
However, I am wondering where the commands come from. They are not included in the list of possible devices in the official documentation (https://ggplot2.tidyverse.org/reference/ggsave.html). And, cairo_png does not exist; instead, type="cairo-png" is necessary, e.g.:
ggsave("test_cairo.png", type = "cairo-png")
Does anyone know why the argument is one time device = "" and another time type = ""?
I have tried code like
ggsave("model.eps", type = "cairo")
or
ggsave("model.eps", type = "cairo-ps")
or
ggsave("model.eps", device = "cairo-ps")
but nothing seems to work. In general, is it possible to create .eps files with ggsave using the Cairo graphics device? If so, how?
The code you need to look at to understand the differences is in a non-exported function named plot_dev in the ggplot namespace. You get this information by looking at the ggsave code. The line that dispatches to a device is:
dev <- plot_dev(device, filename, dpi = dpi)
# Look at that function
getAnywhere(plot_dev) # not exported, so need getAnywhere
The logic of plot_dev is to first check to see whether the "device" value was given as a function name and if so to just call that function. That is what happens in the first two calls you offered. If it's not a function and no character value for "device" is given (which is the situation in your third call), then plot_dev dispatchs from a named list of functions based on the extension of the file name offered as "filename". The type argument gets passed to the png function to get the 'cairo' version of png used rather than the default.
This is the list of possible devices and their default arguments. Those defaults can be offered alternate values and the "dots" can be used to specify other device parameters. (See their respective help pages for specifics):
devices <- list(eps = eps,
ps = eps,
tex = function(filename, ...)
grDevices::pictex(file = filename, ...),
pdf = function(filename, ..., version = "1.4")
grDevices::pdf(file = filename, ..., version = version),
svg = function(filename, ...) vglite::svglite(file = filename, ...),
emf = function(...) grDevices::win.metafile(...),
wmf = function(...) grDevices::win.metafile(...),
png = function(...) grDevices::png(..., res = dpi,
units = "in"),
jpg = function(...) grDevices::jpeg(..., res = dpi,
units = "in"),
jpeg = function(...) grDevices::jpeg(..., res = dpi,
units = "in"),
bmp = function(...) grDevices::bmp(..., res = dpi,
units = "in"),
tiff = function(...) grDevices::tiff(..., res = dpi,
units = "in"))
Notice that the first two parameters are given values of eps. That is an internally defined function:
eps <- function(filename, ...) {
grDevices::postscript(file = filename, ..., onefile = FALSE,
horizontal = FALSE, paper = "special")
TL;DR
You need to call specific pdf and ps cairo devices while the standard png device can be set to produce cario output using its own type parameter.
Explanation
The device parameter of ggsave can take a device function, a character string matching one of a predefined list, or be left as NULL (in which case the device is guessed from the file extension). In any case, a device function will be called. Note that when using the function form, you may need to set some parameters that ggsave would do for you if you used the character or auto-detection forms.
The grDevices package which contains most of the devices used by default also has cario_pdf and cairo_ps devices that you can pass to ggsave.
There is no cairo_png device. However, the png device has a type parameter which takes options from the following vector(on Windows as least): c("windows", "cairo", "cairo-png"). ggsave passes on the type specification to the png device when it calls it.
You can save to EPS with
ggsave("model.eps", device = "eps")
I have written a function that creates a barplot. I would like to save this plot as a pdf as well as display it on my screen (x11) when applying this function. The code looks like this.
create.barplots <- function(vec)
{
x11() # opens the window
### Here is a code that creates a barplot and works perfectly
### but irrelevant for my question
dev.copy(pdf("barplots.table.2.pdf")) # is supposed to copy the plot in pdf
# under the name "barplots.table.2.pdf"
dev.off() # is supposed to close the pdf device
}
This creates the following error: 'device' should be a function
When I modify the code to:
create.barplots <- function(vec)
{
x11()
### Here is a code that creates a barplot and works perfectly
### but irrelevant for my question
dev.copy(pdf) # This is the only difference to the code above
dev.off()
}
R displays the plot and creates a file called Rplots.pdf. This is a problem because of several reasons.
I also tried to open the devices the other way around. First open the pdf device, than copy the content of the pdf device into the x11 device, than set the pdf device as active and than close the pdf device. The code here looks like this:
create.barplots <- function(vec)
{
pdf("barplots.table.2.pdf") # open the pdf device
### Here is a code that creates a barplot and works perfectly
### but irrelevant for my question
dev.copy(x11) # copy the content of the pdf device into the x11 device
dev.set(which = 2) # set the pdf device as actice
dev.off() # close the pdf device
}
The problem here is that the wondow that is supposed to display the plot is empty!
To sum up, I have two questions:
1) How to save a plot as pdf and display it in x11 simultaneously? And
2) How to save the plot not in the working directory somewhere else?
EDIT
The solutions above work great. But I still do not understand why
pdf("barplots.table.2")
barplot(something)
dev.copy(x11)
displays an empty grey window instead of copying the content of the pdf device in the window device! I also tried
pdf("barplots.table.2")
barplot(something)
dev.copy(window)
In which I failed as well...
How about:
create.barplots <- function(...) {
x11()
plot.barplots(...) # create the barplot
dev.copy2pdf(file = "path/to/barplots.table.2.pdf")
}
You can easily add arguments for pdf in the dev.copy call, like this:
create.barplots <- function(vec,dir,file)
{
windows()
plot(vec)
dev.copy(pdf,file=paste(dir,file,sep="/")
dev.off()
}
dev.copy() has a ... argument to pass arguments to the pdf function, see also ?dev.copy. Alternatively you can use dev.copy2pdf , as Max told you. I'd also advise you to use windows() instead of x11(), otherwise you might have trouble with the font families. The defaults for x11 and pdf don't always match.
To save a file in another directory, just add the full directory (eg with paste, like in the function above)
As I mentioned in a previous post, you may consider my knitr package; if you use it in an interactive R session, you will be able to see the plots in a window and save them to pdf without any hacks (it is the default behavior). I still need a lot of efforts on the documentation and demos, but it should be able to work with an Rnw document. The main reason that you can both see the plots and save them in knitr is, knitr is very different with Sweave in design -- the graphical device is opened after the code is evaluated, so your plots will not be hidden in an off-screen device. Again, I need to warn you that it is highly experimental at the moment.
Following works nicely for me when called from inside functions. Call it after the plot code:
pdf2 <- function (file = "plot.pdf", w = 10, h = 7.07, openPDF = FALSE)
{
dev.copy2pdf(file = file, width = w, height = h, out.type = "pdf")
if(openPDF) browseURL(file)
}
NB. openPDF may only work in Windows with full (not relative) file path.
Based on the answer by Max Gasner, I wrote this helper function which allows to quickly switch from displaying and not. The argument x is a plot object or the function that does the drawing.
savepdf<-function(x, file, display=TRUE) {
if (display){
x;
dev.copy2pdf(file=file)
}
else {
pdf(file=file)
x;
dev.off()
}
}
Example:
savepdf(plot(c(1,2,3)), file="123.pdf", display=F)