I'm using annotate() to overlay text on one of my ggplot2 plots. I'm using the option parse=T because I need to use the Greek letter rho. I'd like the text to say = -0.50, but the trailing zero gets clipped and I get -0.5 instead.
Here's an example:
library(ggplot2)
x<-rnorm(50)
y<-rnorm(50)
df<-data.frame(x,y)
ggplot(data=df,aes(x=x,y=y))+
geom_point()+
annotate(geom="text",x=1,y=1,label="rho==-0.50",parse=T)
Does anyone know how I can get the last 0 to show up? I thought I could use paste() like this:
annotate(geom="text",x=1,y=1,label=paste("rho==-0.5","0",sep=""),parse=T)
but then I get the error:
Error in parse(text = lab) : <text>:1:11: unexpected numeric constant
1: rho==-0.5 0
^
It is an plotmath expression parsing problem; it's not ggplot2 related.
What you can do is ensure that 0.50 is interpreted as a character string, not a numeric value which will be rounded:
ggplot(data=df, aes(x=x, y=y)) +
geom_point() +
annotate(geom="text", x=1, y=1, label="rho=='-0.50'", parse=T)
You would get the same behavior using base:
plot(1, type ='n')
text(1.2, 1.2, expression(rho=='-0.50'))
text(0.8, 0.8, expression(rho==0.50))
If you want a more general approach, try something like
sprintf('rho == "%1.2f"',0.5)
There is an r-help thread related to this issue.
Related
I need to render in boldface the labels of the legend of a graph. One of the labels is an expression containing a "lower or equal" sign.
This is where I started from:
library(ggplot2)
df <- data.frame(x=factor(rep(0:1, 10)), y=rnorm(10), z=factor(rep(0:1, 10)))
ggplot(df, aes(x, y, shape=z)) +
geom_point() +
scale_shape_discrete(labels=c("Age > 65", expression(Age <= 65))) +
theme(legend.text=element_text(face="bold"))
In this way, the first label is bold, but the second is not. Following the suggestion here I tried to use plotmath bold():
library(ggplot2)
df <- data.frame(x=factor(rep(0:1, 10)), y=rnorm(10), z=factor(rep(0:1, 10)))
ggplot(aes(x, y, shape=z)) +
geom_point() +
scale_shape_discrete(labels=c("Age > 65", expression(bold(Age <= 65)))) +
theme(legend.text=element_text(face="bold"))
The label is rendered in bold only up to the "<=" sign. I have also tried to put the second part of the string within bold():
expression(bold(Age bold(<= 65)))
but to no avail. Any help is appreciated.
Tucked away in the plotmath documentation is the following:
Note that bold, italic and bolditalic do not apply to symbols, and hence not to the Greek symbols such as mu which are displayed in the symbol font. They also do not apply to numeric constants.
Instead, a suggested approach is to use unicode (assuming font and device support) which, in this case, means we can dispense with plotmath altogether.
ggplot(df, aes(x, y, shape=z)) +
geom_point() +
scale_shape_discrete(labels=c("Age > 65", "Age \U2264 65")) +
theme(legend.text=element_text(face="bold"))
While it is a little overkill for this particular issue, package ggtext makes complicated labels in ggplot2 a lot easier. It allows the use of Markdown and HTML syntax for text rendering.
Here's one way to write your legend text labels, using Markdown's ** for bolding and HTML's ≤ for the symbol.
library(ggtext)
ggplot(df, aes(x, y, shape=z)) +
geom_point() +
scale_shape_discrete(labels=c("**Age > 65**", "**Age ≤ 65**")) +
theme(legend.text=element_markdown())
(I'm on a Windows machine, and the default windows graphics device can have problems with adding extra spaces to symbols. Using ragg::agg_png() avoids the issue when saving plots, but also the next version of RStudio will allow you to change the graphics backend to bypass these problems.)
The function below is a character by character exact copy of a function appearing on page 26 of the second edition of Hadley Wickham's ggplot2 book, with two exceptions:
The output is assigned to p, which is then plotted.
The expression following "colour = " in the original was
"year(date)".
If you take year(economics$date), you get a numeric vector running from 1967 to 2015, inclusive, by ones. I have replaced that expression with 1967:2015. The result is an error:
Error: Aesthetics must be either length 1 or the same as the data (574): colour
I have two questions.
year <- function(x) as.POSIXlt(x)$year + 1900
p <- ggplot(economics, aes(unemploy / pop, uempmed)) +
geom_path(colour = "grey50") +
geom_point(aes(colour = 1967:2015))
plot(p)
Why on earth does this trivial change break the function?
Why did the function work in the first place? (It does). Because if you look at
the documentation for the colour esthetic, here:
https://ggplot2.tidyverse.org/articles/ggplot2-specs.html it
does not say that the colour esthetic takes either a numerical
vector or a function.
I have searched here for a while and my question was partially answered by previous questions/answers. I am learning R, coming from Matlab. As the title says, I have a question about plot annotations. In Matlab it was fairly straightforward to have plot annotations that contained all sorts of data formats, and I am looking for something similar in R. I have already discovered paste and managed to put text and numbers into one annotation and I also figured out (to a degree...) what parse does, for example when displaying an r squared. My question is, how do I combine the two annotations in the code snippet into one annotation without R yelling at me? My solution with two annotations works for what I need, but I simply would like to know how to do it...
a <- 30 # some coefficients
b <- 70
r2 <- 0.87
anno1 <- paste("y = ",b,"ln(x) + ",a) # first annotation with a random equation
anno2 <- paste("r^2 == ", r2) # second annotation with a random r squared
Pdata <- data.frame("X" = 1:10, "Y" = 1:10) # some data
ggplot(Pdata,aes(x=Pdata$X,y=Pdata$Y)) +
geom_point() +
annotate("text", x=2, y=8, label=anno1, parse=FALSE) +
annotate("text", x=2, y=7, label=anno2, parse=TRUE)
Thanks y'all!
It took a while for me to figure this out (for my own projects), but here's a solution:
anno3 <- paste("'y ='~",b,"~'ln(x) +'~",a,"~r^2==~", r2)
Add it to your plot using + annotate("text", x=2, y=6, label=anno3, parse=TRUE)
The single quote identifies text to not evaluate. Combined, the pasted result should be written like an expression.
Here is one way to do the requested operation by using bquote
ggplot() +
geom_point(aes(x = 1:4, y = 1:4)) +
annotate("text", x=2, y=3,
label = deparse(bquote(~y ==~ .(b) ~ln(x)~ + .(a) ~r^2 ==~ .(r2))),
parse = T)
bquote quotes its argument except the terms wrapped in .() which are evaluated
annotate does not support expressions, one trick to get it to work is to deparse it and then parse it again
I am having trouble with putting subscript in facet_grid label. Here is
an example of the work I have been trying to do.
df <- data.frame(species=gl(2,10,labels=c('sp1','sp2')),
age=sample(3:12,40,replace=T),
variable=gl(2,20,labels=c('N1P1 var','N2P1 var')),
value=rnorm(40))
test.plot <- ggplot(data=df,aes(x=age,y=value)) +
geom_point() +
facet_grid(variable~species)
Now I want to make by vertical facet label as 'N[1]P[1] var' and so on,
where the numbers in the squared bracket means subscript.
I have consulted some helps in this platform regarding this, but none helped me. I have used expression, bquote as suggested, but nothing worked!
You need to do 2 things:
first, make your labels as plotmath expressions
variable_labels <-
c(expression(paste(N[1],P[1]~var)), expression(paste(N[2],P[1]~var)))
df <- data.frame(species=gl(2,10,labels=c('sp1','sp2')),
age=sample(3:12,40,replace=T),
variable=gl(2,20,labels=variable_labels),
value=rnorm(40))
And then change the default labeller function in facet_grid to "label_parsed"
test.plot <- ggplot(data=df,aes(x=age,y=value)) +
geom_point() +
facet_grid(variable~species, labeller = "label_parsed")
Can part of the string I pass to parse(text=...) be taken as a literal string? Literal string means it will not try to interpret it.
For instance, I want to have the text "p-value" text in a plot (with the p italicized).
I am doing:
library(ggplot2)
ggplot(data.frame(x=rnorm(500)), aes(x)) + geom_histogram() + geom_text(label='italic(p)-value==0.10', parse=TRUE, x=-2, y=40)
Result:
The hyphen has a little too much padding and too big (because it takes it as the subtraction symbol), and it is not showing the number with the full precision I have used.
Can I just tell him to take part of that string as is?
How about this:
ggplot(data.frame(x=rnorm(500)), aes(x)) +
geom_histogram() +
annotate("text", label='italic(p)*"-value"=="0.15"', parse=TRUE, x=-2, y=40)
Here we use double quotes to specify character values and use * to place them right next to expressions.
Also note the change to annotate() rather than geom_text(). The latter would print out a 500 labels at the same location since it's tied to the data you specified in the ggplot call.
With set.seed(15), I get