Axis label specifications in ggplot - r

I'm attempting to have a two-line y-axis label that contains a superscript in ggplot and I am struggling.
I want the y axis label to say “[3H]ASEM binding (pmol/g)” with the 3 superscripted and (pmol/g) on a separate line.
This is what I have tried so far:
labs(x="", y=expression(paste("[" ^3 "H] ASEM Binding \n (pmol/g)")))
And it's given me the error "unexpected string constant"
Any suggestions?

You need an empty ''(2 single quotes) prior to the ^3.
ggplot(sample_data, aes(x, y)) +
geom_point() +
labs(
x = "",
y = expression(atop(paste("[", ''^3, "H] ASEM Binding"), "(pmol/g)"))
)
Another alternative is:
y = expression(atop("["^3*"H] ASEM Binding", "(pmol/g)"))

I'm not quite sure what you're doing with your for loop, but this code chunk should get you the two-lined axis label with a superscript for which you are looking.
library(tidyverse)
sample_data <- tibble(x = rnorm(1000),
y = x^2)
sample_data %>%
ggplot(aes(x, y)) +
geom_point() +
labs(
x = "X",
y = expression(atop("Variable", X^2))
)

Is this what you are after?
library(ggplot2)
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point()+
labs(x = "",
y = expression(atop("[ "^3*H~"] ASEM Binding", "(pmol/g)")))+
theme(plot.margin = unit(c(10, 10, 20, 10), "mm"))
Created on 2020-05-19 by the reprex package (v0.3.0)

Related

Dynamic decimal precision in ggplot axis labels

I would like to display only the minimum number of decimal places in my ggplot axis labels (e.g. 0.1 with 10 as opposed to 10.0. I was trying to get scales::label_number() to do this, but the accuracy argument is applied across all of the labels. Also I'd like to be able to add big.mark = "," if possible.
The closest answer I found suggests an ifelse function to dynamically round as needed but it feels a little clunky. Is there some slick way to do this with {scales} or similar?
Minimal example with current and desired results:
library(tidyverse)
library(scales)
# current labels with scales::label_number()
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
ggtitle("Undesriable: same precision on all labels") +
scale_y_log10(labels = label_number(big.mark = ","), breaks = 10^(-2:3))
# desired labels manually specified
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
ggtitle("Desriable: minimum needed precision on each label with comma") +
scale_y_log10(labels = c(0.01, 0.1, 1, 10, 100, "1,000"), breaks = 10^(-2:3))
Created on 2022-06-23 by the reprex package (v2.0.1)
Using I seems pretty neat to me:
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
scale_y_log10(labels = I, breaks = 10^(-2:3))
Though if you wanted a bit more control, then you could use prettyNum - e.g.
tibble(x = -2:3, y = 10^x) %>%
ggplot(aes(x, y)) +
geom_point() +
scale_y_log10(labels = ~ prettyNum(.x, big.mark = ","), breaks = 10^(-2:3))

Equivalent of loglog(MATLAB) to R

I am trying to plot a loglog graph but use the non-log labels. So instead of showing in x axis 1 (log10(10), it shows 10. I found the following solution. But that's too much work in my opinion. Is there anything equivalent to the Matlab function "loglog"?
plot(log10(x),log10(y),xaxt = "n")
axis(1,at = c(log10(0.5), log10(10), log10(45),log(100)), labels = c(0.5,10,45,100))
Could be done easily with ggplot:
library(ggplot2)
library(scales)
library(tibble)
tibble(
x = seq(1, 10, .01),
y = sin(log(x)*pi) + 2
) %>%
ggplot(aes(x,y)) +
geom_line() +
scale_x_continuous(trans = log_trans()) +
scale_y_continuous(trans = log_trans())
# Or for log10 it can be done without trans:
tibble(
x = seq(1, 10, .01),
y = sin(log(x)*pi) + 2
) %>%
ggplot(aes(x,y)) +
geom_line() +
scale_x_log10() +
scale_y_log10()
Created on 2022-03-09 by the reprex package (v2.0.1)

r ggplot use plotmath expressions dynamically

I want to change axis labels dynamically using ggplot. The code below is a simple version of what I'd like to do. It correctly displays a degree symbol in the y axis.The commented out ylab lines of code are what I'd like to do but fail. I want to create the plotmath code, assign it to a variable (e.g. yLabel) and then have ggplot interpret it.
library(data.table)
library(ggplot2)
DT <- data.table(timeStamp=c(1:12), ColN1=runif(12, 0, 10))
DT.long <- data.table::melt(
DT, id.vars = c("timeStamp"))
yLabel <- "Temperature~(~degree~F)"
yLabel1 <- expression("Temperature~(~degree~F)")
p <- ggplot(data = DT.long, aes(x = timeStamp, y = value)) +
xlab("Time") +
# ylab( expression(paste("Value is ", yLabel,","))) +
# ylab(yLabel) +
# ylab(yLabel1) +
ylab(Temperature~(~degree~F)) +
scale_y_continuous() +
theme_bw() +
geom_line()
print(p)
Use bquote
Here is your dynamic component
temp <- 12
Assign it to the label using
ylab(bquote(Temperature ~is ~ .(temp) ~(degree~F)))
Or to address your additional question below
V = "Temperature is ("~degree~"F)"
W = "depth is ("~degree~"C)"
ggplot(data = DT.long, aes(x = timeStamp, y = value)) +
xlab("Time") +
ylab(bquote(.(V)))
ggplot(data = DT.long, aes(x = timeStamp, y = value)) +
xlab("Time") +
ylab(bquote(.(W)))
I had the same issue with dynamically modifying an axis label and B Williams answer helped me.
The solution:
dynamic <- "dynamic text"
# Put the dynamic text in its right context
str <- sprintf("Static label text [%s]", dynamic)
# Use multiplication "*" rather than "~" to build the expression to avoid unnecessary space
complete_label <- bquote(.(str)[subscript]*"/L")
To verify that it works:
library(ggplot2)
ggplot() + labs(x = complete_label)

`annotate` in `ggplot2` reports errors when combined with `facet_grid`

I want to add two annotations to the ggplot graph.
When the graph doesn't contain a facet_grid, such as p1, adding such a annotate layer works fine, i.e., q1. However, when I add a facet_grid layer, to the original graph, i.e., p2, then adding the same 'annotate' layer, i.e., q2 results in an error reporting:
Error: Aesthetics must be either length 1 or the same as the data (4): label
Any suggestion? Thanks.
PS, the version of the package ggplot2 I used is 2.2.1.
p1 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
p2 <- p1 + facet_grid(vs~.)
q1 <- p1 + annotate("text", x = 2:3, y = 20:21, label = c("my label", "label 2"))
q2 <- p2 + annotate("text", x = 2:3, y = 20:21, label = c("my label", "label 2"))
The following is the answer I got from the package author, Hadley Wickham:
https://github.com/tidyverse/ggplot2/issues/2221
Unfortunately it's very hard to have annotate() do this automatically. Instead just do it "by hand" by creating the dataset yourself.
library(ggplot2)
df <- data.frame(wt = 2:3, mpg = 20:21, label = c("my label", "label 2"))
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_text(aes(label = label), data = df) +
facet_grid(vs ~ .)
The problem is that You used for x= 2:3 and for y=20:21. X and Y should be given only one value/argument and not a vector as in Your case. If You change to x=2 and y=20, then the plot appears without any Error:
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + facet_grid(vs~.) + annotate("text", x = 2, y = 20, label = c("my label", "label 2"))

How to underline text in a plot title or label? (ggplot2)

Please pardon my ignorance if this is a simple question, but I can't seem to figure out how to underline any part of a plot title. I'm using ggplot2.
The best I could find was
annotate("segment") done by hand, and I have created a toy plot to illustrate its method.
df <- data.frame(x = 1:10, y = 1:10)
rngx <- 0.5 * range(df$x)[2] # store mid-point of plot based on x-axis value
rngy <- 0.5 * range(df$y)[2] # stores mid-point of y-axis for use in ggplot
ggplot(df, aes(x = x, y = y)) +
geom_point() +
ggtitle("Oh how I wish for ..." ) +
ggplot2::annotate("text", x = rngx, y = max(df$y) + 1, label = "underlining!", color = "red") +
# create underline:
ggplot2::annotate("segment", x = rngx-0.8, xend = rngx + 0.8, y= 10.1, yend=10.1)
uses bquote(underline() with base R
pertains to lines over and under nodes on a graph
uses plotmath and offers a workaround, but it didn't help
Try this:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(expression(paste("Oh how I wish for ", underline(underlining))))
Alternatively, as BondedDust points out in the comments, you can avoid the paste() call entirely, but watch out for the for:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(expression(Oh~how~I~wish~'for'~underline(underlining)))
Or another, even shorter approach suggested by baptiste that doesn't use expression, paste(), or the many tildes:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(~"Oh how I wish for "*underline(underlining))

Resources