Obracanie i rozmieszczanie etykiet osi w ggplot2

668

Mam wykres, w którym oś X jest czynnikiem, którego etykiety są długie. Chociaż prawdopodobnie nie jest to idealna wizualizacja, na razie chciałbym po prostu obrócić te etykiety, aby były pionowe. Zrozumiałem tę część za pomocą poniższego kodu, ale jak widać, etykiety nie są całkowicie widoczne.

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

wprowadź opis zdjęcia tutaj

Christopher DuBois
źródło

Odpowiedzi:

1109

Zmień ostatnią linię na

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

Domyślnie osie są wyrównane w środku tekstu, nawet po obróceniu. Kiedy obracasz o +/- 90 stopni, zwykle chcesz, aby zamiast tego był wyrównany do krawędzi:

alternatywny tekst

Powyższe zdjęcie pochodzi z tego postu na blogu .

Jonathan Chang
źródło
95
W najnowszej wersji ggplot2 komenda wyglądałaby następująco: q + theme(axis.text.x=element_text(angle = -90, hjust = 0))
rnorberg
55
Dla tych, dla których sprawiedliwość nie zachowuje się tak, jak tu opisano, spróbuj theme(axis.text.x=element_text(angle = 90, vjust = 0.5)). W przypadku ggplot2 0.9.3.1 wydaje się to rozwiązaniem.
lilster,
42
Właściwie musiałem połączyć dwa powyższe rozwiązania, aby uzyskać poprawnie wyrównane etykiety:q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
jupp0r
32
@ jupp0r jest poprawny. theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))JEST JEDNĄ PRACĄ OBECNIE.
51
jeśli chcesz obrócone o 45 ° etykiety (łatwiejsze do odczytania) theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))daje dobre wyniki
jan-glx
89

Aby tekst na etykietach zaznaczenia był w pełni widoczny i czytany w tym samym kierunku co etykieta na osi y, zmień ostatni wiersz na

q + theme(axis.text.x=element_text(angle=90, hjust=1))
e3bo
źródło
81

Posługiwać się coord_flip()

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

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

wprowadź opis zdjęcia tutaj


W rozdziale 3.9 R dla Data Science Wickham i Grolemund mówią dokładnie o tym pytaniu:

coord_flip()przełącza osie xiy. Jest to przydatne (na przykład), jeśli chcesz poziome wykresy pudełkowe. Przydaje się również w przypadku długich etykiet: trudno jest je dopasować bez nakładania się na oś x.

Bogaty Pauloo
źródło
26

Chciałbym przedstawić alternatywne rozwiązanie , od czasu wprowadzenia funkcji obracania obszaru roboczego wymagane było solidne rozwiązanie podobne do tego, co zamierzam zaproponować w najnowszej wersji ggtern .

Zasadniczo musisz określić pozycje względne za pomocą trygonometrii, budując funkcję zwracającą element_textobiekt, dany kąt (tj. Stopnie) i pozycję (tj. Jedną z informacji x, y, góra lub prawo).

#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)
}

Szczerze mówiąc, moim zdaniem, uważam, że należy udostępnić opcję „auto” ggplot2dla argumentów hjusti vjust, przy określaniu kąta, w każdym razie, pozwala pokazać, jak działa powyższe.

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

Co powoduje:

Przykład

Nicholas Hamilton
źródło
1
Nie uzyskuję takich samych wyników, dla mnie tekst osi nigdy nie jest dobrze dopasowywany za pomocą metody auto. Jednak korzystanie z rads = (-angle - positions[[ position ]])*pi/180lepszych miejsc docelowych. Zwróć uwagę na dodatkowy znak minus przed kątem. W każdym razie dzięki za kod :)
asac
7

W ggpubr oferty pakietowe skrót, który robi słusznie domyślnie (po prawej tekst wyrównanie, polu tekstowym środkowy align zaznaczyć):

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

Utworzono 06.11.2018 przez pakiet reprezentx (v0.2.1)

Znaleziono podczas wyszukiwania w GitHub odpowiednich nazw argumentów: https://github.com/search?l=R&q=element_text+angle+90+vjust+org%3Acran&type=Code

krlmlr
źródło
5

Alternatywnie ggplot 3.3.0zapewnia guide_axis(n.dodge = 2)(jako guideargument do scale_..lub jako xargument do guides) rozwiązanie problemu nadmiernego wydruku poprzez unikanie etykiet w pionie. W tym przypadku działa całkiem dobrze:

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

jan-glx
źródło
1

Aby uzyskać czytelne etykiety x tick bez dodatkowych zależności, należy użyć:

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

Powoduje to obrócenie etykiet zaznaczenia o 90 ° w kierunku przeciwnym do ruchu wskazówek zegara i wyrównanie ich w pionie na ich końcu ( hjust = 1) i wyśrodkowanie w poziomie z odpowiednim znacznikiem (vjust = 0.5 ).

Pełny przykład:

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


Zauważ, że pionowe / poziome parametry Uzasadnienie vjust/ hjustz element_textodnoszą się do tekstu. Dlatego vjustodpowiada za wyrównanie w poziomie .

Bez vjust = 0.5tego wyglądałoby to tak:

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

Bez hjust = 1tego wyglądałoby to tak:

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

Jeśli z jakiegoś powodu (przewodowy) Państwo chcieli obrócić kleszcza etykiet 90 ° w prawo (tak, że można je czytać od lewej) będzie trzeba użyć: q + theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust = -1)).

Wszystko to zostało już omówione w komentarzach do tej odpowiedzi, ale tak często wracam do tego pytania, że ​​chcę odpowiedzi, z której mogę po prostu skopiować bez czytania komentarzy.

jan-glx
źródło
0

Alternatywą coord_flip()jest użycie ggstancepakietu. Zaletą jest to, że ułatwia łączenie wykresów z innymi typami wykresów i, co ważniejsze, można ustawić stałe współczynniki skali dla układu współrzędnych .

library(ggplot2)
library(ggstance)

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

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

Utworzono 2020-03-11 przez pakiet reprezentx (v0.3.0)

Tjebo
źródło