Aslabels roteren en uit elkaar plaatsen in ggplot2

Ik heb een plot waarin de x-as een factor is waarvan de labels lang zijn. Hoewel dit waarschijnlijk geen ideale visualisatie is, zou ik deze labels voor nu gewoon willen roteren om verticaal te zijn. Ik heb dit deel uitgezocht met de onderstaande code, maar zoals je kunt zien, zijn de labels niet helemaal zichtbaar.

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


Antwoord 1, autoriteit 100%

Verander de laatste regel in

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

Standaard worden de assen uitgelijnd in het midden van de tekst, zelfs als ze worden gedraaid. Als je +/- 90 graden draait, wil je meestal dat het in plaats daarvan aan de rand wordt uitgelijnd:

De afbeelding hierboven is van deze blogpost.


Antwoord 2, autoriteit 9%

Gebruik coord_flip()

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))
qplot(cut, carat, data = diamonds, geom = "boxplot") +
  coord_flip()


Voeg str_wrap()

toe

# wrap text to no more than 15 spaces
library(stringr)
diamonds$cut2 <- str_wrap(diamonds$cut, width = 15)
qplot(cut2, carat, data = diamonds, geom = "boxplot") +
  coord_flip()


In hoofdstuk 3.9 van R voor datawetenschap, Wickham en Grolemund spreken precies over deze vraag:

coord_flip()schakelt de x- en y-assen om. Dit is bijvoorbeeld handig als je horizontale boxplots wilt. Het is ook handig voor lange labels: het is moeilijk om ze passend te krijgen zonder overlapping op de x-as.


Antwoord 3, autoriteit 8%

Om de tekst op de vinkjes volledig zichtbaar te maken en in dezelfde richting te lezen als het label op de y-as, wijzigt u de laatste regel in

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

Antwoord 4, autoriteit 3%

ggplot 3.3.0lost dit op door guide_axis(angle = 90)op te geven (als guideargument voor scale_..of als xargument voor guides):

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(angle = 90)) +
  # ... or, equivalently:
  # guides(x =  guide_axis(angle = 90)) +
  NULL

Van de documentatie van het angle-argument:

Vergeleken met het instellen van de hoek in theme() / element_text(), is dit ook
gebruikt een aantal heuristieken om automatisch de hjust te kiezen en dat te doen
je waarschijnlijk wilt.


Als alternatief biedt het ook guide_axis(n.dodge = 2)(als guideargument voor scale_..of als x-argument voor guides) om het over-plotprobleem op te lossen door de labels verticaal te ontwijken. In dit geval werkt het vrij goed:

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


Antwoord 5, autoriteit 2%

Ik wil graag een alternatieve oplossing bieden, een robuuste oplossing die lijkt op wat ik ga voorstellen, was vereist in de nieuwste versie van ggtern, sinds de introductie van de canvasrotatiefunctie.

Kortom, u moet de relatieve posities bepalen met behulp van trigonometrie, door een functie te bouwen die een element_textobject retourneert, een gegeven hoek (dwz graden) en positionering (dwz een van x,y,top of rechts) informatie.

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

Eerlijk gezegd denk ik dat naar mijn mening een ‘auto’-optie beschikbaar moet worden gemaakt in ggplot2voor de argumenten hjusten vjust, laten we bij het specificeren van de hoek hoe dan ook demonstreren hoe het bovenstaande werkt.

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

Wat het volgende oplevert:


Antwoord 6

Het pakket ggpubrbiedt een snelkoppeling die standaard het juiste doet (tekst rechts uitlijnen, tekstvak midden uitlijnen om aan te vinken):

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

gemaakt op 2018-11-06 door de Reprex-pakket (v0.2.1)

Gevonden met een GitHub zoeken naar de relevante argumentnamen: https://github.com/search?l=r&amp ;Q=element_text+gle+90+vjust+org%3Acran&Type=code


7

Een alternatief voor coord_flip()is om de ggstance-pakket te gebruiken.
Het voordeel is dat het het gemakkelijker maakt om de grafieken te combineren met andere grafische typen en u kunt, misschien nog belangrijker, Stel vaste schaalverhoudingen voor uw coördinatensysteem .

library(ggplot2)
library(ggstance)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))
ggplot(data=diamonds, aes(carat, cut)) + geom_boxploth()

gemaakt op 2020-03-11 door de reprrex pakket (v0.3.0)

Other episodes