จะเพิ่มคำบรรยาย ggplot2 ที่มีขนาดและสีต่างกันได้อย่างไร?


89

ฉันใช้ ggplot2 เพื่อปรับปรุงบาร์พล็อตการตกตะกอน

นี่คือตัวอย่างที่ทำซ้ำได้ของสิ่งที่ฉันต้องการบรรลุ:

library(ggplot2)
library(gridExtra)
secu <- seq(1, 16, by=2)
melt.d <- data.frame(y=secu, x=LETTERS[1:8])
m <- ggplot(melt.d, aes(x=x, y=y)) +
  geom_bar(fill="darkblue") + 
  labs(x="Weather    stations", y="Accumulated Rainfall [mm]") +
  opts(axis.text.x=theme_text(angle=-45, hjust=0, vjust=1),
       title=expression("Rainfall"), plot.margin = unit(c(1.5, 1, 1, 1), "cm"),
       plot.title = theme_text(size = 25, face = "bold", colour = "black", vjust = 5))
z <- arrangeGrob(m, sub = textGrob("Location", x = 0, hjust = -3.5, vjust = -33, gp = gpar(fontsize = 18, col = "gray40"))) #Or guessing x and y with just option
z

ฉันไม่รู้จะหลีกเลี่ยงการใช้การเดาตัวเลขบน hjust และ vjust บน ggplot2 ได้อย่างไร? มีวิธีที่ดีกว่าในการใส่คำบรรยาย (ไม่ใช่แค่ใช้ \ n แต่เป็นคำบรรยายที่มีสีและขนาดข้อความต่างกัน)

ฉันต้องสามารถใช้กับ ggsave เพื่อให้มีไฟล์ pdf

คำถามที่เกี่ยวข้องสองข้อมีดังนี้

เพิ่มการอ้างอิงเชิงอรรถนอกพื้นที่พล็อตใน R?

ฉันจะเพิ่มคำบรรยายและเปลี่ยนขนาดฟอนต์ของ ggplot plot ใน R ได้อย่างไร

ขอบคุณสำหรับความช่วยเหลือใด ๆ


vjust = -33 ใช้งานได้สำหรับฉันบน Linux ฉันรู้ว่าส่วนย่อยนั้นหมายถึงการไปที่ด้านล่างของโครงเรื่อง แต่มันเป็นวิธีเดียวที่ฉันได้สิ่งที่ฉันต้องการ
Migue

ด้วยเหตุผลบางอย่างทำให้พล็อตของฉันเล็กมากและสร้างพื้นที่ขนาดใหญ่ใต้กราฟ
zazu

2
คำตอบของ @hrbrmstr ดูเหมือนจะเป็นหนทางไปในปัจจุบัน
andschar

คำตอบ:


103

ggplot2 builds ล่าสุด (เช่น 2.1.0.9000 หรือใหม่กว่า) มีคำบรรยายและคำบรรยายใต้ภาพเป็นฟังก์ชันในตัว นั่นหมายความว่าคุณสามารถทำได้:

library(ggplot2) # 2.1.0.9000+ 

secu <- seq(1, 16, by=2)
melt.d <- data.frame(y=secu, x=LETTERS[1:8])

m <-  ggplot(melt.d, aes(x=x, y=y))
m <- m + geom_bar(fill="darkblue", stat="identity")
m <- m + labs(x="Weather    stations", 
              y="Accumulated Rainfall [mm]",
              title="Rainfall",
              subtitle="Location")
m <- m + theme(axis.text.x=element_text(angle=-45, hjust=0, vjust=1)) 
m <- m + theme(plot.title=element_text(size=25, hjust=0.5, face="bold", colour="maroon", vjust=-1))
m <- m + theme(plot.subtitle=element_text(size=18, hjust=0.5, face="italic", color="black"))
m

ข้อผิดพลาดใน (function (el, elname): "plot.subtitle" ไม่ใช่ชื่อองค์ประกอบของธีมที่ถูกต้อง
Luís de Sousa

1
โปรดอ่านคำตอบ: "ggplot2 builds ล่าสุด (เช่น 2.1.0.9000 หรือใหม่กว่า)"
hrbrmstr

75

ละเว้นคำตอบ ggplot2เวอร์ชัน 2.2.0 นี้มีฟังก์ชันชื่อและคำบรรยาย ดูคำตอบ @ hrbrmstr ของด้านล่าง


คุณสามารถใช้atopฟังก์ชันที่ซ้อนกันภายใน an expressionเพื่อให้ได้ขนาดต่างๆกัน

แก้ไขรหัสที่อัปเดตสำหรับ ggplot2 0.9.3

m <-  ggplot(melt.d, aes(x=x, y=y)) + 
     geom_bar(fill="darkblue", stat = "identity") + 
     labs(x="Weather    stations", y="Accumulated Rainfall [mm]") + 
     ggtitle(expression(atop("Rainfall", atop(italic("Location"), "")))) +
     theme(axis.text.x = element_text(angle=-45, hjust=0, vjust=1), 
     #plot.margin = unit(c(1.5, 1, 1, 1), "cm"), 
     plot.title = element_text(size = 25, face = "bold", colour = "black", vjust = -1))

ใส่คำอธิบายภาพที่นี่


10
สวัสดีนี่เป็นทางออกที่ยอดเยี่ยม ฉันต้องการใช้ แต่แทนที่จะเป็นatop(italic("Location")ฉันต้องการวัตถุ: atop(italic(my_string_vector). ฉันพยายามที่ แต่แล้วคำบรรยายการประเมินเพื่อ(my_string_vector) จะบังคับให้นิพจน์นี้ใช้ค่าสตริงและไม่ปฏิบัติตามข้อความที่ระบุได้อย่างไร
Konrad

1
ในกรณีที่คุณมีปัญหาในการใช้ตัวแปรที่คุณควรใช้bquoteแทนexpressionดูที่นี่
toto_tico

3
@Konrad ต้องใช้วัตถุแทนที่expressionด้วยbquoteและห่อวัตถุที่มี.()เช่นนี้สำหรับชื่อเรื่องหลักเก็บไว้ในวัตถุที่เรียกว่า "main.title" และคำบรรยายเก็บไว้ในวัตถุที่เรียกว่า "sub.title": ggtitle(bquote(atop(.(main.title), atop(italic(.(sub.title)), "")))) เครดิตไป Didzis คำตอบของ Elferts ที่นี่: stackoverflow.com/questions/19957536/…
coip

10

ดูเหมือนว่าoptsจะเลิกใช้งานเมื่อ ggplot 2 0.9.1 และไม่สามารถใช้งานได้อีกต่อไป สิ่งนี้ใช้ได้ผลกับฉันด้วยเวอร์ชันล่าสุด ณ วันนี้: + ggtitle(expression(atop("Top line", atop(italic("2nd line"), "")))).


สิ่งนี้ยังใช้งานได้โดยไม่มีขั้นสุดท้าย, ""- ส่วนนั้นมีไว้เพื่ออะไร?
naught101

เต้นฉัน ฉันอาจจะคัดลอกตัวอย่างที่เห็นจากที่อื่น
Aren Cambre

น่าจะเป็นจากคำตอบของ @ SandyMuspratt ข้างบน: P - ฉันเข้าใจแล้วตอนนี้atop()เป็นเศษส่วนที่ไม่มีแท่ง ดังนั้นการใส่วินาทีatop()เข้าไปในตัวแรกจะทำให้คุณมีเศษส่วนย่อยโดยที่ข้อความจะเล็กลงตามสัดส่วน ""เป็นด้านล่างของย่อยเศษ ดูเหมือนจะไม่จำเป็น - อาจatop()มีสตริงว่างเริ่มต้นสำหรับพารามิเตอร์ที่สองหรือบางอย่าง
naught101

ดูเหมือนว่าคำตอบของ @ SandyMuspratt ได้รับการแก้ไขหลังจากที่ฉันโพสต์คำตอบเพื่อสะท้อนรหัสที่คล้ายกับของฉัน :-)
Aren Cambre

9

ไม่ยากเกินไปที่จะเพิ่ม grobs ลงใน gtable และสร้างชื่อที่แปลกใหม่ด้วยวิธีนั้น

library(ggplot2)
library(grid)
library(gridExtra)
library(magrittr)
library(gtable)

p <- ggplot() + 
  theme(plot.margin = unit(c(0.5, 1, 1, 1), "cm"))

lg <- list(textGrob("Rainfall", x=0, hjust=0, 
                    gp = gpar(fontsize=24, fontfamily="Skia", face=2, col="turquoise4")),
               textGrob("location", x=0, hjust=0, 
                        gp = gpar(fontsize=14, fontfamily="Zapfino", fontface=3, col="violetred1")),
           pointsGrob(pch=21, gp=gpar(col=NA, cex=0.5,fill="steelblue")))

margin <- unit(0.2, "line")
tg <- arrangeGrob(grobs=lg, layout_matrix=matrix(c(1,2,3,3), ncol=2),
                  widths = unit.c(grobWidth(lg[[1]]), unit(1,"null")),
                  heights = do.call(unit.c, lapply(lg[c(1,2)], grobHeight)) + margin)

grid.newpage()
ggplotGrob(p) %>%
  gtable_add_rows(sum(tg$heights), 0) %>%
  gtable_add_grob(grobs=tg, t = 1, l = 4)  %>%
  grid.draw()

ใส่คำอธิบายภาพที่นี่


8

เวอร์ชันนี้ใช้gtableฟังก์ชัน อนุญาตให้มีข้อความสองบรรทัดในชื่อเรื่อง ข้อความขนาดสีและแบบอักษรของแต่ละบรรทัดสามารถตั้งค่าได้โดยไม่ขึ้นกับเส้นอื่น ๆ อย่างไรก็ตามฟังก์ชันนี้จะแก้ไขพล็อตด้วยแผงพล็อตเดียวเท่านั้น

แก้ไขเล็กน้อย: กำลังอัปเดตเป็น ggplot2 v2.0.0

# The original plot
library(ggplot2)

secu <- seq(1, 16, by = 2)
melt.d <- data.frame(y = secu, x = LETTERS[1:8])

m <- ggplot(melt.d, aes(x = x, y = y)) + 
     geom_bar(fill="darkblue", stat = "identity") + 
     labs(x = "Weather    stations", y = "Accumulated Rainfall [mm]") + 
     theme(axis.text.x = element_text(angle = -45, hjust = 0, vjust = 1))


# The function to set text, size, colour, and face
plot.title = function(plot = NULL, text.1 = NULL, text.2 = NULL, 
   size.1 = 12,  size.2 = 12,
   col.1 = "black", col.2 = "black", 
   face.1 = "plain",  face.2 = "plain") {

library(gtable)
library(grid)

gt = ggplotGrob(plot)

text.grob1 = textGrob(text.1, y = unit(.45, "npc"), 
   gp = gpar(fontsize = size.1, col = col.1, fontface = face.1))
text.grob2 = textGrob(text.2,  y = unit(.65, "npc"), 
   gp = gpar(fontsize = size.2, col = col.2, fontface = face.2))

text = matrix(list(text.grob1, text.grob2), nrow = 2)
text = gtable_matrix(name = "title", grobs = text, 
   widths = unit(1, "null"), 
   heights = unit.c(unit(1.1, "grobheight", text.grob1) + unit(0.5, "lines"), unit(1.1,  "grobheight", text.grob2) + unit(0.5, "lines")))

gt = gtable_add_grob(gt, text, t = 2, l = 4)
gt$heights[2] = sum(text$heights)

class(gt) =  c("Title", class(gt))

gt
}

# A print method for the plot
print.Title <- function(x) {
   grid.newpage()   
   grid.draw(x)
}


# Try it out - modify the original plot
p = plot.title(m, "Rainfall", "Location", 
   size.1 = 20, size.2 = 15, 
   col.1 = "red", col.2 = "blue", 
   face.2 = "italic")

p

ใส่คำอธิบายภาพที่นี่


3

คุณสามารถใช้ตัดพล็อตใน grid.arrange และส่งผ่านชื่อตามตารางที่กำหนดเอง

ใส่คำอธิบายภาพที่นี่

library(ggplot2)
library(gridExtra)

p <- ggplot() + 
  theme(plot.margin = unit(c(0.5, 1, 1, 1), "cm"))

tg <- grobTree(textGrob("Rainfall", y=1, vjust=1, gp = gpar(fontsize=25, face=2, col="black")),
               textGrob("location", y=0, vjust=0, gp = gpar(fontsize=12, face=3, col="grey50")),
               cl="titlegrob")
heightDetails.titlegrob <- function(x) do.call(sum,lapply(x$children, grobHeight))

grid.arrange(p, top = tg)

ggplot เวอร์ชันปัจจุบันใช้ธีมและและ element_text แทนตัวเลือกและ theme_text ตามลำดับ นอกจากนี้แนวทาง ggplotGrob ดูเหมือนจะล้มเหลวในเวอร์ชันปัจจุบันของ gridExtra (gridExtra_0.8.1) และ ggplot2 (ggplot2_0.9.3.1)
russellpierce

2

คุณอาจสังเกตเห็นว่าโค้ดของ Sandy ไม่ได้สร้างชื่อที่เป็นตัวหนาสำหรับ "Rainfall" - คำแนะนำในการทำให้ตัวหนานี้ควรเกิดขึ้นภายในฟังก์ชัน atop () แทนที่จะเป็นฟังก์ชัน theme ()

ggplot(melt.d, aes(x=x, y=y)) + 
 geom_bar(fill="darkblue", stat = "identity") + 
 labs(x="Weather    stations", y="Accumulated Rainfall [mm]") + 
 ggtitle(expression(atop(bold("Rainfall"), atop(italic("Location"), "")))) +
 theme(axis.text.x = element_text(angle=-45, hjust=0, vjust=1),
 plot.title = element_text(size = 25, colour = "black", vjust = -1))

ใส่คำอธิบายภาพที่นี่

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