Transform numbers with exponents to plotmath commands for beautiful legends in R - r

I'm trying to generate a beautiful legend in R plots. I have a factor=1e-5, that should appear nicely formatted in the legend. I found a nice function in the package sfsmisc, that transforms numbers to expressions. To add this expression to my bquote command, it seems that I need to transform itto a call. unfortunately, there are braces added at the end of the string (10^-5()).
Is there a way to avoid the addition of thoses braces? Or is there even an easier way to transform numbers to plotmaths commands for their use in legends? (without doing it manually)
factor = 1e-5
alpha = 1:10
omega = alpha^2 * factor
plot (
alpha
, omega
, xlab=bquote(alpha)
, ylab=bquote(omega)
, type="b"
)
text = expression()
# standard version
text[1] = as.expression(bquote(alpha%*%.(factor)))
# beautified version (use pretty10exp from sfsmisc package!?)
library("sfsmisc")
pretty = as.call(pretty10exp(factor, drop.1=T))
text[1] = as.expression(bquote(alpha^2%*%.(pretty)))
# add legend
legend("topleft", legend=text, pch=1, lty=1)

Here's what you can do instead with function parse:
text <- paste("alpha^2%*%",parse(text=pretty10exp(factor,drop.1=T)),sep="")
text
[1] "alpha^2%*%10^-5" # which we then use as the expression in your call to legend
legend("topleft", legend=parse(text=text), pch=1, lty=1)
See ?parse for more explanation on how this work.

Related

In R, why is there awkward output in the legend when I am using paste() instead of c() in addition to pretty10exp()?

I'm trying to make the legend of this plot pretty, so I need there the be an actual superscript, which is why I am using the pretty10exp() function from the sfsmisc library. It works when I use the c() function.
However, I am also trying to keep the string and the scientific notation number on the same line. The legend() is broken into two lines, which I think is due to c(). I thought I could use paste(), but for some reason the output is now incorrect.
plot(1:12)
pVal <- 4
legend("topright", legend = c("P value:", sfsmisc::pretty10exp(pVal)), cex = 1.5)
legend("topright", legend = paste("P value:", sfsmisc::pretty10exp(pVal)), cex = 1.5)
pVal being an arbitrary number represented in scientific notation. The second line results in output like this: "P value: (significand) %*% 10^-4". The first line also doesn't give me what I want. How can I fix this problem?
pretty10exp returns an expression which allows it to use the ?plotmath features for making nice looking numbers. When working with expressions, you can't just paste values in like strings. You need to manipulate them with a special set of functions. One such function is substitute. You can do
plot(1:12)
pVal <- 4
legend("topright", cex = 1.5,
legend = substitute("P value: "*x, list(x=sfsmisc::pretty10exp(pVal)[[1]])) )
We use substitute() to take the value contained in the expression from pretty10exp and prefix it with the label you want. (We use * to concatenate rather than paste() since plotmath allows it)
This is what I would do:
fun <- function(text, pVal) {
y <- floor(log10(pVal))
x <- pVal / 10^y
bquote(.(text)*":" ~ .(x) %.% 10 ^ .(y))
}
plot.new()
text(0.5,0.7,fun("P value", 0.4))
text(0.5, 0.3, fun("P value", signif(1/pi, 1)))
No package is needed.

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 :)

R legend pch mix of character and numeric

Is it possible to use a mix of character and number as plotting symbols in R legend?
plot(x=c(2,4,8),y=c(5,4,2),pch=16)
points(x=c(3,5),y=c(2,4),pch="+")
legend(7,4.5,pch=c("+",16),legend=c("A","B")) #This is the problem
Use the numerical equivalent of the "+" character:
plot(x=c(2,4,8),y=c(5,4,2),pch=16)
points(x=c(3,5),y=c(2,4),pch="+")
legend(7,4.5,pch=c(43,16),legend=c("A","B"))
There are actually numerical equivalents for all symbols!
Source: Dave Roberts
The pch code is the concatenation of the Y and X coordinates of the above plot.
For example, the + symbol is in row (Y) 4 and column (X) 3, and therefore can be drawn using pch = 43.
Example:
plot(x=c(2,4,8),y=c(5,4,2),pch=16)
points(x=c(3,5),y=c(2,4),pch="+")
legend(7,4.5,pch=c(43,16),legend=c("A","B"))
My first thought is to plot the legend twice, once to print the character symbols and once to print the numeric ones:
plot(x=c(2,4,8),y=c(5,4,2),pch=16)
points(x=c(3,5),y=c(2,4),pch="+")
legend(7,4.5,pch=c(NA,16),legend=c("A","B")) # NA means don't plot pt. character
legend(7,4.5,pch=c("+",NA),legend=c("A","B"))
NOTE: Oddly, this works in R's native graphical device (on Windows) and in pdf(), but not in bmp() or png() devices ...
I bumped to this issue several time, so I wrote a tiny function below. You can use to specify the pch value, e.g.
pch=c(15:17,s2n("|"))
String to Numeric
As noted in previous answers, you can simply add the numerical equivalent of the numeric and character symbols you want to plot.
However, just a related aside: if you want to plot larger numbers (e.g., > 100) or strings (e.g., 'ABC') as symbols, you need to use a totally different approach based on using text().
`Plot(x,y,dat,type='n') ; text(x,y,labels = c(100,'ABC')
Creating a legend in this case is more complicated, and the best approach I've ever come up with is to stack legends on top of each other and using the legend argument for both the pch symbol and the description:
pchs <- c(100,'ABC','540',sum(13+200),'SO77')
plot(1:5,1:5,type='n',xlim=c(1,5.1))
text(1:5,1:5,labels = pchs)
legend(3.5,3,legend = pchs,bty='n',title = '')
legend(3.5,3,legend = paste(strrep(' ',12),'ID#',pchs),bty='n',title='Legend')
rect(xleft = 3.7, ybottom = 1.5, xright = 5.1, ytop = 3)
This uses strrep to concatenate spaces in order to shift the text over from the "symbols", and it uses rect to retroactively fit a box around the printed legend text.

How to add nice formated anotations to a R base graph using expression and the value of a variable?

Say, I have a variable rv which has some numerical value. Now, I want to plot the value of this variable on a base plot but preceded by a nicely formatted symbol e.g., r subscript m, using expression. To write on the plot I use mtext.
However, what I get is either the value of the variable, but no nicely formatted symbol (left annotation), or a nicely formatted symbol, but not the value of the variable, but the variable name...
I tried to play around with eval, but didn't get what I wanted. Here is my code:
plot(1:10, rep(10,10), ylim=c(0,12))
rv <- 0.43
#left annotation:
mtext(paste(expression(italic(r[M])), " = ", rv), side = 1, line = -1.5, adj = 0.1)
#right annotation:
mtext(expression(paste(italic(r[M]), " = ", rv)), side = 1, line = -1.5, adj = 0.9)
This is the result:
How do i get both, nice format and value of the variable? Thanks.
btw: I know that I can get it, if I use two times mtext and play around with adj and stuff. But I would really like to get it in one call or without playing around with the position of two annotations.
The bquote function will create an expression and alow substitution of values using .(var) syntax. for your case do something like:
text( 5,1, bquote( italic(r[M]) == .(rv) ) )
Just combine what you have and plot two pieces, joined by using adj:
R> plot(1:10, rep(10,10), ylim=c(0,12))
R> text(2,12, expression(paste(italic(r[M]))), adj=1)
R> text(2,12, paste("=", rv), adj=0)

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