Фон
Прочитав этот красивый ответ о том, как расширить ggplot и соответствующая виньетка Я пытался понять, как расширить ggplot
.
Кратко
Я понимаю, как собираются части, но мне не хватает важной информации: как ggplot
определяет диапазон по умолчанию для оси?
Код
Рассмотрим следующий пример с игрушкой:
library(grid)
library(ggplot2)
GeomFit <- ggproto("GeomFit", GeomBar,
required_aes = c("x", "y"),
setup_data = .subset2(GeomBar, "setup_data"),
draw_panel = function(self, data, panel_scales, coord, width = NULL) {
bars <- ggproto_parent(GeomBar, self)$draw_panel(data,
panel_scales,
coord)
coords <- coord$transform(data, panel_scales)
tg <- textGrob("test", coords$x, coords$y * 2 - coords$ymin)
grobTree(bars, tg)
}
)
geom_fit <- function(mapping = NULL, data = NULL,
stat = "count", position = "stack",
...,
width = NULL,
binwidth = NULL,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomFit,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
width = width,
na.rm = na.rm,
...
)
)
}
set.seed(1234567)
data_gd <- data.frame(x = letters[1:5],
y = 1:5)
p <- ggplot(data = data_gd, aes(x = x, y = y, fill = x)) +
geom_fit(stat = "identity")
Проблема
Как видите, часть текста не отображается. Я предполагаю, что ggplot
каким-то образом вычисляет диапазоны для оси, и поскольку он не знает о дополнительном пространстве, необходимом для моего textGrob
. Как я могу это решить? (Желаемый результат эквивалентен p + expand_limits(y = 10)
Примечание. Конечно, я мог бы довести проблему до конечного пользователя, потребовав добавить ручную шкалу. Но в идеале хотелось бы, чтобы весы были правильно настроены.
ggplot
расширяет диапазон данных мультипликативно и аддитивно. Множители и коэффициенты добавления могут быть установлены пользователем в аргументеexpand
функцииscale
. см. пример здесь. Это часто происходит, когда люди хотят, чтобы график вообще не расширялся. В последних версиях вы можете использоватьexpand_scale
для расширения оси только в одном направлении.?expand_scale
— хорошее место для начала. - person Gregor Thomas   schedule 01.04.2019layer_data(p)
, значения y находятся в диапазоне от 1 до 5, так что это диапазон масштаба графика. - person Z.Lin   schedule 01.04.2019ggplot
узнает, в каком диапазоне он должен искать? С одними и теми же данными я могу получить совершенно разные диапазоны на основе моего сопоставления:d <- data.frame(x = rep(1:10, 10), y = sample(3, 100, TRUE))
:p <- ggplot(d, aes(x = x)); p + geom_bar()
противp + geom_bar(aes(y=y), stat = "identity")
. Поэтому только после того, как мы узнаем, какие отображения мы используем вgeom
, мы можем определить диапазон для графика. -> 1. какая функция отвечает за определение дальности? 2. из какой функции вызывается его функция? - person thothal   schedule 02.04.2019train_position
из Layout. Один трюк, который мне нравится использовать при копании объектов ggplot, заключается в запуске отладки наggplot2:::ggplot_build.ggplot
илиggplot2:::ggplot_gtable.ggplot_built
(два этапаggplotGrob()
) и проверке вывода на каждом этапе, чтобы найти, где происходит интересующее явление (в данном случае создание масштаба). Но будьте осторожны, кроличья нора может быть очень, очень глубокой... - person Z.Lin   schedule 02.04.2019debug
для некоторых внутренних функций в разныхGeom*
. Я думаю, что нашел уродливое обходное решение, которое я опубликую для дальнейшего использования. - person thothal   schedule 02.04.2019