Có cách nào để thay đổi khoảng cách giữa các mục chú giải trong ggplot2 không?


120

Có cách nào để thay đổi khoảng cách giữa các mục chú giải trong ggplot2 không? Tôi hiện có

legend.position ="top" 

tự động tạo chú giải ngang. Tuy nhiên, khoảng cách của các mục rất gần nhau và tôi đang băn khoăn không biết làm thế nào để chúng cách xa nhau hơn.


Sẽ rất hữu ích nếu có một giải pháp hiện tại cho vấn đề này đang optsbị mất giá.
geotheory


3
Câu trả lời của Tùng, hiện ở cuối chủ đề này, có bản cập nhật tháng 7 năm 2018. Các lỗi đã được khắc phục và các giải pháp hacky như trong pastebin ở trên không còn cần thiết nữa.
PatrickT

Câu trả lời:


90

ggplot2 v3.0.0phát hành vào tháng 7 năm 2018 đã lựa chọn làm việc để sửa đổi legend.spacing.x, legend.spacing.ylegend.text.

Ví dụ: Tăng khoảng cách ngang giữa các phím chú giải

library(ggplot2)

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + 
  geom_bar() +
  coord_flip() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(1.0, 'cm'))

Lưu ý: Nếu bạn chỉ muốn mở rộng khoảng cách ở bên phải của văn bản chú giải, hãy sử dụng stringr::str_pad()

Ví dụ: Di chuyển các nhãn của phím chú giải xuống dưới cùng và tăng khoảng cách theo chiều dọc

ggplot(mtcars, aes(factor(cyl), fill = factor(cyl))) + 
  geom_bar() +
  coord_flip() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(1.0, 'cm'),
        legend.text = element_text(margin = margin(t = 10))) +
  guides(fill = guide_legend(title = "Cyl",
                             label.position = "bottom",
                             title.position = "left", title.vjust = 1)) 

Ví dụ: cho scale_fill_xxx&guide_colorbar

ggplot(mtcars, aes(mpg, wt)) +
  geom_point(aes(fill = hp), pch = I(21), size = 5)+
  scale_fill_viridis_c(guide = FALSE) +
  theme_classic(base_size = 14) +
  theme(legend.position = 'top', 
        legend.spacing.x = unit(0.5, 'cm'),
        legend.text = element_text(margin = margin(t = 10))) +
  guides(fill = guide_colorbar(title = "HP",
                               label.position = "bottom",
                               title.position = "left", title.vjust = 1,
                               # draw border around the legend
                               frame.colour = "black",
                               barwidth = 15,
                               barheight = 1.5)) 


Đối với chú giải theo chiều dọc , cài đặt legend.key.sizechỉ làm tăng kích thước của các phím chú thích, không làm tăng khoảng cách dọc giữa chúng

ggplot(mtcars) +
  aes(x = cyl, fill = factor(cyl)) +
  geom_bar() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.key.size = unit(1, "cm"))

Để tăng khoảng cách giữa các phím chú giải, cần sửa đổi legend-draw.rchức năng. Xem vấn đề này để biết thêm thông tin

# function to increase vertical spacing between legend keys
# @clauswilke
draw_key_polygon3 <- function(data, params, size) {
  lwd <- min(data$size, min(size) / 4)

  grid::rectGrob(
    width = grid::unit(0.6, "npc"),
    height = grid::unit(0.6, "npc"),
    gp = grid::gpar(
      col = data$colour,
      fill = alpha(data$fill, data$alpha),
      lty = data$linetype,
      lwd = lwd * .pt,
      linejoin = "mitre"
    ))
}

# register new key drawing function, 
# the effect is global & persistent throughout the R session
GeomBar$draw_key = draw_key_polygon3

ggplot(mtcars) +
  aes(x = cyl, fill = factor(cyl)) +
  geom_bar() +
  scale_fill_brewer("Cyl", palette = "Dark2") +
  theme_minimal(base_size = 14) +
  theme(legend.key = element_rect(color = NA, fill = NA),
        legend.key.size = unit(1.5, "cm")) +
  theme(legend.title.align = 0.5)


3
Cảm ơn vì đã chỉ ra điều này. Đây là một tính năng mới tuyệt vời, tôi luôn sử dụng bản sửa lỗi bẩn thỉu của @ user2568648, haha!
Tjebo

1
Chức năng của bạn để tăng khoảng cách theo chiều dọc giữa các phím chú giải là giải pháp duy nhất mà tôi thấy hoạt động chính xác như tôi mong muốn và dễ sử dụng. Cảm ơn!
Docconcoct

69

Tôi nghĩ lựa chọn tốt nhất là sử dụng guide_legendtrong guides:

p + guides(fill=guide_legend(
                 keywidth=0.1,
                 keyheight=0.1,
                 default.unit="inch")
      )

Lưu ý việc sử dụng default.unit, không cần tải gridgói.


2
Điều này cần nhiều lượt ủng hộ hơn, các câu trả lời khác đã lỗi thời.
Brandon Bertelsen

8
Điều này có thể làm việc cho các truyền thuyết ngang. Tuy nhiên, đối với chú giải theo chiều dọc của tôi ở bên phải cốt truyện, điều này chỉ làm tăng chiều cao của phím chứ không phải khoảng cách giữa các phím. Các phím huyền thoại của tôi vẫn rất gần nhau.
Muhsin Zahid Ugur

9
Như Mushin nói, điều này bỏ sót điểm, cũng như các câu trả lời khác, nếu chú giải là CHỨNG NHẬN thì nó sẽ kéo dài các phím chú giải (ví dụ: các đoạn đường thẳng) mà không cần đệm khoảng cách giữa các phím.
PatrickT

Hoạt động tốt cùng với geom_line và geom_point.
Niels Holst

45

Một bản sửa lỗi đơn giản mà tôi sử dụng để thêm khoảng trắng trong chú giải theo chiều ngang, chỉ cần thêm khoảng trắng trong nhãn (xem phần trích xuất bên dưới):

  scale_fill_manual(values=c("red","blue","white"),
                    labels=c("Label of category 1          ",
                             "Label of category 2          ",
                             "Label of category 3"))

13
Đây là câu trả lời duy nhất cho đến nay liên quan đến câu hỏi! Điều này có thể hữu ích trong trường hợp nhiều mục: scale_fill_manual(values=values, labels=setNames(paste(labels, " "), entries)).
SaschaH

2
Về mặt kỹ thuật thì không đẹp lắm, đặc biệt là khi bạn phải giới thiệu những không gian đó thành các cấp độ yếu tố, nhưng đó là giải pháp hiệu quả duy nhất.
Patrick Bucher

2
Hoặc chúng ta có thể sử dụng str_pad để làm cho cuộc sống dễ dàng hơn một chút
Tùng

37

Bây giờ nó optskhông được dùng nữa trong ggplot2gói, themenên sử dụng hàm để thay thế:

library(grid) # for unit()
... + theme(legend.key.height=unit(3,"line"))
... + theme(legend.key.width=unit(3,"line"))

18
Giải pháp này thay đổi chiều cao / chiều rộng của các hộp trái ngược với khoảng cách giữa chúng.
Berk U.

25

Để thêm khoảng cách giữa các mục nhập trong chú giải, hãy điều chỉnh lề của phần tử chủ đề legend.text.

Để thêm 30pt khoảng trống vào bên phải của mỗi nhãn chú giải (có thể hữu ích cho chú giải ngang):

p + theme(legend.text = element_text(
    margin = margin(r = 30, unit = "pt")))

Để thêm 30pt khoảng trống vào bên trái của mỗi nhãn chú giải (có thể hữu ích cho chú giải dọc):

p + theme(legend.text = element_text(
    margin = margin(l = 30, unit = "pt")))

cho một ggplot2đối tượng p. Các từ khóa là legend.textmargin.

[Lưu ý về chỉnh sửa: Khi câu trả lời này được đăng lần đầu tiên, đã có một lỗi. Lỗi hiện đã được sửa]


3
Lỗi hiện đã được sửa, đây sẽ là câu trả lời được chấp nhận.
giocomai,

1
Xem thêm câu trả lời của Tùng để cập nhật tháng 7 năm 2018 về những vấn đề này.
PatrickT

17

Có vẻ như cách tiếp cận tốt nhất (vào năm 2018) là sử dụng legend.key.sizebên dưới themeđối tượng. (ví dụ: xem tại đây ).

#Set-up:
    library(ggplot2)
    library(gridExtra)

    gp <- ggplot(data = mtcars, aes(mpg, cyl, colour = factor(cyl))) +
        geom_point()

Điều này thực sự dễ dàng nếu bạn đang sử dụng theme_bw():

  gpbw <- gp + theme_bw()

#Change spacing size:

  g1bw <- gpbw + theme(legend.key.size = unit(0, 'lines'))
  g2bw <- gpbw + theme(legend.key.size = unit(1.5, 'lines'))
  g3bw <- gpbw + theme(legend.key.size = unit(3, 'lines'))

  grid.arrange(g1bw,g2bw,g3bw,nrow=3)

nhập mô tả hình ảnh ở đây

Tuy nhiên, điều này không hoạt động khá tốt nếu không (ví dụ: nếu bạn cần nền màu xám trên biểu tượng chú giải của mình):

  g1 <- gp + theme(legend.key.size = unit(0, 'lines'))
  g2 <- gp + theme(legend.key.size = unit(1.5, 'lines'))
  g3 <- gp + theme(legend.key.size = unit(3, 'lines'))

  grid.arrange(g1,g2,g3,nrow=3)

#Notice that the legend symbol squares get bigger (that's what legend.key.size does). 

#Let's [indirectly] "control" that, too:
  gp2 <- g3
  g4 <- gp2 + theme(legend.key = element_rect(size = 1))
  g5 <- gp2 + theme(legend.key = element_rect(size = 3))
  g6 <- gp2 + theme(legend.key = element_rect(size = 10))

  grid.arrange(g4,g5,g6,nrow=3)   #see picture below, left

Lưu ý rằng các hình vuông màu trắng bắt đầu chặn tiêu đề chú giải (và cuối cùng là chính biểu đồ nếu chúng ta tiếp tục tăng giá trị).

  #This shows you why:
    gt <- gp2 + theme(legend.key = element_rect(size = 10,color = 'yellow' ))

nhập mô tả hình ảnh ở đây

Tôi chưa tìm thấy giải pháp khắc phục sự cố ở trên ... Hãy cho tôi biết trong phần nhận xét nếu bạn có ý tưởng và tôi sẽ cập nhật cho phù hợp!

  • Tôi tự hỏi liệu có cách nào đó để xếp lớp lại mọi thứ bằng cách sử dụng $layers...

Tận dụng tối legend.keyminh bạch:theme(legend.key = element_rect(size = 30,color=alpha("transparent",0)))
ukosteopath

1
đây là câu trả lời đơn giản nhất và dễ sử dụng nhất imo
Blacklivesmatter

14

Từ công việc của Koshke trên ggplot2 và blog của anh ấy (blog của Koshke )

... + theme(legend.key.height=unit(3,"line")) # Change 3 to X
... + theme(legend.key.width=unit(3,"line")) # Change 3 to X

Nhập theme_get()bảng điều khiển để xem các thuộc tính chú giải có thể chỉnh sửa khác.


12
Cảm ơn vì đề xuất và liên kết đến blog của Koshke! Tuy nhiên, thật không may, điều này dường như thay đổi kích thước của các hộp nhưng không thay đổi khoảng cách giữa các mục.
tràn

Bạn có thể "làm giả" nó bằng một số loại bẹn phủ. Nhưng tôi không nghĩ có cách nào để có thêm khoảng trống bên trong huyền thoại. Đây là đề cập duy nhất về nó mà tôi có thể tìm thấy trong danh sách gửi thư của ggplot2: groups.google.com/forum/?fromgroups#!topic/ggplot2/PhkJpP8zJuM
Brandon Bertelsen

2
Tôi có thể sử dụng điều này để tăng khoảng cách giữa các huyền thoại thành công. Sử dụng số âm đã giúp giảm khoảng cách giữa các chú giải.
Nova

5

Sử dụng bất kỳ cái nào trong số này

legend.spacing = unit(1,"cm")
legend.spacing.x = unit(1,"cm")
legend.spacing.y = unit(1,"cm")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.