Каков аргумент ширины в position_dodge?
В документации не объясняется, что именно это width
аргумент
- Чья ширина это указывает?
- Что такое "юнит"?
- Какое значение по умолчанию?
Значением по умолчанию является width = NULL
, но методом проб и ошибок видно, что width = 0.9
кажется, производит эффект по умолчанию (см. postscript). Тем не менее, я не мог найти, где такое значение по умолчанию установлено в ggplot2
исходный код Таким образом,
- Не могли бы вы объяснить, как уклонение по умолчанию реализовано в
ggplot2
код?
Суть вопроса заключается в том, чтобы позволить ggplot2
пользователи, чтобы найти соответствующие width
значения без проб и ошибок.
PS:
ggplot(data = df) +
geom_bar(aes(x, y, fill = factor(group)),
position = position_dodge(), stat = "identity")
ggplot(data = df) +
geom_bar(aes(x, y, fill = factor(group)),
position = position_dodge(0.9), stat = "identity")
1 ответ
Сначала я дам очень краткие ответы на три основных вопроса. Затем я прохожу несколько примеров, чтобы проиллюстрировать ответы более тщательно.
- Чья ширина это указывает?
Ширина элементов, которые будут уклонены. - Что такое "юнит "?
Фактическая или виртуальная ширина в единицах данных элементов, которые будут уклонены. - Какое значение по умолчанию?
Если вы не установите уклонениеwidth
явно, но полагаться на значение по умолчанию,position_dodge(width = NULL)
(или простоposition = "dodge"
), ширина dodge, которая используется, является фактической шириной в единицах данных элемента, который будет уклонен.
Я считаю, что ваш четвертый вопрос слишком широк для SO. Пожалуйста, обратитесь к коду collide
а также dodge
и, если необходимо, задайте новый, более конкретный вопрос.
В зависимости от ширины уклонения элемента (вместе с его исходным горизонтальным положением и количеством элементов в стопке), новые центральные позиции (x
) каждого элемента и новые ширины (xmin
, xmax
позиции) рассчитываются. Элементы смещены в горизонтальном направлении достаточно далеко, чтобы не перекрывать соседние элементы. Очевидно, что широкие элементы должны быть смещены больше, чем узкие элементы, чтобы избежать наложения.
Чтобы получить лучшее ощущение от уклонения в целом и использования width
В частности, в качестве аргумента я приведу несколько примеров. Мы начнем с простого штрихового графика с уклонением по умолчанию; мы можем использовать либо position = "dodge"
или более явный position = position_dodge(width = NULL)
# some toy data
df <- data.frame(x = 1,
y = 1,
grp = c("A", "B"))
p <- ggplot(data = df, aes(x = x, y = y, fill = grp)) + theme_minimal()
p + geom_bar(stat = "identity",
position = "dodge")
# which is the same as:
# position = position_dodge(width = NULL))
Итак (1) кто width
это в position_dodge
и (2) что такое единица измерения?
В ?position_dodge
мы можем прочитать:
width
: Ширина уклонения, если она отличается от ширины отдельных элементов
Таким образом, если мы используем значение по умолчанию width
т.е. NULL
расчет уклонения основан на ширине отдельных элементов.
Таким образом, тривиальным ответом на ваш первый вопрос " Чью ширину он определяет? " Будет: ширина отдельных элементов.
Но, конечно, мы тогда задаемся вопросом, что такое "ширина отдельных элементов"? Давайте начнем с баров. От ?geom_bar
:
width
: Ширина полосы. По умолчанию установлено 90% разрешения данных
Возникает новый вопрос: что такое разрешение? Давай проверим ?ggplot2::resolution
:
Разрешение - это наименьшее ненулевое расстояние между соседними значениями. Если есть только одно уникальное значение [как в нашем примере], тогда разрешение определяется как одно.
Мы пытаемся:
resolution(df$x)
# [1] 1
Таким образом, ширина полосы по умолчанию в этом примере 0.9 * 1 = 0.9
Мы можем проверить это, посмотрев на данные ggplot
использует для рендеринга баров на графике, используя ggplot_build
, Мы создаем объект сюжета со сложенным барплотом с полосами ширины по умолчанию.
p2 <- p +
geom_bar(stat = "identity",
position = "stack")
Соответствующий слот в объекте $data
, который представляет собой список с одним элементом для каждого слоя на графике в том же порядке, в котором они отображаются в коде. В этом примере у нас есть только один слой, т.е. geom_bar
Итак, давайте посмотрим на первый слот:
ggplot_build(p2)$data[[1]]
# fill x y label PANEL group ymin ymax xmin xmax colour size linetype alpha
# 1 #F8766D 1 1 A 1 1 0 1 0.55 1.45 NA 0.5 1 NA
# 2 #00BFC4 1 2 B 1 2 1 2 0.55 1.45 NA 0.5 1 NA
Каждая строка содержит данные для "рисования" одного столбца. Как видите, ширина полосок всего 0,9 (xmax - xmin = 0.9
). Таким образом, ширина уложенных столбцов, которая будет использоваться в расчетах новых уклоненных позиций и ширин, равна 0.9
,
В предыдущем примере мы использовали ширину полосы по умолчанию вместе с шириной уклонения по умолчанию. Теперь давайте сделаем полосу чуть шире, чем ширина по умолчанию выше (0,9). Использовать width
аргумент в geom_bar
явно установить ширину (с накоплением) полосы, например, 1. Мы пытаемся использовать ту же ширину уклонения, что и выше (position_dodge(width = 0.9)
). Таким образом, хотя мы установили фактическую ширину полосы равной 1, расчеты уклонения выполняются так, как если бы полосы были шириной 0,9. Давай посмотрим что происходит:
p +
geom_bar(stat = "identity", width = 1, position = position_dodge(width = 0.9), alpha = 0.8)
p
Бары перекрываются, потому что ggplot смещает бары горизонтально, как если бы они имели (сложенную) ширину 0,9 (установлено в position_dodge
), хотя на самом деле столбцы имеют ширину 1 (устанавливается в geom_bar
).
Если мы используем значения уклонения по умолчанию, полосы точно смещаются по горизонтали в соответствии с заданной шириной полосы:
p +
geom_bar(stat = "identity", width = 1, position = "dodge", alpha = 0.8)
# or: position = position_dodge(width = NULL)
Далее мы пытаемся добавить текст к нашему сюжету, используя geom_text
, Начнем с уклонения по умолчанию width
(т.е. position_dodge(width = NULL)
), т.е. уклонение основано на размере элемента по умолчанию.
p <- ggplot(data = df, aes(x = x, y = y, fill = grp, label = grp)) + theme_minimal()
p2 <- p +
geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
geom_text(size = 10, position = position_dodge(width = NULL))
# or position = "dodge"
p2
# Warning message:
# Width not defined. Set with `position_dodge(width = ?)`
Уклонение от текста не удается. Как насчет предупреждающего сообщения? "Ширина не определена?". Слегка загадочный. Мы должны проконсультироваться с разделом Подробности ?geom_text
:
Обратите внимание, что "ширина" и "высота" текстового элемента равны 0, поэтому укладка и уклонение текста не будут работать по умолчанию, [...] Очевидно, что метки имеют высоту и ширину, но они являются физическими единицами, а не данными ед.
Таким образом, для geom_text
ширина отдельных элементов равна нулю. Это также первая "официальная ссылка на ggplot" на ваш второй вопрос: width
находится в единицах данных.
Давайте посмотрим на данные, используемые для визуализации текстовых элементов на графике:
ggplot_build(p3)$data[[2]]
# fill x y label PANEL group xmin xmax ymax colour size angle hjust vjust alpha family fontface lineheight
# 1 #F8766D 1 1 A 1 1 1 1 1 black 10 0 0.5 0.5 NA 1 1.2
# 2 #00BFC4 1 1 B 1 2 1 1 1 black 10 0 0.5 0.5 NA 1 1.2
В самом деле, xmin == xmax
; Таким образом, ширина текстового элемента в единицах данных равна нулю.
Как добиться правильного уклонения текстового элемента с нулевой шириной? Из примеров в ?geom_text
:
ggplot2 не знает, что вы хотите присвоить меткам ту же виртуальную ширину, что и столбцы [...]. Так и скажите:
Таким образом, для того, чтобы уклоняться от использования той же ширины для geom_text
элементы как для geom_bar
Для элементов, когда вычисляются новые позиции, нам нужно установить "ширину виртуального уклонения в единицах данных" текстового элемента равной ширине столбцов. Мы используем width
аргумент position_dodge
установить виртуальную ширину текстового элемента равной 0,9 (то есть ширину полосы в приведенном выше примере):
p2 <- p +
geom_bar(stat = "identity", position = position_dodge(width = NULL)) +
geom_text(position = position_dodge(width = 0.9), size = 10)
Проверьте данные, используемые для рендеринга geom_text
:
ggplot_build(p2)$data[[2]]
# fill x y label PANEL group xmin xmax ymax colour size angle hjust vjust alpha family fontface lineheight
# 1 #F8766D 0.775 1 A 1 1 0.55 1.00 1 black 10 0 0.5 0.5 NA 1 1.2
# 2 #00BFC4 1.225 1 B 1 2 1.00 1.45 1 black 10 0 0.5 0.5 NA 1 1.2
Теперь текстовые элементы имеют ширину в единицах данных: xmax - xmin = 0.9
т. е. той же ширины, что и стержни. Таким образом, вычисления уклонения теперь будут выполняться так, как если бы текстовые элементы имели определенную ширину, здесь 0,9. Визуализируйте сюжет:
p2
Текст уклонён правильно!
Аналогично тексту, ширина в единицах данных точек (geom_point
) и панели ошибок (например, geom_errorbar
) ноль. Таким образом, если вам нужно уклониться от таких элементов, вам нужно указать соответствующую виртуальную ширину, на которой будут основаны вычисления уклонения. Смотрите, например, раздел Пример ?geom_errorbar
:
Если вы хотите уклоняться от панелей и панелей ошибок, вам нужно вручную указать ширину уклонения [...]. Поскольку бары и панели ошибок имеют разную ширину, нам нужно указать, насколько широки объекты, от которых мы уклоняемся
Вот пример с несколькими значениями x в непрерывном масштабе:
df <- data.frame(x = rep(c(10, 20, 50), each = 2),
y = 1,
grp = c("A", "B"))
Допустим, мы хотим создать уклоненный барплот с текстом над каждым баром. Во-первых, просто проверьте барплот только с использованием ширины уклонения по умолчанию:
p <- ggplot(data = df, aes(x = x, y = y, fill = grp, label = grp)) + theme_minimal()
p +
geom_bar(stat = "identity", position = position_dodge(width = NULL))
# or position = "dodge"
Работает как положено. Затем добавьте текст. Мы пытаемся установить виртуальную ширину текстового элемента равной ширине столбцов в приведенном выше примере, т.е. мы "догадываемся", что столбцы по-прежнему имеют ширину 0,9, и что нам нужно увертывать текстовые элементы, как если бы они также имеют ширину 0,9:
p +
geom_bar(stat = "identity", position = "dodge") +
geom_text(position = position_dodge(width = 0.9), size = 10)
Очевидно, что расчет уклонения для столбцов теперь основан на ширине, отличной от 0,9, и установка виртуальной ширины на 0,9 для текстового элемента была неверной догадкой. Так что здесь ширина бара? Опять же, ширина полосы равна "[b]y default, установлено 90% разрешения данных". Проверьте разрешение:
resolution(df$x)
# [1] 10
Таким образом, ширина (сгруппированных по умолчанию) баров, на которой рассчитывается их новая, уклоненная позиция, теперь 0.9 * 10 = 9
, Таким образом, чтобы избежать штрихов и соответствующего им текста "рука об руку", нам нужно установить виртуальную ширину и текстовых элементов равной 9:
p +
geom_bar(stat = "identity", position = "dodge") +
geom_text(position = position_dodge(width = 9), size = 10)
В нашем последнем примере у нас есть категорическая ось x, просто "факторная версия" значений x сверху.
df <- data.frame(x = factor(rep(c(10, 20, 50), each = 2)),
y = 1,
grp = c("A", "B"))
В R факторы - это набор целочисленных кодов с атрибутом "уровни". И из ?resolution
:
Если x является целочисленным вектором, то предполагается, что он представляет дискретную переменную, а разрешение равно 1.
К настоящему времени мы знаем, что когда resolution
равен 1, ширина столбцов по умолчанию равна 0,9. Таким образом, по категориальной оси х ширина по умолчанию для geom_bar
0,9, и нам нужно установить уклонение width
за geom_text
соответственно:
ggplot(data = df, aes(x = x, y = y, fill = grp, label = grp)) +
theme_minimal() +
geom_bar(stat = "identity", position = "dodge") +
# or: position = position_dodge(width = NULL)
# or: position = position_dodge(width = 0.9)
geom_text(position = position_dodge(width = 0.9), size = 10)