Como faço para que os formatos de texto personalizados do ggplot2 das funções de escala do eixo sigam as especificações de formato definidas em theme ()?

Aug 18 2020

Quero mudar a notação científica nos eixos ggplot2 de um formato semelhante 3.23e+6a 3.23 × 10^6. Felizmente, esta questão foi respondida aqui: Como altero a formatação de números em um eixo com ggplot?

Funciona bem para casos básicos. No entanto, ele não funciona quando você deseja alterar a formatação do rótulo do eixo. Isso é ilustrado por este exemplo:

library(tidyverse)
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")) 


O que produz:

O problema é que o texto do eixo Y não está em negrito conforme especificado na chamada para theme. Quando costumo browserver o que está acontecendo dentro de fancy_scientificvejo que ele retorna um objeto da classe "expressão" que neste caso é impresso como expression('2'%*%10^+01, '3'%*%10^+01, '4'%*%10^+01)enquanto a função scales::scientific, que pode ser usada para forçar a notação científica do tipo que desejo evitar, mas está em conformidade para quaisquer especificações de tema que eu definir, retorna um vetor de strings diretamente. Quando eu modifico fancy_scientificpara retornar um vetor de strings como '2'%*%10^+01se fossem diretamente renderizados no eixo Y exibido.

Portanto, a questão é como faço para que a saída da fancy_scientificfunção esteja em conformidade com a especificação do meu tema?

Respostas

JordanMandel Aug 20 2020 at 02:54

Uma maneira de fazer isso, conforme sugerido pelo comentário, é o ggtextpacote.

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")) 

Porém, se você executar este código, perceberá alguns problemas. Existem aspas ao redor do número inicial, que podem ser eliminadas excluindo as aspas simples de l <- gsub("^(.*)e", "'\\1'e", l). Recebo um erro quando especifico textcomo element_markdown()porque aparentemente há alguns padrões que precisam ser definidos para outras partes do texto. Portanto, tenho que definir especificamente axis.text.ycomo element_markdown. Isso deixa o problema de obter um sinal de tempo real para ser exibido. Farei uma pergunta de acompanhamento sobre isso porque respondi à pergunta sobre como fazer com que a formatação em negrito seja aplicada, embora também esteja curioso sobre como definir os padrões element_markdowncorretamente para que possa usá-los para especificar em textvez de axis.text.y.