Comment faire pour que les formats de texte personnalisés ggplot2 à partir des fonctions d'échelle d'axe suivent les spécifications de format définies dans theme ()?
Je veux changer la notation scientifique sur les axes ggplot2 d'un format comme 3.23e+6
à 3.23 × 10^6
. Heureusement, cette question a été répondue ici: Comment changer la mise en forme des nombres sur un axe avec ggplot?
Cela fonctionne bien pour les cas de base. Cependant, cela ne fonctionne pas lorsque vous souhaitez modifier la mise en forme de l'étiquette de l'axe. Ceci est illustré par cet exemple:
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"))
Ce qui donne:

Le problème est que le texte de l'axe Y n'est pas en gras comme spécifié dans l'appel à theme
. Quand j'utilise browser
pour voir ce qui se passe à l'intérieur de fancy_scientific
je vois qu'il renvoie un objet de classe "expression" qui dans ce cas est affiché comme expression('2'%*%10^+01, '3'%*%10^+01, '4'%*%10^+01)
while la fonction scales::scientific
, qui peut être utilisée pour forcer la notation scientifique du genre que je veux éviter mais conforme quelle que soit les spécifications de thème que j'ai définies, renvoie directement un vecteur de chaînes. Lorsque je modifie fancy_scientific
pour renvoyer un vecteur de chaînes comme si '2'%*%10^+01
elles sont directement rendues sur l'axe Y affiché.
La question est donc de savoir comment rendre la sortie de la fancy_scientific
fonction conforme à ma spécification de thème?
Réponses
Un moyen de le faire, comme suggéré par le commentaire, est le ggtext
package.
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"))
Si vous exécutez ce code, vous remarquerez des problèmes. Il y a des guillemets autour du premier nombre, qui peuvent être supprimés en supprimant les guillemets simples dans l <- gsub("^(.*)e", "'\\1'e", l)
. J'obtiens une erreur lorsque je spécifie text
comme element_markdown()
parce qu'apparemment, il y a des valeurs par défaut qui doivent être définies pour d'autres parties du texte. Je dois donc définir spécifiquement axis.text.y
comme element_markdown
. Cela laisse le problème de l'affichage d'un signe des temps réels. Je poserai une question de suivi à ce sujet car j'ai répondu à la question de savoir comment appliquer la mise en forme en gras, bien que je sois également curieux de savoir comment définir element_markdown
correctement les valeurs par défaut afin de pouvoir l'utiliser pour spécifier text
plutôt que axis.text.y
.