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

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)

Related

R plot title involving a subscript and value of a variable

In R, the value of the variable MyVar should be evaluated and appear in the title of a simple R plot p.
MyVar<-0.23
The plot p is called using
plot(p, main = MyTitle)
My plot title needs a subscript and should look like this:
What is the correct statement for MyTitle= ?
I tried dozens of variations using paste, expression, substitute, and bquote. Nothing seems to work...
Any help is highly appreciated!
Thanks a bunch!
Mark
I don't believe you can paste an expression to a variable (paste/print/cat/bquote/etc). As a workaround, you could use the "Fbelow=" expression as the title and use mtext to insert the value of MyVar, e.g.
MyVar<-0.23
plot(mtcars[2:3], main = expression('F'[below]*'='))
mtext(text = MyVar, side = 3, adj = 0.625, padj = -1.75, cex = 1.5)
Obviously this isn't ideal, but unless someone else has a clever way of solving your issue this will at least give you a potential option

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.

R - Text Formatting of Plot Text that is not hard-wired

I would like to add formatted text to a plot (title, axes labels, legend, etc.). A standard solution would be e.g.
plot(1, 1, ylab=substitute(lambda[1]))
where the y-axis label will be the greek letter λ with subscript 1. That is what I want but unfortunatelly it is hard-wired. I would like it to be flexible, i.e. to have an option to pass the text as an argument of a function. So, looking at r help, I found that the argument for substitute is an expression. So I've tried
sometext <- "lambda[1]"
e <- parse(text="sometext")
plot(1, 1, ylab=substitute(e))
But substitute ignores that e is an object an simply prints the text 'e' as the label. So instead I tried
plot(1, 1, ylab=eval(e))
which was better because eval at least evaluates the expression but the label now is literally 'lambda[1]', i.e. it is not evaluated as a greek letter λ with a subscript.
I then explicitly stated that 'e' is an expression doing
e <- expression(sometext)
and running the two previous plot commands but with the same results as before.
The closest I came to what I wanted ot achieve was doing
plot(1, 1, ylab=substitute(var[i], list(var="lambda", i=1)))
where at least the 1 is printed as a subscript but the text 'lambda' instead of the greek letter λ is printed.
Any suggestions on how can I achieve what the first command does but not hard-wired? E.g. using a string and somehow converting it to the right object so that it will be displayed properly? Thanks.
Daniel
You can pass the label as an expression like so and then use substitute inside the function:
dwat <- function(expr){
plot(1, 1, ylab = substitute(expr))
}
dwat(lambda[1])
dwat(mu[2])
If you want to pass a string instead of an expression use parse:
dwat_string <- function(string){
plot(1, 1, ylab = parse(text = string))
}
dwat_string("mu[1]")
Another option would be to use the ellipsis approach. That way you can pass an xlab or any other argument to plot:
dwat2 <- function(...){
plot(1, 1, ...)
}
dwat2(ylab = expression(lambda[1]))
you were close, checks if this works
substitute(lambda[i],list(i=i))

R axis text no dots

I want to add the following x-axis label to my bar plot but unfortunately R does not recognize the character '!' and prints dots instead of whitespaces:
I want: I get:
!src x.x.x.x X.src.x.x.x.x
!TCP X.TCP
!udp && !src x.x.x.x X.udp.....src.x.x.x.x
Additionally a would like to increase the margin because the text is to long and when setting the size over 'cex.names=0.6' then it just vanishes!?
There are two reason I can think of that R will have substituted X. for instances of !.
I suspect that the labelling you are seeing is due to R's reading of your data. Those column names aren't really syntactically valid and the erroneous character has been replaced by X.. This happens at the data import stage, so I presume you didn't check how R had read your data in?, or
You have a vector and the names of that vector are similarly invalid and R has done the conversion.
However, as you haven't made this reproducible it could be anything.
To deal with case 1 above, either edit your data file to contain valid names or pass check.names = FALSE in your read.table() call used to read in the data. Although doing the latter will make it difficult for you to select variable by name without quoting the name fully.
If you have a vector, then you can reset the names again:
> vec <- 1:5
> names(vec) <- paste0("!",LETTERS[1:5])
> vec
!A !B !C !D !E
1 2 3 4 5
> barplot(vec)
Also note that barplot() has a names.arg argument that you can use to pass it the labels to draw beneath each bar. For example:
> barplot(vec, names.arg = paste0("!", letters[1:5]))
which means you don't need to rely on what R has read in/converted for you as you tell it exactly what to label the plot with.
To increase the size of the margin, there are several ways to specify the size but I find setting it in terms of number of lines most useful. You change this via graphical parameter mar, which has the defaults c(5,4,4,2) + 0.1 which correspond to the bottom, left, top, and right margins respectively. Use par() to change the defaults, for example in the code below the defaults are store in op and a much larger bottom margin specified
op <- par(mar = c(10,4,4,2) + 0.1)
barplot(vec, names.arg = paste0("!", letters[1:5]), las = 2)
par(op) ## reset
The las = 2 will rotate the bar labels 90 degrees to be perpendicular to the axis.
One option is to use ann=F and add anotation to the plot using mtext.
x <- 1:2
y <- runif(2, 0, 100)
par(mar=c(4, 4, 2, 4))
plot(x, y, type="l", xlim=c(0.5, 2.5), ylim=c(-10, 110),
axes=TRUE, ann=FALSE)
Then add annotation:
mtext("!udp && !src x.x.x.x ", side=1, line=2)
Edit It is a question of a barplot and not simple plot.
as said in Gavin solution, the names argument can be setted. Here I show an example.
barplot(VADeaths[1:2,], angle = c(45, 135),
density = 20, col = "grey",
names=c("!src x.x.x.x", "!TCP", "!udp && !src x.x.x.x", "UF"),
horiz=FALSE)

Using subscript and variable values at the same time in Axis titles in R

I want to use the title "CO2 emissions in wetlands" in a plot in R, whereas the 2 in CO2 is in subscript, and the value for the region (here: "wetlands") is contained in a variable named "region".
region = "wetlands"
plot (1, 1, main=expression(CO[2]~paste(" emissions in ", region)))
The problem is, that not the value of the variable is pasted, but the name of the variable. This gives "CO2 emissions in region" instead of "CO2 emissions in wetlands". I also tried:
region="wetlands"
plot (1,1,main=paste(expression(CO[2]), "emissions in", region))
But the subscript is not done here, and the title is: "CO[2] emissions in wetlands".
Is it somehow possible to get values of variables into expression?
Thanks for your help,
Sven
There is no need to use paste() in producing an expression for plothmath-style annotation. This works just fine:
region <- "foo"
plot (1, 1, main = bquote(CO[2] ~ "emissions in" ~ .(region)))
giving:
Using paste() just gets in the way.
Nb: You have to quote "in" because the parser grabs it as a key part of R syntax otherwise.
You can use substitute:
mn <- substitute(CO[2]~ "emissions in" ~ region, list(region="wetlands") )
plot(1, 1, main=mn )
From the ?substitute help file:
The typical use of substitute is to create informative labels for
data sets and plots. The myplot example below shows a simple use of
this facility. It uses the functions deparse and substitute to create
labels for a plot which are character string versions of the actual
arguments to the function myplot.
For your case, stolen from one of the answers at the duplicated link:
x <- "OberKrain"
plot(1:10, 1:10, main = bquote(paste(CO[2], " in ", .(x))))

Resources