2

I am trying to display scientific notation on a ggplot2 axis in boldface, with the literal "Ax10^B" format, not "AeB" format that is the default of ggplot2. When this code is run

library(tidyverse)
library(ggtext)
ggplot(mpg, aes(displ, hwy*10^9)) + geom_point()


#makes the scientific notation using "AeB" explicitly write out Ax10^B
fancy_scientific <- function(l) {
  # turn in to character string in scientific notation
  l <- format(l, scientific = TRUE)
  # quote the part before the exponent to keep all the digits
  l <- gsub("^(.*)e", "'\\1'e", l)
  # turn the 'e+' into plotmath format
  l <- gsub("e", "%*%10^", l)
  # return this as an expression
  parse(text=l)
}


ggplot(mpg, aes(displ, hwy*10^9)) + 
  theme_classic() +
  geom_point() + 
  scale_y_continuous(labels= fancy_scientific)  +
  theme(text = element_text(face = "bold"), 
        axis.text.y = element_markdown(face = "bold")) 


this is the result: Output of code

I use element_markdown() from ggtext because it allows the bold face to be transferred as I discovered here: How do I make ggplot2 custom text formats from axis scale functions follow format specifications set in theme()?

I can fix the double quotes by changing '\\1' to \\1 (deleting the single quotes). But I am having trouble getting the multiplication sign to display. I could just use a lowercase x but that is lazy.

When I try to use $\times$ as suggested here https://rstudio-pubs-static.s3.amazonaws.com/18858_0c289c260a574ea08c0f10b944abc883.html I get an error. A vignette for ggtext seems to use html: https://cran.r-project.org/web/packages/ggtext/vignettes/theme_elements.html but they use <sup> tags which seems to go against the use of ^ to make an exponenent here, and the tags don't work when I use them, and all resources for "multiplication sign in html" that I searched for haven't yielded a solution. So my question is: Where can I find a good resource to learn the proper formatting language that ggtext/ ggplot2 uses for axis tick labels? Would also like to know the solution to the specific problems I'm having.

Jordan Mandel
  • 478
  • 3
  • 14

2 Answers2

2

{ggtext} uses Markdown/HTML. You can insert special characters either by just using unicode characters or by using HTML entities. Here, you probably want &times;.

Also, don't parse strings into expressions when working with {ggtext}.

library(tidyverse)
library(ggtext)

#makes the scientific notation using "AeB" explicitly write out Ax10^B
fancy_scientific <- function(l) {
  # turn in to character string in scientific notation
  l <- format(l, scientific = TRUE)
  # quote the part before the exponent to keep all the digits
  l <- gsub("^(.*)e", "\\1e", l)
  # turn the 'e+' into plotmath format
  l <- gsub("e", "&times;10^", l)
  # return this as a string
  l
}


ggplot(mpg, aes(displ, hwy*10^9)) + 
  theme_classic() +
  geom_point() + 
  scale_y_continuous(labels= fancy_scientific)  +
  theme(text = element_text(face = "bold"), 
        axis.text.y = element_markdown(face = "bold")) 

Created on 2020-08-20 by the reprex package (v0.3.0)

Claus Wilke
  • 16,992
  • 7
  • 53
  • 104
  • Thank you! I'm new at this so I'm wondering about the distinction between markdown and html. For example you specify superscripts with a caret while in other places like the other answer the `````` tag is used. Am I correct in assuming that the former is markdown while the latter is HTML? Also am wondering if when writing a ggtext input string you have to choose one or the other, or if there are circumstances where the input can be a mix of markdown and html. – Jordan Mandel Aug 20 '20 at 14:58
  • The input is always processed as markdown, and you can throw in HTML tags as needed. See e.g. here: https://daringfireball.net/projects/markdown/syntax – Claus Wilke Aug 20 '20 at 18:12
  • However, ggtext knows only a very small subset of all HTML tags, so don't throw in an HTML table or list and expect this to work. – Claus Wilke Aug 20 '20 at 18:13
0

Here is a version with just plotmath expressions:

library(dplyr)
library(ggplot2)

fancy_scientific <- function(l) {
    l <- format(l, scientific = TRUE)
    parse(text=gsub("(.*)e(\\+?)(\\-?[0-9]+)", 
        "bold('\\1') * bold(' * ') * bold('10')^bold('\\3')", l))
}

mpg %>% dplyr::mutate(hwy = hwy * 1e9) %>% 
    ggplot(aes(displ, hwy)) + 
    theme_classic() +
    geom_point() + 
    scale_y_continuous(labels= fancy_scientific) +
    theme(text = element_text(face = "bold"))

... and here is a version with ggtext:

library(dplyr)
library(ggplot2)
library(ggtext)

fancy_scientific <- function(l) {
    l <- format(l, scientific = TRUE)
    parse(text=gsub("(.*)e(\\+?)(\\-?[0-9]+)", "\\1 * 10^(\\3)", l))

    ## this would also work, instead of the line above:
    # gsub("(.*)e(\\+?)(\\-?[0-9]+)", "**\\1 \\* 10<sup>\\3</sup>**", l)
}

mpg %>% dplyr::mutate(hwy = hwy * 1e9) %>% 
    ggplot(aes(displ, hwy)) + 
    theme_classic() +
    geom_point() + 
    scale_y_continuous(labels= fancy_scientific)  +
    theme(text = element_text(face = "bold"), 
          axis.text.y = element_markdown(face = "bold"))

Created on 2020-08-20 by the reprex package (v0.3.0)

user12728748
  • 8,106
  • 2
  • 9
  • 14
  • Thanks! Do you know a way to do this without specifying bold, and that gives a real multiplication sign rather than an asterisk? – Jordan Mandel Aug 20 '20 at 05:35
  • The plotmath version does not require you to specify bold outside of the `fancy_scientific` function, the html version of the second example does not require you to specify bold outside of the function, and I am not sure what multiplication sign you want, but that should be no problem, either. E.g. use `gsub("(.*)e(\\+?)(\\-?[0-9]+)", "**\\1 × 10\\3**", l)` in the html notation. – user12728748 Aug 20 '20 at 05:41