RMarkdown won't knit ggplot2 plot after changing font - r

The plot below was generated in R (without any issue), using this code:
library(tidyverse)
library(extrafont)
loadfonts()
x <- rexp(100)
data.frame(info = x) %>%
ggplot() +
geom_histogram(aes(x = info), col = "red", fill = "red", alpha = 0.5) +
theme_minimal() +
theme(text = element_text(family="LM Roman 10"))
As you can see, the font of the plot is set to "LM Roman 10", which I was able to do thanks to this post and it works perfectly within R.
However when I try to place the image in a LaTeX document using RMarkdown, I get this error:
Quitting from lines 10-22 (min_example.Rmd)
Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
invalid font type
Calls: <Anonymous> ... drawDetails -> drawDetails.text -> grid.Call.graphics
Además: There were 50 or more warnings (use warnings() to see the first 50)
Ejecución interrumpida
Here is the code for min_example.Rmd
---
title: "Untitled"
author: "Javier Rojas"
date: "2/9/2020"
output: pdf_document
---
```{r, echo=FALSE}
library(tidyverse)
library(extrafont)
loadfonts()
x <- rexp(100)
data.frame(info = x) %>%
ggplot() +
geom_histogram(aes(x = info), col = "red", fill = "red", alpha = 0.5) +
theme_minimal() +
theme(text = element_text(family="LM Roman 10"))
```
I am using a Mac computer running macOS High Sierra and R 3.6.1

Usually quite easy to solve. The problem should be, that the font is not installed in your computer.
You have to download the .otf file for the font e.g. (https://fonts2u.com/lmroman10-regular.font) and install it on your Operating System.
If you don't know how to do this, just google it (e.g. "install extra font Windows"), there are plenty of tutorials on it online.
-edit-
I was a little to quick - didn't realize the problem just comes from running it in rmarkdown. Try the following:
```{r, fig.showtext=TRUE, echo=FALSE}
library("tidyverse")
library("showtext")
x <- rexp(100)
font_add("LM Roman 10", regular = "lmroman10-regular.otf")
data.frame(info = x) %>%
ggplot() +
geom_histogram(aes(x = info), col = "red", fill = "red", alpha = 0.5) +
theme_minimal() +
theme(text = element_text(family="LM Roman 10"))
```
It's important that you add fig.showtext=TRUE, library("showtext") and font_add("LM Roman 10", regular = "lmroman10-regular.otf").
I just placed the .otf in my project folder - but I think you can also give it another path.

There exists a current new approach using showtext and showtextdb packages.
On Windows, install manually Latin Modern Roman font (.tff version) following these steps easy instructions https://tex.stackexchange.com/questions/55787/latin-modern-roman-for-ttf. After the installation, you can locate all your fonts in "C:/Windows/Fonts/" just in case.
Once it's already installed, try the following R code to see and example:
install.packages("showtext")
install.packages("showtextdb")
library(showtext)
library(showtextdb)
#set the name and file path
font_add(family = "lmroman10", regular = "C:/Windows/Fonts/lmroman10-regular-webfont.ttf")
showtext_auto()
library(ggplot2)
p = ggplot(NULL, aes(x = 1, y = 1)) + ylim(0.8, 1.2) +
theme(axis.title = element_blank(), axis.ticks = element_blank(),
axis.text = element_blank()) +
annotate("text", 1, 1.1, family = "lmroman10", size = 15,
label = "Text using new font")

Related

Unicode character not shown in pdf file after embeding fonts with extrafonts package

I am trying to embed the ≤ sign into the fonts of my pdf plot. The ≤ sign is shown in the plot when viewed within RStudio (p1). However, when I save the plot and embed the fonts the ≤ sign is converted to an = sign.
Using the extrafont package I want to save my plot with the CM Roman font. I have tried alternative methods with the device set as cairo_pdf in ggsave(). This embeds the ≤ sign into the pdf, but the font is no longer CM Roman.
What needs to be done so that the ≤ sign remains in the plot and the font is CM Roman?
library(ggplot2)
library(extrafont)
font_import()
font_install("fontcm")
loadfonts()
df <- data.frame(foo = c(2, 4, 8 , 16),
bar = factor(c(1:3, "4\u2264")))
p1 <- ggplot(df, aes(x = bar, y = foo)) +
geom_bar(stat="identity") +
labs(title = "p1: Equality sign shows in RStudio plot") +
theme(text = element_text(family = "CM Roman", size = 25))
p2 <- ggplot(df, aes(x = bar, y = foo)) +
geom_bar(stat="identity") +
labs(title = "p2: Equality sign not shown in .pdf file") +
theme(text = element_text(family = "CM Roman", size = 25))
print(p1)
[![p1 plot][1]][1] # there should be an image of p1 here...
# Sys.setenv(R_GSCMD = "C:/Program Files/gs/gs9.53.3/bin/gswin64c.exe") #~ run once at start of each R session
ggsave("p2.pdf", p2, width = 15, height = 10, units = "in")
embed_fonts("p2.pdf", outfile="p2.pdf")
[![p2 plot][1]][1] # there should be an image of p2 here...
ggsave losing unicode characters from ggplot+gridExtra
There are several solutions in this post. I think it has to do something with encoding, but I am not 100% sure.

ggsave with non-ASCII plotmath labels using cairo

I have a non-ASCII axis label with a plotmath expression. When I try to save as png using cairo, I get an error:
library(ggplot2)
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab(expression(`cÜl`~italic(r)(italic(M)))) +
xlab(expression(hp~italic(hp))),
device = grDevices::png,
type = "cairo")
The error message is:
Metric information not available for this family/device
On the other hand, using the "windows" device works (except for a warning):
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab(expression(`cÜl`~italic(r)(italic(M)))) +
xlab(expression(hp~italic(hp))),
device = grDevices::png,
type = "windows")
The warning (in German) is:
In dev(filename = filename, width = dim[1], height = dim[2], ...) :
'width=7, height=7' sind unwahrscheinliche Pixelzahlen
Finally, non-ASCII axis labels are not a problem per se, if the label is not a plotmath expression:
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab("cÜl") +
xlab(expression(hp~italic(hp))),
device = grDevices::png,
type = "cairo")
The last command raises no error.
However, I would prefer to use cairo, since it draws nicer pictures sometimes. Any ideas?
This worked on a Windows machine with R 4.0.2 (and also on linux):
library(ggplot2)
library(ggtext)
ggsave("test.png", width = 6, height = 6,
qplot(mtcars$hp, mtcars$cyl) +
labs(x = "hp *hp*",
y = "c\u00DCl *r*(*M*)") +
theme(
axis.title.x = element_markdown(),
axis.title.y = element_markdown()
),
type = "cairo-png")
Created on 2020-07-07 by the reprex package (v0.3.0)
This works for me (though I am not on windows); try leaving out the device parameter:
library(ggplot2)
ggsave("test.png",
qplot(mtcars$hp, mtcars$cyl) +
ylab(expression(`cÜl`~italic(r)(italic(M)))) +
xlab(expression(hp~italic(hp))),
type = "cairo-png")
#> Saving 7 x 5 in image
Created on 2020-07-05 by the reprex package (v0.3.0)

Cannot embed ggplot2 (/R) fonts in PDF with ggsave()

I have added a font to my ggplot2-plot, and it works perfectly when viewed in RStudio's plot viewer. However, when I try to save the plot as a PDF, NO text at all is printed (see code and pictures below):
df <- data.frame(x = c(1:10), y = c(1:10)) # Dummy data
plot <- ggplot(df, aes(x, y)) + # Dummy plot
geom_point() +
labs(title = "Correct font in R, NO fonts at all in pdf :-(") +
theme(text = element_text(family = "latex"))
Then I try to ggsave() the plot with the following code:
ggsave("df_plot.pdf",
plot = plot,
device = "pdf",
dpi = 320)
But I get an error message:
Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x,
x$y, : invalid font type
Below is the plot with the correct fonts (in RStudio) + the plot that is written to my pdf file (with no fonts at all):
Plot with correct font
Plot witn NO text
What am I missing here? I've tried various stuff with the extrafont package, but the pdfs don't print the fonts there either (if something is printed, its just the default fonts).
Actually, ggsave() appears to work fine for me. The error is actually adding the theme(text = element_text(family = "latex")) to the plot.
Adjusting the example a little bit,
df <- data.frame(x = c(1:10), y = c(1:10)) # Dummy data
plot <- ggplot(df, aes(x, y)) + # Dummy plot
geom_point() +
labs(title = "Correct font in R, NO fonts at all in pdf :-(")
ggsave("df_plot.pdf",
plot = plot,
device = "pdf",
dpi = 320)
#Saving 10.7 x 8.01 in image
But,
plot + theme(text = element_text(size=10, family="LM Roman 10"))
produces the error you've found:
Error in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
polygon edge not found.
This question has already been answered here:
Error in grid.Call(L_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : Polygon edge not found
Do these suggestions work for you?
you may consider using the extrafont package:
library(tidyverse)
library(extrafont)
fonts()
df <- data.frame(x = c(1:10), y = c(1:10)) # Dummy data
windowsFonts(Calibri = windowsFont("Calibri"))
plot <- ggplot(df, aes(x, y)) + # Dummy plot
geom_point() +
labs(title = "Correct font in R, NO fonts at all in pdf :-(") +
theme(text = element_text(size=15, family= "Tw Cen MT Condensed Extra Bold"))
ggsave("df_plot.pdf",
plot = plot,
device = cairo_pdf,
dpi = 320)

RMarkdown not printing Chinese characters in graphs

---
title:
output:
pdf_document:
latex_engine: xelatex
fontsize: 11pt
#mainfont: Calibri
classoption: letter
geometry: left=0.5in, right=0.5in, top=0.6in, bottom=1.25in
subparagraph: yes
header-includes:
- \usepackage[UTF8]{ctex}
- \usepackage{setspace}
- \usepackage{tocloft}
- \usepackage{anyfontsize}
- \usepackage{fancyhdr}
- \usepackage{fontspec}
- \usepackage{sectsty}
- \sectionfont{\huge}
- \subsectionfont{\fontsize{14}{16.8}\selectfont}
- \pagestyle{fancy}
- \renewcommand{\headrulewidth}{0pt}
---
```{r}
library(ggplot2)
print("中文")
df <- data.frame(
gp = factor(rep(letters[1:3], each = 10)),
y = rnorm(30)
)
ds <- plyr::ddply(df, "gp", plyr::summarise, mean = mean(y), sd = sd(y))
# The summary data frame ds is used to plot larger red points on top
# of the raw data. Note that we don't need to supply `data` or `mapping`
# in each layer because the defaults from ggplot() are used.
ggplot(df, aes(gp, y)) +
geom_point() +
geom_point(data = ds, aes(y = mean), colour = 'red', size = 3) +
labs(x = "中文")
```
After knitting this file, it seems that the character encoding works fine for the print function, but the Chinese characters do not show up in graph labels, and I get errors on character conversions. I am a Mac user.
TL;DR: This doesn't appear to be a knitr/rmarkdown issue, but rather an issue related to both the font and the output device. I'm not sure of the cause, but the workaround below involves changing the output font (Batang worked for me) and the output device (pdf is the default, but changing to cairo_pdf or png both worked for me).
First, identify a font family for which R will render the characters properly. I'm not sure in general how to determine this without trial and error, but in the past I've found that the Symbola and Batang fonts often seem to work with non-English characters and various unicode symbols. You'll need to install the fonts on your computer if you don't have them, and you also might need to use the extrafont package to register the fonts in R. Then you can run the plot code in the console and see if the Chinese characters render properly.
With the Batang font, I found that I was able to output plots to the console with the Chinese characters rendered properly. However, the standard pdf device failed to render the characters, whether saving the plot to pdf interactively or when knitting. Instead I tried the cairo_pdf and png devices and these both worked. Here's example code (using the same yaml as in your question):
```{r, include=FALSE}
knitr::opts_chunk$set(echo=FALSE)
library(ggplot2)
```
```{r, dev="cairo_pdf"}
df <- data.frame(
gp = factor(rep(letters[1:3], each = 10)),
y = rnorm(30)
)
ds <- plyr::ddply(df, "gp", plyr::summarise, mean = mean(y), sd = sd(y))
ggplot(df, aes(gp, y)) +
geom_point() +
geom_point(data = ds, aes(y = mean), colour = 'red', size = 3) +
labs(x = "中文", title="cairo_pdf device") +
#theme(axis.title.x=element_text(family="Batang")) # To change font only for x-axis title
theme(text=element_text(family="Batang", size=15))
```
```{r, dev="png", dpi=400}
ggplot(df, aes(gp, y)) +
geom_point() +
geom_point(data = ds, aes(y = mean), colour = 'red', size = 3) +
labs(x = "中文", title="png device") +
theme(text=element_text(family="Batang", size=15))
```
And here's what the plots look like in the output document:

Embed ggplot2 Graph in Knitr Document: Unable to find function ggplot

I am working on a document and am using both knitr and ggplot2. I am new to knitr and TeX itself and therefore not overly familiar with all that I am doing.
When I open RStudio to do the work, I first run the following two commands:
require("knitr")
require("ggplot2")
I then click on the Compile PDF. I have the following code that throws an error:
<<histogram, echo=FALSE, fig.align='center'>>=
summary(los$hosp_svc)
summary(los$Pt_Age)
binsize = diff(range(los$Pt_Age)/30)
ggplot(los, aes(x = Pt_Age)) +
geom_histogram(binwidth = binsize, fill = "red",
alpha = 0.315, colour = 'black') +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
xlab("Patient Age in Years") +
ylab("Frequency/Count") +
ggtitle("Histogram of Patient Age")
#
The error that I am getting is that the ggplot function could not be found, which is odd because if I just run the above code in the console the graph produces just find, so I know the package is loaded and available for use.
Any thoughts?
Thank you,
When working with .Rnw files (or .Rmd files), be sure to include any library calls in your script (see below). When you press the "Compile PDF" button, the R code in your script is submitted to a new instance of R to prevent anything in your current environment from mucking up the results. This might seem a little strange, but is good for reproducibility. So objects that aren't created explicitly via your script and packages that aren't called explicitly in your script will be forgotten as soon as you hit "Compile PDF"
<<histogram, echo=FALSE, fig.align='center'>>=
library(ggplot2)
summary(los$hosp_svc)
summary(los$Pt_Age)
binsize = diff(range(los$Pt_Age)/30)
ggplot(los, aes(x = Pt_Age)) +
geom_histogram(binwidth = binsize,
fill = "red",
alpha = 0.315,
colour = 'black') +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank()) +
xlab("Patient Age in Years") +
ylab("Frequency/Count") +
ggtitle("Histogram of Patient Age")
#

Resources