การหมุนและการเว้นวรรคฉลากแกนใน ggplot2


669

ฉันมีพล็อตที่แกน x เป็นปัจจัยที่มีฉลากยาว แม้ว่าตอนนี้อาจไม่ใช่การสร้างภาพในอุดมคติ แต่ตอนนี้ฉันต้องการหมุนป้ายกำกับเหล่านี้ให้เป็นแนวตั้ง ฉันพบส่วนนี้ด้วยโค้ดด้านล่าง แต่อย่างที่คุณเห็นป้ายกำกับจะไม่ปรากฏให้เห็นโดยสิ้นเชิง

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

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบ:


1112

เปลี่ยนบรรทัดสุดท้ายเป็น

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

โดยค่าเริ่มต้นแกนจะถูกจัดตำแหน่งที่กึ่งกลางของข้อความแม้ในขณะที่หมุน เมื่อคุณหมุน +/- 90 องศาโดยปกติคุณต้องการให้จัดแนวที่ขอบแทน:

ข้อความแสดงแทน

ภาพด้านบนมาจากบล็อกโพสต์นี้


95
ใน ggplot2 เวอร์ชันใหม่ล่าสุดคำสั่งจะเป็น: q + theme(axis.text.x=element_text(angle = -90, hjust = 0))
rnorberg

55
เพื่อให้ผู้ที่ hjust theme(axis.text.x=element_text(angle = 90, vjust = 0.5))ไม่ได้พฤติกรรมตามที่อธิบายไว้ที่นี่ลอง จาก ggplot2 0.9.3.1 ดูเหมือนว่าจะเป็นวิธีแก้ปัญหา
lilster

42
อันที่จริงผมมีการรวมสองการแก้ปัญหาดังกล่าวข้างต้นจะได้รับป้ายชิดอย่างถูกต้อง:q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
jupp0r

32
@ jupp0r ถูกต้องแล้ว theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))เป็นหนึ่งในการทำงานในปัจจุบัน

51
ถ้าคุณต้องการป้ายกำกับแบบหมุน 45 ° (อ่านง่ายขึ้น) theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1))ให้ผลลัพธ์ที่ดี
jan-glx

89

ในการทำให้ข้อความบนป้ายกำกับเห็บปรากฏให้เห็นอย่างสมบูรณ์และอ่านในทิศทางเดียวกับป้ายกำกับแกน y ให้เปลี่ยนบรรทัดสุดท้ายเป็น

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

81

ใช้ coord_flip()

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

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

ป้อนคำอธิบายรูปภาพที่นี่


ใน Ch 3.9 of R สำหรับวิทยาศาสตร์ข้อมูล Wickham และ Grolemund พูดกับคำถามที่แน่นอนนี้:

coord_flip()สลับแกน x และ y สิ่งนี้มีประโยชน์ (ตัวอย่าง) หากคุณต้องการ boxplots แนวนอน นอกจากนี้ยังมีประโยชน์สำหรับฉลากแบบยาว: มันยากที่จะทำให้มันพอดีโดยไม่ต้องซ้อนทับบนแกน x


26

ฉันต้องการเสนอทางเลือกวิธีแก้ปัญหาที่มีประสิทธิภาพเช่นเดียวกับสิ่งที่ฉันกำลังจะเสนอให้เป็นสิ่งจำเป็นในggternเวอร์ชั่นล่าสุดตั้งแต่เปิดตัวคุณสมบัติการหมุนผ้าใบ

โดยทั่วไปคุณต้องกำหนดตำแหน่งสัมพัทธ์โดยใช้ตรีโกณมิติโดยการสร้างฟังก์ชันที่ส่งคืนelement_textวัตถุมุมที่กำหนด (เช่นองศา) และการวางตำแหน่ง (เช่นหนึ่งในข้อมูล x, y, ด้านบนหรือขวา)

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

ตามความเห็นของฉันฉันคิดว่าควรมีตัวเลือก 'อัตโนมัติ' ggplot2สำหรับhjustและสำหรับการvjustโต้แย้งเมื่อระบุมุมอย่างไรก็ตามให้แสดงวิธีการทำงานข้างต้น

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

ซึ่งผลิตสิ่งต่อไปนี้:

ตัวอย่าง


1
ฉันไม่ได้ผลลัพธ์เดียวกันสำหรับฉันข้อความของแกนไม่เคยถูกปรับโดยวิธีอัตโนมัติของคุณ อย่างไรก็ตามการใช้การrads = (-angle - positions[[ position ]])*pi/180จัดตำแหน่งที่ดีขึ้น สังเกตเครื่องหมายลบเพิ่มเติมก่อนมุม ขอบคุณสำหรับรหัสต่อไป :)
asac

7

ggpubrแพคเกจข้อเสนอทางลัดที่ไม่สิ่งที่ถูกต้องโดยค่าเริ่มต้น (ข้อความชิดขวากล่องข้อความจัดกลางติ๊ก) A:

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

สร้างเมื่อ 2018-11-06 โดยแพ็คเกจ reprex (v0.2.1)

พบกับ GitHub ค้นหาชื่ออาร์กิวเมนต์ที่เกี่ยวข้อง: https://github.com/search?l=R&q=element_text+angle+90+vjust+org%3Acran&type=Code


5

อีกทางหนึ่งggplot 3.3.0จัดเตรียมguide_axis(n.dodge = 2)(เป็นguideอาร์กิวเมนต์ไปยังscale_..หรือเพื่อxโต้แย้ง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(n.dodge = 2)) +
  NULL


1

หากต้องการรับเลเบล x ที่อ่านได้โดยไม่ต้องพึ่งพาเพิ่มเติมคุณต้องการใช้:

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

สิ่งนี้จะหมุนป้ายกำกับเห็บ 90 °ทวนเข็มนาฬิกาและจัดเรียงพวกมันในแนวตั้งที่จุดสิ้นสุด ( hjust = 1) และกึ่งกลางแนวนอนของพวกเขาด้วยเครื่องหมายเห็บที่สอดคล้องกัน (vjust = 0.5 )

ตัวอย่างเต็มรูปแบบ:

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


ทราบว่าพารามิเตอร์เหตุผลแนวตั้ง / แนวนอนvjust/hjustของelement_textสัมพันธ์กับข้อความ ดังนั้นจึงvjustมีความรับผิดชอบสำหรับการจัดตำแหน่งแนวนอน

ไม่มี vjust = 0.5มันจะมีลักษณะเช่นนี้:

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

ไม่มี hjust = 1มันจะมีลักษณะเช่นนี้:

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

ถ้าบางคน (แบบใช้สาย) เหตุผลที่คุณอยากจะหมุนเห็บป้าย 90 °ตามเข็มนาฬิกา (เช่นที่พวกเขาสามารถอ่านจากซ้าย) q + theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust = -1))คุณจะต้องใช้งาน:

ทั้งหมดนี้ได้ถูกกล่าวถึงในความคิดเห็นของคำตอบนี้แล้วแต่ฉันกลับมาที่คำถามนี้บ่อยครั้งซึ่งฉันต้องการคำตอบที่ฉันสามารถคัดลอกได้โดยไม่ต้องอ่านความคิดเห็น


0

อีกทางเลือกหนึ่งcoord_flip()คือใช้ggstanceแพ็คเกจ ข้อดีคือมันทำให้ง่ายที่จะรวมกราฟที่มีประเภทกราฟอื่น ๆ และคุณสามารถอาจจะมากขึ้นที่สำคัญตั้งคงอัตราส่วนขนาดระบบการประสานงานของคุณ

library(ggplot2)
library(ggstance)

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

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

สร้างเมื่อ 2020-03-11 โดยแพ็คเกจ reprex (v0.3.0)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.