ggplot2 определяет позицию geom_text с помощью обычных "top", "bottom", "left", "right", "center"
Я делаю некоторые графики в ggplot и не могу понять, как изобразить в графике текст без указания x и y позиций.
Допустим, я делаю график, как это.
sp <- ggplot(mpg, aes(hwy, cty, label = "sometext"))+
geom_point()
Я хочу добавить ярлык, который будет напечатан одинаково на каждом графике. Вызов следующего просто печатает текст при каждом значении x, y aes
,
sp + geom_text()
Я мог бы манипулировать данными XY, предоставленными geom_text()
чтобы текст оставался в одном и том же относительном положении между графиками, но разве не существует простого способа вызвать положение по умолчанию в таких позициях, как "верх", "низ" и т. д.? Т.е. sp + geom_text(position="top")
,
4 ответа
geom_text
хочет построить метки на основе вашего набора данных. Похоже, вы хотите добавить один фрагмент текста на ваш сюжет, в этом случае, annotate
это лучший вариант. Чтобы заставить метку появляться в одной и той же позиции независимо от единиц на графике, вы можете воспользоваться Inf
ценности:
sp <- ggplot(mpg, aes(hwy, cty, label = "sometext"))+
geom_point() +
annotate(geom = 'text', label = 'sometext', x = -Inf, y = Inf, hjust = 0, vjust = 1)
print(sp)
Я избегаю annotate
как чума и просто использовать пустой фрейм данных data
аргумент в пользу geom_text
:
ggplot(mpg, aes(hwy, cty, label = "sometext"))+
geom_point() +
geom_text(data=data.frame(), aes(label = 'sometext', x = -Inf, y = Inf),
hjust = 0, vjust = 1)
В ggpmisc::geom_text_npc
то x
а также y
позиции даны в единицах npc (0-1). Однако позиции также могут быть указаны как "слова":
d = data.frame(x = rep(c("left", "center", "right"), each = 3),
y = rep(c("bottom", "middle", "top"), 3))
d$lab = with(d, paste0(x, "-", y))
d
# x y lab
# 1 left bottom left-bottom
# 2 left middle left-middle
# 3 left top left-top
# 4 center bottom center-bottom
# 5 center middle center-middle
# 6 center top center-top
# 7 right bottom right-bottom
# 8 right middle right-middle
# 9 right top right-top
ggplot(d) +
geom_text_npc(aes(npcx = x.chr, npcy = y.chr, label = lab))
Конечно, можно написать обертку, но способ определения единиц и обоснования делает его довольно многословным,
library(ggplot2)
qplot(1,1) +
annotation_compass('testN') +
annotation_compass('testE','E') +
annotation_compass('testSW','SW') +
annotation_compass('testW','W')
annotation_compass <- function(label,
position = c('N','NE','E','SE','S','SW','W','NW'),
padding = grid::unit(c(0.5,0.5),"line"), ...){
position <- match.arg(position)
x <- switch (position,
N = 0.5,
NE = 1,
E = 1,
SE = 1,
S = 0.5,
SW = 0,
W = 0,
NW = 0
)
y <- switch (position,
N = 1,
NE = 1,
E = 0.5,
SE = 0,
S = 0,
SW = 0,
W = 0.5,
NW = 1
)
hjust <- switch (position,
N = 0.5,
NE = 1,
E = 1,
SE = 1,
S = 0.5,
SW = 0,
W = 0,
NW = 0
)
vjust <- switch (position,
N = 1,
NE = 1,
E = 0.5,
SE = 0,
S = 0,
SW = 0,
W = 0.5,
NW = 1
)
f1 <- switch (position,
N = 0,
NE = -1,
E = -1,
SE = -1,
S = 0,
SW = 1,
W = 1,
NW = 1
)
f2 <- switch (position,
N = -1,
NE = -1,
E = 0,
SE = 1,
S = 1,
SW = 1,
W = 0,
NW = -1
)
annotation_custom(grid::textGrob(label,
x=grid::unit(x,"npc") + f1*padding[1] ,
y=grid::unit(y,"npc") + f2*padding[2],
hjust=hjust,vjust=vjust, ...))
}
Решение с использованием бесконечности хорошо и, безусловно, самый простой вариант.
Однако, если вам нужен больший контроль над положением ваших надписей (например, если вы хотите, чтобы они были отцентрированы, или если вы хотите больше места между линией оси и аннотацией), вы можете использовать некоторую математику с min()
а также max()
заголовков вашего сюжета для создания заголовков по центру сверху, снизу, справа или слева. Приведенный ниже код немного длинен, но все равно будет правильно размещать метки, если значения в вашем графике изменятся. Кроме того, для копирования на другие графики вам не нужно вручную вычислять значения, просто измените имена переменных x и y.
sp <- ggplot(mpg, aes(hwy, cty)) +
geom_point() +
theme_classic() +
annotate("text", label = "top",
x = 0.5*(min(mpg$hwy) + max(mpg$hwy)), y = max(mpg$cty), vjust = 1) +
annotate("text", label = "bottom",
x = 0.5*(min(mpg$hwy) + max(mpg$hwy)), y = min(mpg$cty), vjust = 0) +
annotate("text", label = "right",
x = max(mpg$hwy), y = 0.5*(min(mpg$cty) + max(mpg$cty)), hjust = 1) +
annotate("text", label = "left",
x = min(mpg$hwy), y = 0.5*(min(mpg$cty) + max(mpg$cty)), hjust = 0)
sp