Чи є спосіб змінити інтервал між елементами легенди в 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.