R: Show plot when running script from command line - r

How to display a window with a ggplot figure when executing an R script from the command line (without intermediary save to file)?
Example script test.R
#!/usr/bin/env Rscript
library(ggplot2)
p = ggplot(aes(x = Sepal.Length), data = iris) + geom_histogram(color = 'black', fill = NA)
plot(p)
On the command line run the script with ./test.R.
This dumps the plot to Rplots.pdf - instead I'd like a window just like in an interactive session with the plot, with no file output.
How to specify output device to be the screen? (e.g. on Ubuntu)

You can do this via a call to X11(), which will open a graphics window. Some relevant excerpts from help("X11"):
on Unix-alikes ‘X11’ starts a graphics device driver for the X
Window System (version 11). This can only be done on
machines/accounts that have access to an X server.
Usage:
X11(display = "", width, height, pointsize, gamma, bg, canvas,
fonts, family, xpos, ypos, title, type, antialias)
Arguments:
display: the display on which the graphics window will appear. The
default is to use the value in the user's environment
variable ‘DISPLAY’. This is ignored (with a warning) if an
X11 device is already open on another display.
However, it will close immediately after the R script is done being executed. So, this works to display your plot, but it isn't open for long:
#!/usr/bin/env Rscript
library(ggplot2)
p = ggplot(aes(x = Sepal.Length), data = iris) +
geom_histogram(color = 'black', fill = NA)
X11()
plot(p)
I guess the real questions are
Why are you averse to saving the plot before viewing it? and
If you want to open a plot window but not save the plot, why not just run your commands in an interactive R session? That seems to me more useful if you're not saving results.

Related

Fonts not loading in showtext font_add_google

I'm trying to graph some data and my code looks like this:
library('ggplot2')
library('tidyr')
library('ggthemes')
library('showtext')
font_add_google('Syncopate', 'Syncopate')
showtext_auto()
ggplot(aes(x = X, group=1), data = glassdoor)+
geom_line(aes(y = col1, color = 'red'))+
geom_line(aes(y = col2, color = 'blue'))+
geom_line(aes(y = col3, color = 'magenta'))+
geom_line(aes(y = col4, color = 'yellow'))+
theme(text = element_text(family = "Syncopate"))+
ggtitle('A Long Test Title')
Syncopate is a distinctive font, seen here. But my visualization's font just looks like this (this is a test graph, ignore its overall poorness):
But if I load a system theme like Times New Roman, it works fine. Why aren't my google fonts loading using showtext?
Edit
Jrakru's answer works, but bear in mind that you have to run that entire code block: The new fonts will appear in a saved png file, but not in the preview window. This isn't written as a slight against the answer, but rather for others like myself who expect the fonts to show up in the RStudio console and therefore omit the ggsave and png portions of the code.
The GitHub for showtext mentions
This example should work on most graphics devices, including pdf(),
png(), postscript(), and on-screen devices such as windows() on
Windows and x11() on Linux.
If you read really really hard between lines, that means, that RStudioGD graphics device is not supported. I did not see that the first few times I read it. I only know because the vignette is a little more explicit.
NOTE: Currently showtext does not work with the built-in graphics
device of RStudio, hence to try the code below, it is suggested to run
the code in original R console, or use other graphics devices such as
x11() and windows()
see
https://cran.rstudio.com/web/packages/showtext/vignettes/introduction.html
With the above knowledge, we can do this:
library('tidyr')
library('ggthemes')
library('showtext')
font_add_google("Schoolbell", "bell")
showtext_auto()
library('ggplot2')
df<- data.frame(x=1:10, y=101:110)
options("device" = "windows")
win.graph(10,10,12)
ggplot(data = df) +
geom_line(aes(x,y))+
theme(text = element_text(family = "bell"))+
ggtitle('A Long Test Title')
ggsave("showtext-example.png", width = 7, height = 4, dpi = 96)
options("device" = "RStudioGD")
And Voila!
Ps: I assumed you are a windows user.
according to the same document: https://cran.rstudio.com/web/packages/showtext/vignettes/introduction.html
And the very bottom of it, you can read this:
Compatibility with RStudio
Starting from version 0.9, showtext can work well with the RStudio
graphics device (RStudioGD). Simply call showtext_auto() in the
RStudio session and then the plots will be displayed correctly.
it worked for me in RStudio 1.3.959

How to display the Plots by executing the file from command line

I'm trying to execute the below code that display a plot:
using Plots, Measures
pyplot()
data = [rand(100), rand(100)];
histogram(data, layout = 2,
title = ["Dataset A" "Dataset B"], legend = false,
ylabel = "ylabel", margin = 5mm)
I do not get any output once I execute it from the command line!!
Knowing that I tried it in 3 different ways and it works (Jupyter, Juni, Julia session), though I'm confused about the way it works in the Juno, kinldy see my observations below:
With Jupyter it is functioning perfectly:
With Juno, I've to run the file TWICE!! the first time looks to be for compilation, second time for execution, maybe!!
And if I closed the plot, I've to close the Julia session, restart it, then re-execute the file TWICE!! and sometimes nothing is appearing!!
With Julia session, it take time for first time execution, then if I closed the plot and run it again, it is appearing smoothly.
The commands like histogram or plot typically don't display the plots for users, they only generate and return the plots.
What displays the plots is actually the display system in Julia.
When Julia is in interactive use, like in REPL, Jupyter and Juno, the display system will be invoked automatically with commands not ending with ";". That's why you see plots displayed in REPL, Jupyter and Juno.
But when executing the file from the command line, the display system is not automatically activated. So you first have to invoke display yourself like this:
using Plots, Measures
pyplot()
data = [rand(100), rand(100)];
h = histogram(data, layout = 2,
title = ["Dataset A" "Dataset B"], legend = false,
ylabel = "ylabel", margin = 5mm)
display(h)
But even this will not give you the picture, but only text representation of the plot. This is because in command line julia, only a very simple text display system is in place, and it doesn't have "full" support for plots from Plots. To display the plots, you have to write your own display mechanism and push it to Julia display system, which is not hard but a little tedious. I will give an example when I have more time.
BTW, if you just want plots generated from command line, another way is to save it to files, which is more direct than making a display mechanism yourself.
Update
Here is a simple display, which mimics the display system used in Julia REPL. The code here is for Julia 0.7/1.0.
const output = IOBuffer()
using REPL
const out_terminal = REPL.Terminals.TerminalBuffer(output)
const basic_repl = REPL.BasicREPL(out_terminal)
const basic_display = REPL.REPLDisplay(basic_repl)
Base.pushdisplay(basic_display)
Using it before the previous code will show the plot. Please note that you use pyplot() backend for Plots, whose default is to open a new window and display the plot in the window, but when the julia finish execution in the command line, it will close the plot window. To deal with this, we could either change ways for the default display, or use another backend to show the plot, for example, plotly() backend will display the plot through html. The complete code may look like following:
const output = IOBuffer()
using REPL
const out_terminal = REPL.Terminals.TerminalBuffer(output)
const basic_repl = REPL.BasicREPL(out_terminal)
const basic_display = REPL.REPLDisplay(basic_repl)
Base.pushdisplay(basic_display)
using Plots, Measures
plotly()
data = [rand(100), rand(100)];
h = histogram(data, layout = 2,
title = ["Dataset A" "Dataset B"], legend = false,
ylabel = "ylabel", margin = 5mm)
display(h)
Use readline() to get such destination that close the plot window by typing enter.
using GR
y = rand(20,1)
p = plot(y,linewidth=2,title="My Plot")
readline()

Saving ggplot graph to PDF with fonts embedded in r

I've been following advice I've found online for saving a ggplot graph to PDF but I can't quite get it to work. I'm using the extrafont package to produce charts with text in Calibri, but my charts are printing out with no text. I don't know what I'm missing. I can't find any mistakes in my process. Hopefully, someone else can help.
Here's the code and process I used:
library(extrafont)
font_import(pattern="[C/c]alibri")
loadfonts(device="win")
I installed GhostScript at this time. Then ran the following to set the GhostScript location.
Sys.setenv(R_GSCMD = "C:\\Program Files\\gs\\gs9.21\\bin\\gswin64c.exe")
I then produced a chart using ggplot called "chart". The chart looked perfect in RStudio, but not in PDF.
ggsave("chart.pdf", plot = chart, width = 6, height = 4)
Here I get warnings showing stuff like this:
In grid.Call(C_textBounds, as.graphicsAnnot(x$label), ... : font family 'Calibri' not found in PostScript font database
Apparently, these warnings are supposed to happen? Then I run...
embed_fonts("chart.pdf", outfile="chart_embed.pdf")
Unfortunately, after all this, the final "embed" chart looks no different than the original chart produced, neither of which have any text.
In case it helps, here's the code to produce the chart:
a <- ggplot(data=stats, aes(x=Date))
Chart <- a + geom_point(aes(y=NevadaTotalNonfarmAllEmployees)) +
xlab("Date") +
ylab("Nonfarm Jobs") +
ggtitle("Nevada Total Jobs") +
theme(axis.title.x = element_text(size=15, family = "Calibri"),
axis.title.y = element_text(size=15, family = "Calibri"),
axis.text.x = element_text(size=10, family = "Calibri"),
axis.text.y = element_text(size=10, family = "Calibri"),
plot.title = element_text(hjust=0.5, size=20, family = "Calibri"))
I've been pulling my hair out trying to figure this out. Or maybe it's not the code but something else? Either way, thanks for any assistance.
There are a couple issues at play here: (1) loading fonts into R and (2) using a PDF-writing library that works correctly with custom embedded fonts.
First, as others have mentioned, on Windows you generally need to run extrafont::font_import() to register many of your system fonts with R, but it can take a while and can miss TTF and other types of fonts. One way around this is to load fonts into R on the fly, without loading the full database, using windowsFonts(name_of_font_inside_r = windowsFont("Name of actual font")), like so:
windowsFonts(Calibri = windowsFont("Calibri"))
This makes just that one font accessible in R. You can check with windowsFonts(). You have to run this line each time the script is run—the font loading doesn't persist across sessions. Once the font has been loaded, you can use it normally:
library(tidyverse)
df <- data_frame(x = 1:10, y = 2:11)
p <- ggplot(df, aes(x = x, y = y)) +
geom_point() +
labs(title = "Yay Calibri") +
theme_light(base_family = "Calibri")
p
Second, R's built-in PDF-writing device on both Windows and macOS doesn't handle font embedding very well. However, R now includes the Cairo graphics library, which can embed fonts just fine. You can specify the Cairo device in ggsave() to use it, which is easier than dealing with GhostScript:
ggsave(p, filename = "whatever.pdf", device = cairo_pdf,
width = 4, height = 3, units = "in")
I’ve found it safer to explicitly register fonts using pdfFonts (and/or postscriptFonts).
The documentation contains an example but also take a look at my fonts module. With this, registering a new font is as easy as writing
fonts$register_font('Calibri')
Internally, this creates a font specification using Type1Font, ensures that names are set correctly, and invokes pdfFonts.
It also ensures that the complete set of font metrics to exist (which is done using extrafont::ttf_import).
This way is considerably faster than generating font metrics for all fonts using font_import, and it gives you more control.
I think you missed the initialization step font_import(). Be forewarned, executing this command can take a bit longer time.
First, you can see what fonts you have available with the command windowsFonts(). The current fonts in my graphing device are;
$serif
[1] "TT Times New Roman"
$sans
[1] "TT Arial"
$mono
[1] "TT Courier New"
Thereafter, you can import the extrafont library and the loadfonts(device = "win"). I also recommend to execute these commands in the R console and not in RStudio. I suggest this because when you are importing the fonts using font_import() in RStudio, it may not show the y/n prompt.
Below I provide a minimum reproducible example;
library(ggplot2)
library(extrafont)
font_import()
# tell where ghostscript is located. This is required for saving the font in pdf
Sys.setenv(R_GSCMD = "C:\\Program Files\\gs\\gs9.21\\bin\\gswin64c.exe") # I have installed 64-bit version of GhostScript. This is why I've used gswin64c.exe. If you have installed 32-bit version of GhostScript, use gswin32c.exe. Failure to specify the correct installed GhostScript will yield error message, "GhostScript not found"
# create a plot object
p <- ggplot(mtcars, aes(x=wt, y=mpg)) +
geom_point()+
ggtitle("Fuel Efficiency of 32 Cars")+
xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
theme_bw()+
theme(text=element_text(family="ArialMT", size=14))
# show the plot
print(p)
# save the plot as pdf
ggsave("figures//ggplot_arialmt.pdf", p, width=20, height=20,
device = "pdf", units = "cm")
Note
Its only the ArialMT font that seems to work with ggsave(). See this SO post. Using any other font for saving to pdf, renders the figure with characters on top of another. This is also an open issue for ggsave and has not been answered since 2013.

Plotting device with RStudio

I have issue with plotting lines over my existing plot in .Rmd in RStudio. I ran the code within the code chunk in .Rmd (⌘ + return) and the plot gives me a graph within the .Rmd (new feature of RStudio v1.0), however when I ran the second code lines, an error shows up.
plot(density(with$glucose),
ylim = c(0.00, 0.02),
xlab = "Glucose Level",
main = "Figure",
lwd = 2)
lines(density(without$glucose),
col = "red",
lwd = 2)
Error in plot.xy(xy.coords(x, y), type = type, ...) : plot.new has not been called yet
On the other hand, if I copy and paste the codes into the console, I could get the plot I want, in the plot viewer within RStudio.
In addition, when I ran some other codes within the .Rmd (⌘ + return), my plots in the plot viewer in RStudio disappear. This means I have to do copy-paste into the console instead of using the (⌘ + return) shortcut.
Does anyone have the same problem?
This is a known problem, but you can solve it very easy: Press Ctrl+Shift+Enter to run the complete chunk, then everything works fine and you don't have to copy-and-paste all thing to the console.
So do all your plots in one chunk and run this chunk. This will produce you the plot within the RMD file (as you mentioned: new feature of RStudio 1.0)
If you're not a fan of the inline output / notebook mode for R Markdown documents, you can also disable it within the Global Options dialog -- try disabling the option:
Show output inline for all R Markdown document

R eps export and import into Word 2010

I'm having trouble with exporting eps files from R and importing into Word 2010.
I'm using ggplot2 plots, eg
library(ggplot2)
p <- qplot(disp,hp,data=mtcars) + stat_smooth()
p
Even after calling setEPS() neither of the following produce files which can be successfully imported.
ggsave("plot.eps")
postscript("plot.eps")
print(p)
dev.off()
The strange thing is that if I produce the plot using File -> Save As -> Postscript from the menu in the GUI, it can be imported correctly. However, when the Word document is subsequently exported as a pdf, the fonts in the graphic are a little jagged.
So my questions are:
What combination of (ggsave/postscript) settings allows me to produce eps files that can be imported into Word 2010?
How can I ensure the fonts remain clear when the Word document is exported as a pdf?
Update
After more investigation I have had more luck with cairo_ps to produce the plots. However, no text shows up when imported into Word.
Furthermore, after checking the various eps outputs (cairo_ps, save from the GUI, ggsave) in a latex document, it seems like the eps import filter in Word quite poor as the printed/pdf output doesn't match the quality of the latex'd document. The ggsave version (which uses postscript) did have some issues with colours that the other two methods didn't have though.
The conclusion is that this is a Word issue and therefore fortune(109) does not apply. I'd be happy to be proven otherwise, but I'll award the answer and the bounty to whoever can provide the commands that can replicate the output from the GUI in command form.
This worked for me... following advice in the postscript help page:
postscript("RPlot.eps", height = 4, width = 4, horizontal = FALSE, onefile = FALSE,
paper = "special")
library(ggplot2)
p <- qplot(disp,hp,data=mtcars) + stat_smooth()
p
#geom_smooth: method="auto" and size of largest group is <1000, so using loess. Use 'method = x' to #change the smoothing method.
#Warning message:
#In grid.Call.graphics(L_polygon, x$x, x$y, index) :
# semi-transparency is not supported on this device: reported only once per page
dev.off()
#quartz
# 2
The funny stuff at the end puts you on notice that this is only a Mac-tested solution, so far anyway.
Edit: I just tested it with R version 2.15.1 (2012-06-22) -- "Roasted Marshmallows": Platform: i386-pc-mingw32/i386 (32-bit) and MS Word 2007 in Win XP and it worked. Commands were Insert/Picture.../select eps format/select file.
Edit2: There is another method for saving besides directly using the postscript device. The savePlot method with an "eps" mode is available in Windows (but not in the Mac). I agree that the fonts are not as smooth as they appear on a Mac but I can discern no difference in quality between saving with savePlot and using save as from an interactive window.
savePlot(filename = "Rplot2", type = "eps", device = dev.cur(), restoreConsole = TRUE)
savePlot calls (.External(CsavePlot, device, filename, type, restoreConsole))
I solved the problem with exporting .eps files from R and importing into Word 2010 on Windows 7 using the colormodel="rgb" option (defaults to "srgb") of the postscript command.
postscript("RPlot.eps", height = 4, width = 4, horizontal = FALSE,
paper = "special", colormodel = "rgb")
library(ggplot2)
p <- qplot(disp,hp,data=mtcars) + stat_smooth(se=FALSE, method="loess")
p
dev.off()
You are probably better of using wmf as a format which you can create on Windows.
Word indeed doesn't support EPS very well.
A better solution is to export your graphs to Word or Powerpoint directly in native Office format. I just made a new package, export, that does exactly that, see
https://cran.r-project.org/web/packages/export/index.html and
for demo
https://github.com/tomwenseleers/export
Typical syntax is very easy, e.g.:
install.packages("export")
library(export)
library(ggplot2)
qplot(Sepal.Length, Petal.Length, data = iris, color = Species,
size = Petal.Width, alpha = I(0.7))
graph2doc(file="ggplot2_plot.docx", width=6, height=5)
graph2ppt(file="ggplot2_plot.pptx", width=6, height=5)
Output is vector format and so fully editable after you ungroup your graph in Word or Powerpoint. You can also use it to export statistical output of various R stats objects.
You can use R studio to knit html files with all of your plots and then open HTML files with Word.
knitr tutorial

Resources