Rotação e espaçamento dos rótulos dos eixos no ggplot2


671

Eu tenho um gráfico em que o eixo x é um fator cujos rótulos são longos. Embora provavelmente não seja uma visualização ideal, por enquanto eu gostaria de simplesmente girar esses rótulos para ficar na vertical. Eu descobri essa parte com o código abaixo, mas como você pode ver, os rótulos não são totalmente visíveis.

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))
q <- qplot(cut,carat,data=diamonds,geom="boxplot")
q + opts(axis.text.x=theme_text(angle=-90))

insira a descrição da imagem aqui

Respostas:


1113

Mude a última linha para

q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

Por padrão, os eixos estão alinhados no centro do texto, mesmo quando rotacionados. Quando você gira +/- 90 graus, geralmente deseja que seja alinhado na borda:

texto alternativo

A imagem acima é deste post do blog .


95
Na versão mais recente do ggplot2 o comando seria: q + theme(axis.text.x=element_text(angle = -90, hjust = 0))
rnorberg

55
Para aqueles para quem hjust não está se comportando como descrito aqui, tente theme(axis.text.x=element_text(angle = 90, vjust = 0.5)). A partir do ggplot2 0.9.3.1, essa parece ser a solução.
lilster

42
Na verdade, tive que combinar as duas soluções acima para obter rótulos alinhados corretamente:q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
jupp0r 25/12/13

32
@ jupp0r está correto. theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))É O ÚLTIMO TRABALHO ATUALMENTE.

51
se você queria 45 ° rótulos rodados (mais fácil de ler) theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))dá bons resultados
jan-GLX

89

Para tornar o texto nos rótulos dos ticks totalmente visível e lido na mesma direção que o rótulo do eixo y, altere a última linha para

q + theme(axis.text.x=element_text(angle=90, hjust=1))

82

Usar coord_flip()

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))

qplot(cut,carat,data = diamonds, geom = "boxplot") +
  coord_flip()

insira a descrição da imagem aqui


No capítulo 3.9 do R para Data Science , Wickham e Grolemund falam exatamente sobre esta questão:

coord_flip()alterna os eixos x e y. Isso é útil (por exemplo), se você quiser boxplots horizontais. Também é útil para etiquetas longas: é difícil ajustá-las sem sobrepor no eixo x.


26

Gostaria de fornecer uma solução alternativa, uma solução robusta semelhante à que estou prestes a propor foi necessária na versão mais recente do ggtern , desde a introdução do recurso de rotação da tela.

Basicamente, você precisa determinar as posições relativas usando trigonometria, construindo uma função que retorna um element_textobjeto, dado o ângulo (ou seja, graus) e posicionamento (ou seja, uma das informações x, y, superior ou direita).

#Load Required Libraries
library(ggplot2)
library(gridExtra)

#Build Function to Return Element Text Object
rotatedAxisElementText = function(angle,position='x'){
  angle     = angle[1]; 
  position  = position[1]
  positions = list(x=0,y=90,top=180,right=270)
  if(!position %in% names(positions))
    stop(sprintf("'position' must be one of [%s]",paste(names(positions),collapse=", ")),call.=FALSE)
  if(!is.numeric(angle))
    stop("'angle' must be numeric",call.=FALSE)
  rads  = (angle - positions[[ position ]])*pi/180
  hjust = 0.5*(1 - sin(rads))
  vjust = 0.5*(1 + cos(rads))
  element_text(angle=angle,vjust=vjust,hjust=hjust)
}

Francamente, na minha opinião, acho que uma opção 'auto' deve ser disponibilizada ggplot2para os argumentos hjuste vjust, ao especificar o ângulo, de qualquer maneira, vamos demonstrar como funciona acima.

#Demonstrate Usage for a Variety of Rotations
df    = data.frame(x=0.5,y=0.5)
plots = lapply(seq(0,90,length.out=4),function(a){
  ggplot(df,aes(x,y)) + 
    geom_point() + 
    theme(axis.text.x = rotatedAxisElementText(a,'x'),
          axis.text.y = rotatedAxisElementText(a,'y')) +
    labs(title = sprintf("Rotated %s",a))
})
grid.arrange(grobs=plots)

Que produz o seguinte:

Exemplo


1
Não obtenho os mesmos resultados, para mim o texto do eixo nunca é bem ajustado usando o seu método automático. No entanto, o uso rads = (-angle - positions[[ position ]])*pi/180produziu melhores canais. Observe o sinal de menos adicional antes do ângulo. Obrigado pela qualquer maneira código :)
ASAC

7

O pacote ggpubr oferece um atalho que faz a coisa certa por padrão (texto alinhado à direita, caixa de texto alinhada ao meio para marcar):

library(ggplot2)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))
q <- qplot(cut, carat, data = diamonds, geom = "boxplot")
q + ggpubr::rotate_x_text()

Criado em 06/11/2018 pelo pacote reprex (v0.2.1)

Encontrado com uma pesquisa no GitHub pelos nomes de argumentos relevantes: https://github.com/search?l=R&q=element_text+angle+90+vjust+org%3Acran&type=Code


6

Como alternativa, ggplot 3.3.0fornece guide_axis(n.dodge = 2)(como guideargumento para scale_..ou como xargumento guides) para superar o problema de plotagem excessiva, evitando os rótulos verticalmente. Funciona muito bem neste caso:

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))

ggplot(diamonds, aes(cut, carat)) + 
  geom_boxplot() +
  scale_x_discrete(guide = guide_axis(n.dodge = 2)) +
  NULL


1

Para obter rótulos x tick legíveis sem dependências adicionais, você deseja usar:

  ... +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)) +
  ...

Isso gira os rótulos dos tiquetaques 90 ° no sentido anti-horário e os alinha verticalmente no final ( hjust = 1) e seus centros horizontalmente com a marca correspondente (vjust = 0.5 ).

Exemplo completo:

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))
q <- qplot(cut,carat,data=diamonds,geom="boxplot")
q + theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))


Observe que os parâmetros de justificação vertical / horizontal vjust/ hjustde element_textsão relativos ao texto. Portanto, vjusté responsável pela horizontal alinhamento .

Sem vjust = 0.5ele ficaria assim:

q + theme(axis.text.x = element_text(angle = 90, hjust = 1))

Sem hjust = 1ele ficaria assim:

q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5))

Se, por algum motivo (com fio), você quiser girar os rótulos dos marcadores 90 ° no sentido horário (para que possam ser lidos da esquerda), você precisará usar: q + theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust = -1)) .

Tudo isso já foi discutido nos comentários desta resposta, mas volto a essa pergunta com tanta frequência que desejo uma resposta da qual possa copiar sem ler os comentários.


0

Uma alternativa coord_flip()é usar o ggstancepacote. A vantagem é que facilita a combinação dos gráficos com outros tipos de gráficos e você pode, talvez mais importante, definir proporções de escala fixa para o seu sistema de coordenadas .

library(ggplot2)
library(ggstance)

diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))

ggplot(data=diamonds, aes(carat, cut)) + geom_boxploth()

Criado em 2020-03-11 pelo pacote reprex (v0.3.0)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.