Adding expression to ggplot axis label seems to require an extra character? - r

I am working on a plot in which I have scaled the horizontal axis by a factor of ten thousand. I've been trying to include that in my axis label, but have consistently failed. However, what I've found is that this works:
g <- g + xlab(expression(paste("Word Count ", (x %.% 10^4))))
but this does not:
g <- g + xlab(expression(paste("Word Count ", (%.% 10^4))))
The latter throws the error "Unexpected special in...".
Were I to be writing the label I wanted in LaTeX, it would be: $\text{Word Count } \left( \cdot 10^4 \right)$.
How do I get the axis label I'm after without the extra character?

For whatever reason, expression needs something on the left-hand side. However, that something can be NULL, so this works:
g <- g + xlab(expression(paste("Word Count ", (NULL %.% 10^4))))

Related

Check if y-axis begins at zero

I want to determine if a plot generated by ggplot begins at zero.
I am generating a couple hundred reports that each have thirty or more charts in them. I am content with ggplot's defaults for when a plot starts at zero and when it doesn't, but I want to add a caption that draws the reader's attention to this fact.
Something like:
labs(caption = ifelse(XXXXX, "Note: y-axis does not begin at zero", ""))
But I have no clue what my test should be.
Try this:
library(ggplot2)
g <- ggplot(data.frame(x=1:10, y=0:9), aes(x=x,y=y)) + geom_point()
yrange <- ggplot_build(g)$layout$panel_params[[1]]$y.range
if(yrange[1] <= 0) g <- g + labs(caption = "Note: y-axis does not begin at zero")
plot(g)

ggplot2 label: Combination of Greek symbol and exponential term,

I need to label my y axis so that it displays first the word "Power" followed by an expression in square brackets: [micro Volt squared].
I can produce single parts of the overall label that I want, but I run into problems when I want to combine them:
x <- 1:10; y <- 10:1; z <- data.frame(x,y)
g <- ggplot(z, aes(x,y) + geom_bar(stat='identity')
g + ylab('Power') # No problem
g + ylab(paste('Power [', ']')) #No problem
g + ylab(expression(mu)) # No problem
g + ylab(expression(V^2)) # No problem
However, this seems not to be possible:
g + ylab(paste('Power [', expression(mu), expression(V^2), ']'))
The output does not evalute the expressions (mu and V^2):
Where am I going wrong? Is the paste() command the wrong approach in general? I have also had a look at unicode characters (Unicode Characters in ggplot2 PDF Output) ... but that would still leave me with the question how I adequately combine all the single terms.
Your help is much appreciated!
You need to put everything inside the expression.
You can use an asterisk for separation, the tilde is for space. So this should be right.
g + ylab(expression("Power"~"["*mu*V^2*"]"))
A single expression seems to do the trick:
g + ylab(expression(paste("Power [",mu, V^2,"]")))

Adding output of print function to ggplot chart - r

Say I have a dataframe:
df <- data.frame(x=1:10, y=4:13)
p <- ggplot(df,aes(x,y)) + geom_point()
Now I want to add many things to this graph, so I use a big paste function and print the output. Just as an example, say I wanted to add the word 'bananas' inside the x axis label.
x <- "bananas"
print(paste0("+ xlab('Price of", x[1], "')"), quote=F)
If I try:
p + print(paste0("+ xlab('Price of", x[1], "')"), quote=F)
then it obviously does not work. But is there a way of adding the output of this function to the ggplot object 'p' without cutting/pasting from the console?
i.e. so we automatically can execute:
p + xlab('Price ofbananas')
If you want to add Price of bananas as the x label, then:
p + xlab(paste0("Price of ", x[1]))
Remember you're adding the xlab, so that should be your outside function. Inside it, you add/create the label you want. No need to print.
Update:
I think what you want is eval(parse(text=xxx)). For example:
add <- paste0("xlab('Price of ", x[1], "')")
p + eval(parse(text=add))
Note that I removed the + from the text, because you need it next to p to connect with eval.
I'm not sure why you would do this, but it works.

Label or annotation with subscript and variable source

I have an R routine which creates a number of plots from a large set of data. Each plot is labeled with a titles describing the details of the set of points plotted. Unfortunately, I have not been able to use subscripts in the text if I am using paste to combine a complex label. The result is ugly. This is a simplified version of the code using data from R. The title shows the technique I am currently using, without subscripts. The attempt at an improved version is placed either on the x axis or on the plot.
library(ggplot2)
x1 = 1
x2 = 2
list <- c(1:4)
tle <- paste("VGM = ", as.character(list[1]),
"V, VDM = ", as.character(list[2]),
"V, VGF = ", as.character(list[3]),
"V, VDF = ", as.character(list[4]),
"V", sep="")
p <- ggplot(mtcars, aes(x=wt, y=mpg)) +
labs(title=tle) +
geom_point()
p
p + xlab(expression(V[DM])) #works fine
p + xlab(expression(paste(V[DM], "= 3"))) # works fine
# now we would like to use a variable to provide the number
p + xlab(expression(paste(V[DM], "=", x1))) # Just displays "x1", not value of x1
p + xlab(expression(paste(V[DM], "=",
as.character(x1)))) # NO
p + xlab(expression(paste(V[DM], "=",
as.character(as.number(x1))))) # NO
my.xlab1 <- bquote(V[DM] == .(x1))
p + xlab(my.xlab1) # We can see the success here
# A single variable at the end of the expression works
# What if you wanted to display two variables?
my.xlab2 <- bquote(V[GM] == .(x2))
my.xlab3 <- paste(my.xlab1, my.xlab2)
p + xlab(my.xlab3) # doesn't work
# Apparently the expressions cannot be pasted together. Try another approach.
# Place the two expressions separately on the plot. They no longer need to be
# pasted together. It would look better, anyway. Would it work?
p + annotate("text", x=4, y=30, label="Annotate_text", parse=TRUE)
# This is the idea
# p + annotate("text", x=4, y=30, label=bquote(V[DM] == .(x1)), parse=TRUE)
# This is a disaster
# RStudio stops the process with a question mark placed on the console. Appears that
# more input is being requested?
p + geom_text(x=4, y=30, label="Geom_text") # works
p + geom_text(x=4, y=30, label=my.xlab1) # does not accept variables.
I have included comments which describe the problems raised by each attempt. Ideally, the information should probably be placed as an annotation on the plot rather than as a title, but I cannot find a way to do this. Using a subscript turns a character into an expression, and it seems that there is a long list of functions which handle characters but not expressions.
If you want to "paste" two expressions together, you need to have some "operator" join them. There really isn't a paste method for expressions, but there are ways to put them together. First, obviously you could use one bquote() to put both variables together. Either
my.xlab3 <- bquote(V[DM] == .(x1)~ V[GM] == .(x2))
my.xlab3 <- bquote(list(V[DM] == .(x1), V[GM] == .(x2)))
would work. The first puts a space between them, the second puts a comma between them. But if you want to build them separately, you can combine them with another round of bquote. So the equivalent building method for the two above expressions is
my.xlab3 <- bquote(.(my.xlab1) ~ .(my.xlab2))
my.xlab3 <- bquote(list(.(my.xlab1), .(my.xlab2)))
All of those should work to set your xlab() value.
Now, if you also want to get annotate to work, you can "un-parse" your expression and then have R "re-parse" it for you and you should be all set. Observe
p + annotate("text", x=4, y=30, label=deparse(my.xlab3), parse=TRUE)

stat_summary_hex coloured by ratio

Let's say I have a data frame with the following columns: x, y, num, denom, and I would like to produce a hex plot with the colours of the hexagons set by sum(num)/sum(denom).
I assumed that the answer would involve stat_summary_hex so I naively tried:
ggplot(data, aes(x=x, y=y)) + stat_summary_hex(fun=function(d) {sum(d$num)/sum(d$denom) })
but the output is:
Error: stat_summaryhex requires the following missing aesthetics: z
and I understand why (I didn't give it a z aesthetic), but I'm not sure what to try next: how can I pass in 2 z aesthetics (i.e. num and denom)?
I ended up finding a hack to do what I wanted, which I will record here:
ggplot(data, aes(x=x,y=y,z=complex(0,num,denom))) +
stat_summary_hex(fun= function(x) { sum(Re(x)) / sum(Im(x)) })
Essentially, I did provide a z parameter, which was a column of complex numbers. Complex numbers are numbers, so ggplot lets them through, and they have two parts, a real and an imaginary part, so the aggregation function is able to compute the ratio I wanted.

Resources