knitr: cannot create a figure with utf-8 character - r

The following is my .Rnw file:
\documentclass{article}
\begin{document}
<<myChunk>>=
options(warn = 2)
library(ggplot2)
library(directlabels)
data(BodyWeight,package="nlme")
BodyWeight$temp <- as.character(BodyWeight$Rat)
BodyWeight$temp[BodyWeight$temp == "4"] <- "HI₂"
p <- qplot(Time,weight,data=BodyWeight,colour=temp,geom="line")
direct.label(p,"first.qp")
#
\end{document}
The following is how I call knitr from R:
library(knitr)
# I have tryied this but doesn't make difference:
# pdf.options(encoding='ISOLatin2.enc')
knit("mwe_knitr.Rnw")
I get following as output:
> knit("mwe_knitr.Rnw")
processing file: mwe_knitr.Rnw
|...................... | 33%
ordinary text without R code
|........................................... | 67%
label: myChunk
Quitting from lines 5-13 (mwe_knitr.Rnw)
Error in grid.Call(L_convert, x, as.integer(whatfrom), as.integer(whatto), :
(converted from warning) conversion failure on 'HI₂' in 'mbcsToSbcs': dot substituted for <e2>
I tried solutions with encoding, such as posted here:
Rhtml: Warning: conversion failure on '<var>' in 'mbcsToSbcs': dot substituted for <var>
(I note in comment above exactly where I try the solution to that problem) but it did not seem to change nothing for me.
I am using R 3.3.1 and knitr package 1.13 on Ubuntu.

It looks like using the cairo_pdf device resolves this issue. In the setup chunk below, I set the device option to the cairo_pdf device (that's the line that begins option(device = ...) and the global chunk option dev to default to "cairo_pdf" (in the line that begins knitr::opts_chunk$set(...). This approach is discussed in the knitr documentation (see the section Encoding of Multibyte Characters) and in Issue #436.
I've made a few other changes:
Instead of "hard-coding" "HI₂" I've used the Unicode symbol for the subscripted 2, "\U2082".
Changed the plot call to "standard" ggplot rather than qplot.
Changed from calling directlabels after making the plot to calling geom_dl to add direct labels within the "standard" ggplot workflow.
Set the fontfamily within geom_dl. I found that the subscript 2 was rendered with some font families, but not others.
Changed the warn option to zero (the default) so that warnings won't be turned into errors. I just did this while I was testing the code, but it can, of course, be set back to 2 if desired.
The chunk myChunk1a creates the plot. The chunk myChunk1b creates basically the same plot, but in multiple versions, each using a different font family. In these versions, you can see that the subscript 2 is rendered with some font families, but not others. I'm not sure what determines this and the results may be different on your system.
\documentclass{article}
\begin{document}
<<setup, include=FALSE>>=
options(warn = 0)
options(device = function(file, width = 7, height = 7, ...) {
cairo_pdf(tempfile(), width = width, height = height, ...)
})
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE, dev="cairo_pdf")
#
<<myChunk>>=
library(ggplot2)
library(directlabels)
library(gridExtra)
library(dplyr)
data(BodyWeight,package="nlme")
BodyWeight$temp <- as.character(BodyWeight$Rat)
BodyWeight$temp[BodyWeight$temp=="4"] = "HI\U2082"
# Change first value so that HI2 label is easily visible
BodyWeight$weight[BodyWeight$temp=="HI\U2082" & BodyWeight$Time==1] = 350
#
<<myChunk1a, fig.height=5>>=
ggplot(BodyWeight, aes(Time, weight, colour=temp)) +
geom_line() +
geom_dl(method=list("first.qp", fontfamily="Helvetica", cex=1), aes(label=temp)) +
theme_bw() +
ggtitle("Helvetica") +
guides(colour=FALSE)
#
<<myChunk1b, fig.height=11>>=
# Create several plots, each demonstrating a different font family for the labels
grid.arrange(grobs=lapply(c("Helvetica","Courier","Palatino","Times","Serif"), function(f) {
ggplot(BodyWeight, aes(Time, weight, colour=temp)) +
geom_line() +
geom_dl(method=list("first.qp", fontfamily=f, cex=1), aes(label=temp)) +
labs(x="") +
theme_bw() +
theme(plot.margin=unit(c(0,0,0,0), "lines"),
text=element_text(size=9)) +
ggtitle(f) +
guides(colour=FALSE)
}), ncol=1)
#
<<myChunk2, fig.height=5>>=
data(BodyWeight,package="nlme")
BodyWeight$temp <- as.character(BodyWeight$Rat)
# Change first value so that HI2 label is easily visible
BodyWeight$weight[BodyWeight$temp=="4" & BodyWeight$Time==1] = 350
# Set temp==4 to desired expression
BodyWeight$temp[BodyWeight$temp == "4"] <- paste(expression(HI[2]))
# Convert temp to factor to set order
BodyWeight$temp = factor(BodyWeight$temp, levels=unique(BodyWeight$temp))
qplot(Time, weight, data=BodyWeight, colour=temp, geom="line") +
guides(colour=FALSE) +
geom_text(data=BodyWeight %>% group_by(temp) %>%
filter(Time == min(Time)),
aes(label=temp, x=Time-0.5, y=weight), parse=TRUE, hjust=1) +
theme_bw()
#
\end{document}
Here's what the plot from myChunk1a looks like:

Related

ggplot2 does not show the graph in Latex (knitr)

I have an issue with knitr and ggplot2 in Latex. I am trying to create a dynamic document with knitr. All my plots are in ggplot2. Hear me out:
I created the Latex document
I opened it in R Studio and saved the TEX file as RNW file. Global and Project options: knitr.
I pasted the R script there like:
<<echo=FALSE>>=
knitr::opts_chunk$set(fig.path='graphs/',
echo=FALSE, warning=FALSE, message=FALSE)
#
<<>>=
library(ggplot2)
library(tidyverse)
#
<<plot1>>=
my_data1 <- read.csv(file.choose(), header=TRUE, sep=",")
plot1 <- ggplot(data=my_data1, aes(x = pos , y = sum)) +
geom_line(colour = 'black', size = 1) +
scale_y_continuous(trans = 'log10', limits = c(1,100)) +
theme_classic() +
labs (x = 'axis_name1', y = 'axis_name2') +
coord_cartesian(xlim = c(1219890,1220102)) +
#
Everything is going well, except the graph does not show when I press 'Compile PDF' or in the graphs directory. However when I select only the R code and run it everything is fine(as long as I add print()). I managed to use TikZ which works just fine but without creating a dynamic document. I thought it was possible to output the plot directly in the PDF document but for some reason ggplot2 does not work. Is there something that I am missing?
Thank you.

Modify external R script in a knitr chunk

I'm wondering if it's possible to hook into the code in an external R script that is read by knitr.
Specifically, say that you have the following R file
test.R
## ---- CarPlot
library(ggplot2)
CarPlot <- ggplot() +
stat_summary(data = mtcars,
aes(x = factor(gear),
y = mpg
),
fun.y = "mean",
geom = "bar"
)
CarPlot
Imagine that you wanted to use this graph in multiple reports, but in one of these reports you want the graph to have a title and in the other report you do not.
Ideally, I would like to be able to use the same external R script to be able to do this so that I do not have to make changes to multiple R files in case I decide to change something about the graph.
I thought that one way to perhaps do this would be by setting the fig.show chunk option to hold—since it will "hold all plots and output them in the very end of a code chunk"—and then appending a title to the plot like so:
test.Rnw
\documentclass{article}
\begin{document}
<<external-code, cache=FALSE,echo=FALSE>>=
read_chunk('./test.R')
#
<<CarPlot,echo=FALSE,fig.show='hold'>>=
CarPlot <- CarPlot + ggtitle("Plot about cars")
#
\end{document}
This, however, does not work. Although the plot is printed, the title that I tried to append does not show up.
Is there some way to do what I would like to do?
You don't want to show the plot created by test.R, so you should set fig.show = 'hide' or include = FALSE for that chunk:
<<external-code, cache=FALSE,echo=FALSE,fig.show = 'hide'>>=
read_chunk('./test.R')
#
You do want to show the plot after modification, so you have to print it:
<<CarPlot,echo=FALSE>>=
CarPlot <- CarPlot + ggtitle("Plot about cars")
CarPlot
#
fig.show = 'hold' is used if you have a large code chunk that prints a plot in the middle, but you don't want the plot to show in your document until the end. It doesn't apply to this case.

How can I use latex code in R plot? [duplicate]

I would like to add LaTeX typesetting to elements of plots in R (e.g: the title, axis labels, annotations, etc.) using either the combination of base/lattice or with ggplot2.
Questions:
Is there a way to get LaTeX into plots using these packages, and if so, how is it done?
If not, are there additional packages needed to accomplish this.
For example, in Python matplotlib compiles LaTeX via the text.usetex packages as discussed here: http://www.scipy.org/Cookbook/Matplotlib/UsingTex
Is there a similar process by which such plots can be generated in R?
The CRAN package latex2exp contains a TeX function that translate LaTeX formulas to R's plotmath expressions. You can use it anywhere you could enter mathematical annotations, such as axis labels, legend labels, and general text.
For example:
x <- seq(0, 4, length.out=100)
alpha <- 1:5
plot(x, xlim=c(0, 4), ylim=c(0, 10),
xlab='x', ylab=TeX(r'($\alpha x^\alpha$, where $\alpha \in \{1 \ldots 5\}$)'),
type='n', main=TeX(r'(Using $\LaTeX$ for plotting in base graphics!)', bold=TRUE))
for (a in alpha) {
lines(x, a*x^a, col=a)
}
legend('topleft',
legend=TeX(sprintf(r'($\alpha = %d$)', alpha)),
lwd=1,
col=alpha)
produces this plot.
Here's an example using ggplot2:
q <- qplot(cty, hwy, data = mpg, colour = displ)
q + xlab(expression(beta +frac(miles, gallon)))
As stolen from here, the following command correctly uses LaTeX to draw the title:
plot(1, main=expression(beta[1]))
See ?plotmath for more details.
You can generate tikz code from R:
http://r-forge.r-project.org/projects/tikzdevice/
Here's something from my own Lab Reports.
tickzDevice exports tikz images for LaTeX
Note, that in certain cases "\\" becomes "\" and "$" becomes "$\" as in the following R code: "$z\\frac{a}{b}$" -> "$\z\frac{a}{b}$\"
Also xtable exports tables to latex code
The code:
library(reshape2)
library(plyr)
library(ggplot2)
library(systemfit)
library(xtable)
require(graphics)
require(tikzDevice)
setwd("~/DataFolder/")
Lab5p9 <- read.csv (file="~/DataFolder/Lab5part9.csv", comment.char="#")
AR <- subset(Lab5p9,Region == "Forward.Active")
# make sure the data names aren't already in latex format, it interferes with the ggplot ~ # tikzDecice combo
colnames(AR) <- c("$V_{BB}[V]$", "$V_{RB}[V]$" , "$V_{RC}[V]$" , "$I_B[\\mu A]$" , "IC" , "$V_{BE}[V]$" , "$V_{CE}[V]$" , "beta" , "$I_E[mA]$")
# make sure the working directory is where you want your tikz file to go
setwd("~/TexImageFolder/")
# export plot as a .tex file in the tikz format
tikz('betaplot.tex', width = 6,height = 3.5,pointsize = 12) #define plot name size and font size
#define plot margin widths
par(mar=c(3,5,3,5)) # The syntax is mar=c(bottom, left, top, right).
ggplot(AR, aes(x=IC, y=beta)) + # define data set
geom_point(colour="#000000",size=1.5) + # use points
geom_smooth(method=loess,span=2) + # use smooth
theme_bw() + # no grey background
xlab("$I_C[mA]$") + # x axis label in latex format
ylab ("$\\beta$") + # y axis label in latex format
theme(axis.title.y=element_text(angle=0)) + # rotate y axis label
theme(axis.title.x=element_text(vjust=-0.5)) + # adjust x axis label down
theme(axis.title.y=element_text(hjust=-0.5)) + # adjust y axis lable left
theme(panel.grid.major=element_line(colour="grey80", size=0.5)) +# major grid color
theme(panel.grid.minor=element_line(colour="grey95", size=0.4)) +# minor grid color
scale_x_continuous(minor_breaks=seq(0,9.5,by=0.5)) +# adjust x minor grid spacing
scale_y_continuous(minor_breaks=seq(170,185,by=0.5)) + # adjust y minor grid spacing
theme(panel.border=element_rect(colour="black",size=.75))# border color and size
dev.off() # export file and exit tikzDevice function
Here's a cool function that lets you use the plotmath functionality, but with the expressions stored as objects of the character mode. This lets you manipulate them programmatically using paste or regular expression functions. I don't use ggplot, but it should work there as well:
express <- function(char.expressions){
return(parse(text=paste(char.expressions,collapse=";")))
}
par(mar=c(6,6,1,1))
plot(0,0,xlim=sym(),ylim=sym(),xaxt="n",yaxt="n",mgp=c(4,0.2,0),
xlab="axis(1,(-9:9)/10,tick.labels,las=2,cex.axis=0.8)",
ylab="axis(2,(-9:9)/10,express(tick.labels),las=1,cex.axis=0.8)")
tick.labels <- paste("x >=",(-9:9)/10)
# this is what you get if you just use tick.labels the regular way:
axis(1,(-9:9)/10,tick.labels,las=2,cex.axis=0.8)
# but if you express() them... voila!
axis(2,(-9:9)/10,express(tick.labels),las=1,cex.axis=0.8)
I did this a few years ago by outputting to a .fig format instead of directly to a .pdf; you write the titles including the latex code and use fig2ps or fig2pdf to create the final graphic file. The setup I had to do this broke with R 2.5; if I had to do it again I'd look into tikz instead, but am including this here anyway as another potential option.
My notes on how I did it using Sweave are here: http://www.stat.umn.edu/~arendahl/computing
I just have a workaround. One may first generate an eps file, then convert it back to pgf using the tool eps2pgf. See http://www.texample.net/tikz/examples/eps2pgf/
h <- rnorm(mean = 5, sd = 1, n = 1000)
hist(h, main = expression(paste("Sampled values, ", mu, "=5, ", sigma,
"=1")))
Taken from a very help article here https://stats.idre.ucla.edu/r/codefragments/greek_letters/
You can use the following, for example:
title(sub=TeX(sprintf(paste("Some latex symbols are ", r'(\lambda)', "and", r'(\alpha)'))))
Just remember to enclose LaTeX expressions in paste() using r'()'
You can also add named objects in the paste() function. E.g.,
lambda_variable <- 3
title(sub=TeX(sprintf(paste(r'(\lambda=)', lambda_variable))))
Not sure if there are better ways to do this, but the above worked for me :)

Dynamic references to figures in a R comment within Sweave document

I would like to find a way to use the LaTeX \ref{} markup to comment in the R code within a Sweave .Rnw file. Here are two examples, one in print
http://cm.bell-labs.com/cm/ms/departments/sia/project/nlme/UGuide.pdf
and one to use to work with:
The .Rnw file
% File: example.Rnw
\documentclass{article}
\usepackage{fullpage}
\usepackage{graphics}
\usepackage{Sweave}
\usepackage[margin = 10pt, font=small, labelfont={bf}]{caption}
\begin{document}
Here is an example file to show what I want to do. I would like to figure out how to use the \LaTeX\ reference command to reference a figure being generated by R code. Note in the R code, in a comment there is a reference to the figure, but of course the output file shows a verbatim copy of the \LaTeX\ markup. Does anyone know how to get something for Figure \ref{fig2}?
<< example plot >>=
library(reshape)
library(ggplot2)
n <- 100
lambda <- 1 / 3
x <- seq(0, qexp(0.999, rate = lambda), length = n)
q1.a <- data.frame(x = x,
f = dexp(x, rate = lambda),
F = pexp(x, rate = lambda))
q1.a <- melt(q1.a, id.vars = 'x')
g <- ggplot(q1.a) + # Produces \ref{fig1}
aes(x = x, y = value) +
geom_line() +
facet_wrap( ~ variable, scale = "free_y")
ggsave(g, filename = "example1.jpeg")
#
\begin{figure}[h]
\centering
\includegraphics[width = 0.48\textwidth]{./example1}
\caption{Exponential Distribution based plots.}
\label{fig1}
\end{figure}
Here is more of what I would like to see:
<< example plot 2 >>=
ggsave(g + geom_point(), filename = "example2.jpeg") # Produces Figure 2
#
\begin{figure}
\centering
\includegraphics[width = 0.48\textwidth]{./example2}
\caption{Exponential Distribution based plots with points and lines.}
\label{fig2}
\end{figure}
\end{document}
and the pdf is build with the R commands
Sweave(file = 'example.Rnw',
engine = "R",
keep.source = 'TRUE',
echo = 'TRUE',
results = 'verbatim')
tools::texi2dvi(file = "example.tex",
pdf = TRUE,
clean = TRUE)
Any insight on how do this would be great.
Here is one way to solve this issue by redefining the Sinput environment in which source code is wrapped by Sweave. By default, it is a simple verbatim environment which is not processed by latex for tokens. The trick is to redefine it to use the alltt environment which allows some tokens to be parsed inside the alltt environment. Note that this might lead to unwanted side effects that I am not aware of, so use with caution!
Here is a reproducible example that works. If you compile it, you will generate a file where ref{fig1} is replaced by the figure number.
\documentclass{article}
\usepackage{Sweave}
\usepackage{alltt}
\renewenvironment{Sinput}{\begin{alltt}}{\end{alltt}}
\begin{document}
In this document, we will create a plot using `R`, and reference its position in
the source code.
<<produce-plot, results = hide>>=
pdf('example1.pdf')
plot(1:10, 1:10) # Produces Figure \ref{fig1}
dev.off()
#
\begin{figure}
\includegraphics{example1.pdf}
\caption{Figure 1}
\label{fig1}
\end{figure}
\end{document}

Getting LaTeX into R Plots

I would like to add LaTeX typesetting to elements of plots in R (e.g: the title, axis labels, annotations, etc.) using either the combination of base/lattice or with ggplot2.
Questions:
Is there a way to get LaTeX into plots using these packages, and if so, how is it done?
If not, are there additional packages needed to accomplish this.
For example, in Python matplotlib compiles LaTeX via the text.usetex packages as discussed here: http://www.scipy.org/Cookbook/Matplotlib/UsingTex
Is there a similar process by which such plots can be generated in R?
The CRAN package latex2exp contains a TeX function that translate LaTeX formulas to R's plotmath expressions. You can use it anywhere you could enter mathematical annotations, such as axis labels, legend labels, and general text.
For example:
x <- seq(0, 4, length.out=100)
alpha <- 1:5
plot(x, xlim=c(0, 4), ylim=c(0, 10),
xlab='x', ylab=TeX(r'($\alpha x^\alpha$, where $\alpha \in \{1 \ldots 5\}$)'),
type='n', main=TeX(r'(Using $\LaTeX$ for plotting in base graphics!)', bold=TRUE))
for (a in alpha) {
lines(x, a*x^a, col=a)
}
legend('topleft',
legend=TeX(sprintf(r'($\alpha = %d$)', alpha)),
lwd=1,
col=alpha)
produces this plot.
Here's an example using ggplot2:
q <- qplot(cty, hwy, data = mpg, colour = displ)
q + xlab(expression(beta +frac(miles, gallon)))
As stolen from here, the following command correctly uses LaTeX to draw the title:
plot(1, main=expression(beta[1]))
See ?plotmath for more details.
You can generate tikz code from R:
http://r-forge.r-project.org/projects/tikzdevice/
Here's something from my own Lab Reports.
tickzDevice exports tikz images for LaTeX
Note, that in certain cases "\\" becomes "\" and "$" becomes "$\" as in the following R code: "$z\\frac{a}{b}$" -> "$\z\frac{a}{b}$\"
Also xtable exports tables to latex code
The code:
library(reshape2)
library(plyr)
library(ggplot2)
library(systemfit)
library(xtable)
require(graphics)
require(tikzDevice)
setwd("~/DataFolder/")
Lab5p9 <- read.csv (file="~/DataFolder/Lab5part9.csv", comment.char="#")
AR <- subset(Lab5p9,Region == "Forward.Active")
# make sure the data names aren't already in latex format, it interferes with the ggplot ~ # tikzDecice combo
colnames(AR) <- c("$V_{BB}[V]$", "$V_{RB}[V]$" , "$V_{RC}[V]$" , "$I_B[\\mu A]$" , "IC" , "$V_{BE}[V]$" , "$V_{CE}[V]$" , "beta" , "$I_E[mA]$")
# make sure the working directory is where you want your tikz file to go
setwd("~/TexImageFolder/")
# export plot as a .tex file in the tikz format
tikz('betaplot.tex', width = 6,height = 3.5,pointsize = 12) #define plot name size and font size
#define plot margin widths
par(mar=c(3,5,3,5)) # The syntax is mar=c(bottom, left, top, right).
ggplot(AR, aes(x=IC, y=beta)) + # define data set
geom_point(colour="#000000",size=1.5) + # use points
geom_smooth(method=loess,span=2) + # use smooth
theme_bw() + # no grey background
xlab("$I_C[mA]$") + # x axis label in latex format
ylab ("$\\beta$") + # y axis label in latex format
theme(axis.title.y=element_text(angle=0)) + # rotate y axis label
theme(axis.title.x=element_text(vjust=-0.5)) + # adjust x axis label down
theme(axis.title.y=element_text(hjust=-0.5)) + # adjust y axis lable left
theme(panel.grid.major=element_line(colour="grey80", size=0.5)) +# major grid color
theme(panel.grid.minor=element_line(colour="grey95", size=0.4)) +# minor grid color
scale_x_continuous(minor_breaks=seq(0,9.5,by=0.5)) +# adjust x minor grid spacing
scale_y_continuous(minor_breaks=seq(170,185,by=0.5)) + # adjust y minor grid spacing
theme(panel.border=element_rect(colour="black",size=.75))# border color and size
dev.off() # export file and exit tikzDevice function
Here's a cool function that lets you use the plotmath functionality, but with the expressions stored as objects of the character mode. This lets you manipulate them programmatically using paste or regular expression functions. I don't use ggplot, but it should work there as well:
express <- function(char.expressions){
return(parse(text=paste(char.expressions,collapse=";")))
}
par(mar=c(6,6,1,1))
plot(0,0,xlim=sym(),ylim=sym(),xaxt="n",yaxt="n",mgp=c(4,0.2,0),
xlab="axis(1,(-9:9)/10,tick.labels,las=2,cex.axis=0.8)",
ylab="axis(2,(-9:9)/10,express(tick.labels),las=1,cex.axis=0.8)")
tick.labels <- paste("x >=",(-9:9)/10)
# this is what you get if you just use tick.labels the regular way:
axis(1,(-9:9)/10,tick.labels,las=2,cex.axis=0.8)
# but if you express() them... voila!
axis(2,(-9:9)/10,express(tick.labels),las=1,cex.axis=0.8)
I did this a few years ago by outputting to a .fig format instead of directly to a .pdf; you write the titles including the latex code and use fig2ps or fig2pdf to create the final graphic file. The setup I had to do this broke with R 2.5; if I had to do it again I'd look into tikz instead, but am including this here anyway as another potential option.
My notes on how I did it using Sweave are here: http://www.stat.umn.edu/~arendahl/computing
I just have a workaround. One may first generate an eps file, then convert it back to pgf using the tool eps2pgf. See http://www.texample.net/tikz/examples/eps2pgf/
h <- rnorm(mean = 5, sd = 1, n = 1000)
hist(h, main = expression(paste("Sampled values, ", mu, "=5, ", sigma,
"=1")))
Taken from a very help article here https://stats.idre.ucla.edu/r/codefragments/greek_letters/
You can use the following, for example:
title(sub=TeX(sprintf(paste("Some latex symbols are ", r'(\lambda)', "and", r'(\alpha)'))))
Just remember to enclose LaTeX expressions in paste() using r'()'
You can also add named objects in the paste() function. E.g.,
lambda_variable <- 3
title(sub=TeX(sprintf(paste(r'(\lambda=)', lambda_variable))))
Not sure if there are better ways to do this, but the above worked for me :)

Resources