Чи є спосіб змінити інтервал між елементами легенди в ggplot2?


120

Чи є спосіб змінити інтервал між елементами легенди в ggplot2? На даний момент я маю

legend.position ="top" 

яка автоматично створює горизонтальну легенду. Однак відстань між предметами дуже близьке між собою, і мені цікаво, як розмістити їх далі один від одного.


Було б корисно прийняти поточне рішення цього питання, яке optsзараз знецінюється.
— геотеорія


3
Відповідь Тунга, що знаходиться внизу цієї теми, має оновлення липня 2018 року. Помилки були виправлені, і хиткі обхідні шляхи, як той, що знаходиться в пастелі вище, більше не потрібні.
— PatrickT

Відповіді:


90

ggplot2 v3.0.0випущений в липні 2018 року має можливості працювати , щоб змінити legend.spacing.x, legend.spacing.yі legend.text.

Приклад: збільшення горизонтального проміжку між клавішами легенди

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

Примітка. Якщо ви хочете розширити лише інтервал праворуч від тексту легенди, використовуйте stringr::str_pad()

Приклад: перемістіть мітки клавіш легенди на дно та збільште вертикальний інтервал

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

Приклад: для 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)) 


Для вертикальних легенд встановлення legend.key.sizeлише збільшує розмір клавіш легенди, а не вертикальний пробіл між ними

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

Щоб збільшити відстань між клавішами легенди, legend-draw.rпотрібна модифікація функції. Дивіться цю проблему для отримання додаткової інформації

# 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
Дякуємо, що вказали на це. Це така чудова нова функція, я завжди використовував брудне виправлення @ user2568648, ха-ха!
— Тебо

1
Ваша функція збільшити вертикальний проміжок між клавішами легенди - це єдине знайдене нами рішення, яке працює саме так, як я бажаю, і з легкістю використання. Дякую!
— Docconcoct

69

Я думаю, що найкращим варіантом є використання guide_legendв межах guides:

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

Зверніть увагу на використання default.unit, не потрібно завантажувати gridпакет.


2
Для цього потрібно більше результатів, інші відповіді застаріли.
— Брендон Бертелсен

8
Це може працювати для горизонтальних легенд. Однак для моєї вертикальної легенди праворуч від ділянки це збільшує лише висоту ключа, а не відстань між клавішами. Клавіші моєї легенди ще дуже близькі один до одного.
— Мухсін Захід Угур

9
Як каже Мушин, це не вистачає точки, як і в інших відповідях, якщо легенда є ВЕРТИКАЛЬНОЮ, вона розтягує клавіші легенди (наприклад, відрізки рядків), не прокладаючи пробіл між клавішами.
— PatrickT

Чудово працює разом з geom_line та geom_point.
— Нільс Холст

45

Просте виправлення, яке я використовую для додавання місця в горизонтальних легендах, просто додайте пробіли в мітках (див. Витяг нижче):

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

13
Це єдина відповідь поки що, яка стосується питання! Це може бути корисно в разі багатьох записів: scale_fill_manual(values=values, labels=setNames(paste(labels, " "), entries)).
— СашаH

2
Технічно не дуже приємно, особливо коли вам доводиться вводити ці простори в рівні факторів, але це єдине робоче рішення.
— Патрік Бючер

2
Або ми можемо використовувати str_pad, щоб трохи полегшити життя
— Tung

37

Тепер, коли optsце застаріло в ggplot2пакеті, themeзамість нього слід використовувати функцію :

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

18
Це рішення змінює висоту / ширину коробок на відміну від відстані між ними.
— Берк У.

25

Щоб додати інтервал між записами в легенді, відрегулюйте поля елемента теми legend.text.

Щоб додати 30 крапки місця праворуч від кожної мітки легенди (може бути корисно для горизонтальної легенди):

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

Щоб додати 30 крапки місця зліва від кожної мітки легенди (може бути корисно для вертикальної легенди):

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

для ggplot2об’єкта p. Ключові слова - legend.textі margin.

[Примітка про редагування: Коли ця відповідь була вперше опублікована, виникла помилка. Помилка тепер виправлена]


3
Помилка тепер виправлена, це має бути прийнятою відповіддю.
— giocomai

1
Дивіться також відповідь Тунга на оновлення з цих питань у липні 2018 року.
— PatrickT

17

Схоже, найкращим підходом (у 2018 році) є використання legend.key.size під themeоб’єктом. (наприклад, дивіться тут ).

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

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

Це дуже просто, якщо ви використовуєте 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)

введіть тут опис зображення

Однак це інакше не дуже добре працює (наприклад, якщо вам потрібен сірий фон на символі легенди):

  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

Зауважте, що білі квадрати починають блокувати назву легенди (і, зрештою, сам графік, якщо ми продовжували збільшувати значення).

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

введіть тут опис зображення

Я не зовсім знайшов обхід для вирішення вищезазначеної проблеми ... Повідомте мене в коментарях, якщо у вас є ідея, і я відповідно оновлю!

  • Цікаво, чи є спосіб змінити рівень шару за допомогою $layers...

Зробіть legend.keyпрозорий:theme(legend.key = element_rect(size = 30,color=alpha("transparent",0)))
— ukosteopath

1
це була найпростіша відповідь і найпростіша у використанні imo
— Blacklivesmatter

14

З роботи Кошке на ggplot2 та його блозі (блог Кошке )

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

Введіть theme_get()консоль, щоб побачити інші редаговані атрибути легенди.


12
Дякуємо за пропозицію та посилання на блог Кошке! На жаль, однак, здається, це змінює розміри коробок, але не відстань між предметами.
— переповнення

Можливо, ви зможете "підробити" це за допомогою якогось типу накладеної могили. Але я не думаю, що це спосіб отримати додатковий інтервал в легенді. Це єдина згадка про це, яку я міг знайти у списку розсилки ggplot2: groups.google.com/forum/?fromgroups#!topic/ggplot2/PhkJpP8zJuM
— Брендон Бертелсен

2
Я можу використовувати це, щоб успішно збільшити відстань між легендами. Використання від'ємних чисел сприяло зменшенню відстані між легендами.
— Нова

5

Використовуйте будь-яке з них

legend.spacing = unit(1,"cm")
legend.spacing.x = unit(1,"cm")
legend.spacing.y = unit(1,"cm")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.