Ответ 1
Как говорит Юлий, проблема в том, что hexGrob
не получает информацию о размерах бункера и угадывает ее из различий, которые она находит в фасете.
Очевидно, было бы целесообразно передать dx
и dy
в hexGrob
- не имея ширины и высоты шестиугольника, как указание круга по центру без предоставления радиуса.
Обход проблемы:
Стратегия resolution
работает, если фасет содержит два соседних хаксагона, которые различаются как по x, так и по y. Итак, в качестве обходного пути я создам вручную data.frame, содержащую координаты центра x и y ячеек, а также фактор фасетирования и подсчеты:
В дополнение к библиотекам, указанным в вопросе, мне понадобится
library (reshape2)
а также bindata$factor
на самом деле должен быть фактором:
bindata$factor <- as.factor (bindata$factor)
Теперь вычислим основную сечение шестиугольника
h <- hexbin (bindata, xbins = 5, IDs = TRUE,
xbnds = range (bindata$x),
ybnds = range (bindata$y))
Затем нам нужно вычислить числа, зависящие от bindata$factor
counts <- hexTapply (h, bindata$factor, table)
counts <- t (simplify2array (counts))
counts <- melt (counts)
colnames (counts) <- c ("ID", "factor", "counts")
Поскольку у нас есть идентификаторы ячеек, мы можем объединить этот data.frame с соответствующими координатами:
hexdf <- data.frame (hcell2xy (h), ID = [email protected])
hexdf <- merge (counts, hexdf)
Вот что выглядит data.frame:
> head (hexdf)
ID factor counts x y
1 3 e 0 -0.3681728 -1.914359
2 3 s 0 -0.3681728 -1.914359
3 3 y 0 -0.3681728 -1.914359
4 3 r 0 -0.3681728 -1.914359
5 3 p 0 -0.3681728 -1.914359
6 3 o 0 -0.3681728 -1.914359
ggplot
ting (используйте приведенную ниже команду), это дает правильные размеры бункера, но фигура имеет немного странный внешний вид: нарисованы 0 шестиугольников, но только там, где какая-либо другая грань имеет этот бункер. Чтобы отменить чертеж, мы можем установить счетчики на NA
и сделать na.value
полностью прозрачным (по умолчанию он равен grey50):
hexdf$counts [hexdf$counts == 0] <- NA
ggplot(hexdf, aes(x=x, y=y, fill = counts)) +
geom_hex(stat="identity") +
facet_wrap(~factor) +
coord_equal () +
scale_fill_continuous (low = "grey80", high = "#000040", na.value = "#00000000")
выводит фигуру в верхней части сообщения.
Эта стратегия работает до тех пор, пока ширина бинов не будет корректной без фасетов. Если ширина бинов установлена очень мала, значение resolution
может по-прежнему давать слишком большие значения dx
и dy
. В этом случае мы можем поставить hexGrob
двумя соседними ячейками (но отличающимися как x, так и y) с NA
подсчетами для каждой грани.
dummy <- hgridcent (xbins = 5,
xbnds = range (bindata$x),
ybnds = range (bindata$y),
shape = 1)
dummy <- data.frame (ID = 0,
factor = rep (levels (bindata$factor), each = 2),
counts = NA,
x = rep (dummy$x [1] + c (0, dummy$dx/2),
nlevels (bindata$factor)),
y = rep (dummy$y [1] + c (0, dummy$dy ),
nlevels (bindata$factor)))
Дополнительным преимуществом этого подхода является то, что мы можем удалить все строки с 0 отсчетами уже в counts
, в этом случае уменьшая размер hexdf
примерно на 3/4 (122 строки вместо 520):
counts <- counts [counts$counts > 0 ,]
hexdf <- data.frame (hcell2xy (h), ID = [email protected])
hexdf <- merge (counts, hexdf)
hexdf <- rbind (hexdf, dummy)
Сюжет выглядит точно так же, как и выше, но вы можете визуализировать разницу с na.value
не полностью прозрачным.
подробнее о проблеме
Проблема не уникальна для фасетирования, но встречается всегда, если слишком мало бункеров занято, так что никакие "диагональные" соседние ячейки не заполняются.
Здесь приведен ряд более минимальных данных, которые показывают проблему:
Во-первых, я трассирую hexBin
, поэтому получаю все центральные координаты одной и той же гексагональной сетки, что ggplot2:::hexBin
и объект, возвращаемый hexBin
:
trace (ggplot2:::hexBin, exit = quote ({trace.grid <<- as.data.frame (hgridcent (xbins = xbins, xbnds = xbnds, ybnds = ybnds, shape = ybins/xbins) [1:2]); trace.h <<- hb}))
Настройте очень маленький набор данных:
df <- data.frame (x = 3 : 1, y = 1 : 3)
И сюжет:
p <- ggplot(df, aes(x=x, y=y)) + geom_hex(binwidth=c(1, 1)) +
coord_fixed (xlim = c (0, 4), ylim = c (0,4))
p # needed for the tracing to occur
p + geom_point (data = trace.grid, size = 4) +
geom_point (data = df, col = "red") # data pts
str (trace.h)
Formal class 'hexbin' [package "hexbin"] with 16 slots
[email protected] cell : int [1:3] 3 5 7
[email protected] count : int [1:3] 1 1 1
[email protected] xcm : num [1:3] 3 2 1
[email protected] ycm : num [1:3] 1 2 3
[email protected] xbins : num 2
[email protected] shape : num 1
[email protected] xbnds : num [1:2] 1 3
[email protected] ybnds : num [1:2] 1 3
[email protected] dimen : num [1:2] 4 3
[email protected] n : int 3
[email protected] ncells: int 3
[email protected] call : language hexbin(x = x, y = y, xbins = xbins, shape = ybins/xbins, xbnds = xbnds, ybnds = ybnds)
[email protected] xlab : chr "x"
[email protected] ylab : chr "y"
[email protected] cID : NULL
[email protected] cAtt : int(0)
Я повторяю сюжет, оставляя точку данных 2:
p <- ggplot(df [-2,], aes(x=x, y=y)) + geom_hex(binwidth=c(1, 1)) + coord_fixed (xlim = c (0, 4), ylim = c (0,4))
p
p + geom_point (data = trace.grid, size = 4) + geom_point (data = df, col = "red")
str (trace.h)
Formal class 'hexbin' [package "hexbin"] with 16 slots
[email protected] cell : int [1:2] 3 7
[email protected] count : int [1:2] 1 1
[email protected] xcm : num [1:2] 3 1
[email protected] ycm : num [1:2] 1 3
[email protected] xbins : num 2
[email protected] shape : num 1
[email protected] xbnds : num [1:2] 1 3
[email protected] ybnds : num [1:2] 1 3
[email protected] dimen : num [1:2] 4 3
[email protected] n : int 2
[email protected] ncells: int 2
[email protected] call : language hexbin(x = x, y = y, xbins = xbins, shape = ybins/xbins, xbnds = xbnds, ybnds = ybnds)
[email protected] xlab : chr "x"
[email protected] ylab : chr "y"
[email protected] cID : NULL
[email protected] cAtt : int(0)
-
обратите внимание, что результаты из
hexBin
находятся в одной и той же сетке (номера ячеек не изменились, только ячейка 5 больше не заполнена и, следовательно, не указана), размеры и диапазоны сетки не изменились. Но графические шестиугольники действительно сильно изменились. -
Также обратите внимание, что
hgridcent
забывает возвращать центральные координаты первой ячейки (внизу слева).
Хотя он заселен:
df <- data.frame (x = 1 : 3, y = 1 : 3)
p <- ggplot(df, aes(x=x, y=y)) + geom_hex(binwidth=c(0.5, 0.8)) +
coord_fixed (xlim = c (0, 4), ylim = c (0,4))
p # needed for the tracing to occur
p + geom_point (data = trace.grid, size = 4) +
geom_point (data = df, col = "red") + # data pts
geom_point (data = as.data.frame (hcell2xy (trace.h)), shape = 1, size = 6)
Здесь рендеринг шестиугольников не может быть правильным - они не принадлежат к одной гексагональной сетке.