4
votes

Exposants dans le texte de l'axe de ggplot2

Je voudrais créer un graphique qui a des exposants sur l'axe au lieu d'afficher des nombres non formatés en utilisant ggplot2 . Je sais qu'il y a beaucoup de réponses qui modifient le libellé de l'axe, mais pas le texte de l'axe. Je n'essaye pas de changer le libellé du graphique, mais le texte sur l'axe.

Exemple:

x<-c('2^-5','2^-3','2^-1','2^1','2^2','2^3','2^5','2^7','2^9','2^11','2^13')
y<-c('2^-5','2^-3','2^-1','2^1','2^2','2^3','2^5','2^7','2^9','2^11','2^13')
df<-data.frame(x,y)
p<-ggplot()+
  geom_point(data=df,aes(x=x,y=y),size=4)
p

Je voudrais donc que le x- axe pour afficher les mêmes nombres mais sans la carotte.

 entrez la description de l'image ici


7 commentaires

Avez-vous essayé expression si je me souviens?


Ou ajustez ceci: stackoverflow.com/questions/36920492/...


Ce n'est pas un doublon car ce sont des étiquettes d'axe, c'est du texte d'axe.


Savez-vous que x et y sont des chaînes de caractères, pas des nombres? Vous tracez des facteurs, c'est-à-dire les nombres entiers de 1 à 11.


Oui, je les ai conçus comme ça parce que si c'est numérique, alors vous tracez des nombres comme n'importe quel autre graphique, je voudrais les garder sous forme de caractères, mais vous pourriez aussi avoir des facteurs.


Alors, souhaitez-vous évaluer le nombre égal au texte sur l'axe ou simplement supprimer le curseur?


supprimer le curseur


3 Réponses :


2
votes

MODIFIER : Une approche purement base :

    library(dplyr)
   df %>% 
          mutate(new_x=gsub("\\^"," ",x),
                 new_y=gsub("\\^"," ",y))->new_df
        new_df %>%   
        ggplot()+
          geom_point(aes(x=x,y=y),size=4)+
         scale_x_discrete(breaks=x,labels=new_df$new_x)+
          scale_y_discrete(breaks=y,labels=new_df$new_y)

Ce qui précède peut être réduit à moins d'étapes, j'ai posté l'approche par étapes que j'ai adoptée. Le résultat pour seulement x , la même chose peut être faite pour y:

new_df %>%   
ggplot()+
  geom_point(aes(x=x,y=y),size=4)+
 scale_x_discrete(breaks=df$x,labels=to_use_1)#replace with y and scale_y_discrete for y

Tracé: entrez la description de l'image ici

Réponse originale et erronée :

J'ai dévié du code tidyverse standard > pratiquez en utilisant $ , vous pouvez le remplacer par . et cela pourrait fonctionner bien que dans ce cas ce ne soit pas vraiment important puisque l'accent est mis sur les étiquettes .:

df %>% 
  mutate_all(as.character)->new_df
res<-unlist(Map(function(x) eval(parse(text=x)),new_df$x))#replace with y for y
to_use<-unlist(lapply(res,as.expression))
split_text<-strsplit(gsub("\\^"," ",names(to_use))," ")
join_1<-as.numeric(sapply(split_text,"[[",1)) #tidyr::separate might help, less robust for numeric(I think)
join_2<-as.numeric(sapply(split_text,"[[",2))
to_use_1<-sapply(seq_along(join_1),function(x) parse(text=paste(join_1[x],"^",
                                                join_2[x])))


4 commentaires

Je pense que c'est un bon début, mais maintenant les chiffres sont dans le désordre


Pardon, pourriez-vous expliquer comment?


Eh bien, 2 ^ 11 précède 2 ^ 3 par exemple.


Je ne sais pas pourquoi nous avons des résultats différents. Utilisez-vous les données de la question ou d'autres données? Cela fait quelques jours que j'ai regardé cela, vous devrez peut-être voir le code que vous utilisez et / ou les données.



2
votes

Cela peut être fait avec les fonctions scale_x_log2 et scale_y_log2 qui se trouvent dans le package GitHub jrnoldmisc .

Tout d'abord, installez le package.

a <- ggplot(df1, aes(x = x, y = y, size = 4)) + 
  geom_point(show.legend = FALSE) +
  scale_x_log2(limits = c(0.01, NA), 
               labels = trans_format("log2", math_format(2^.x)),
               breaks = trans_breaks("log2", function(x) 2^(x - 1), n = 11)) +
  scale_y_log2(limits = c(0.01, NA),
               labels = trans_format("log2", math_format(2^.x)),
               breaks = trans_breaks("log2", function(x) 2^(x - 1), n = 11))
a + annotation_logticks(base = 2)

Ensuite, forcez les variables en numérique. Je travaillerai avec une copie du dataframe original.

a <- ggplot(df1, aes(x = x, y = y, size = 4)) + 
  geom_point(show.legend = FALSE) +
  scale_x_log2(limits = c(1.01, NA), 
                labels = trans_format("log2", math_format(2^.x)),
                breaks = trans_breaks("log2", function(x) 2^(x), n = 11)) +
  scale_y_log2(limits = c(1.01, NA),
                labels = trans_format("log2", math_format(2^.x)),
                breaks = trans_breaks("log2", function(x) 2^(x), n = 11))
a + annotation_logticks(base = 2)

Maintenant, tracez-le.

library(jrnoldmisc)
library(ggplot2)
library(MASS)
library(scales)

a <- ggplot(df1, aes(x = x, y = y, size = 4)) + 
  geom_point(show.legend = FALSE) +
  scale_x_log2(limits = c(0.01, NA), 
                labels = trans_format("log2", math_format(2^.x)),
                breaks = trans_breaks("log2", function(x) 2^x, n = 10)) +
  scale_y_log2(limits = c(0.01, NA),
                labels = trans_format("log2", math_format(2^.x)),
                breaks = trans_breaks("log2", function(x) 2^x, n = 10))
a + annotation_logticks(base = 2)

entrer l'image description here

Modifier.

Suite à la discussion dans les commentaires, voici les deux autres façons qui ont été vues pour donner des étiquettes d'axe.

  1. Axis marque chaque graduation. Définissez limits = c (1.01, NA) et l'argument de fonction n = 11 , un nombre impair.
  2. Étiquettes d'axe sur les exposants de nombre impair. Gardez limits = c (0.01, NA) , passez à function (x) 2 ^ (x - 1), n ​​= 11 .

Juste les instructions, pas de parcelles.

Le premier.

df1 <- df
df1[] <- lapply(df1, function(x){
  x <- as.character(x)
  sapply(x, function(.x)eval(parse(text = .x)))
})

Et le second.

devtools::install_github("jrnold/rubbish")


6 commentaires

Est-il possible d'avoir des graduations sur les nombres impairs ou sur chaque graduation au lieu de seulement les paires?


@JackArmstrong Oui, c'est vrai, je viens de tester limits = c (1.01, NA) sur les deux appels sclae _ * _ log2 et il s'imprime maintenant sur chaque coche.


Au lieu d'utiliser des limites, dans les pauses, = trans_breaks ("log2", fonction (x) 2 ^ (x-1), n ​​= 10))


@JackArmstrong Vous avez absolument raison, vous n'y avez pas pensé. Mais il ne donnera les étiquettes que sur les exposants impairs, avec moi limites les donne à chaque coche.


@JackArmstrong OK, compris. J'avais changé l'argument n dans function (x) 2 ^ (x), n = 11 en un nombre impair. Plus limits = c (1.01, NA) , il donne des étiquettes sur chaque coche. Dois-je modifier la réponse avec ceci?


Si vous le souhaitez avec d'autres moyens possibles, bien sûr. Pas besoin de photos je pense. Les gens devraient savoir lire.



1
votes

Vous pouvez fournir une fonction à l'argument labels des fonctions scale_x _ *** et scale_y _ *** pour générer des libellés avec des exposants (ou autre formatage). Voir les exemples ci-dessous.

ggplot(df) +
  geom_point(aes(x=x,y=y),size=2)  +
  scale_x_log10(breaks=10^seq(-1,1,1),
                labels=function(x) parse(text=paste("10^",round(log10(x),2))))

 entrez la description de l'image ici

ggplot(df) +
  geom_point(aes(x=x,y=y),size=2)  +
  scale_x_continuous(breaks=c(2^-5, 2^seq(1,5,2)),
                     labels=function(x) parse(text=paste("2^",round(log2(x),2))))

 entrez la description de l'image ici

library(jrnoldmisc)
library(ggplot2)

df<-data.frame(x=2^seq(-5,5,2),
               y=2^seq(-5,5,2))

ggplot(df) +
  geom_point(aes(x=x,y=y),size=2)  +
  scale_x_log2(breaks=2^seq(-5,5,2),
               labels=function(x) parse(text=paste("2^",round(log2(x),2))))

entrez la description de l'image ici


0 commentaires