Что делать и делать, когда делаете сюжет с помощью ggplot?
Каждый раз, когда я делаю сюжет с использованием ggplot, я немного провожу разные значения для hjust и vjust в строке типа
+ opts(axis.text.x = theme_text(hjust = 0.5))
чтобы метки осевой линии совпадали, где метки оси почти касаются оси, и находятся на одном уровне с ней (как бы оправдано, например, на оси). Однако я не совсем понимаю, что происходит. Часто hjust = 0.5
дает такие резко отличающиеся результаты от hjust = 0.6
, например, что я не смог понять это, просто играя с разными значениями.
Может ли кто-нибудь указать мне на подробное объяснение того, как работают функции hjust и vjust?
Ответы
Ответ 1
Значения hjust
и vjust
определены только между 0 и 1:
- 0 означает выравнивание по левому краю
- 1 означает правильное выравнивание
Источник: ggplot2, Хэдли Уикхем, стр. 196
(Да, я знаю, что в большинстве случаев вы можете использовать его за пределами этого диапазона, но не ожидайте, что он будет вести себя каким-то особым образом. Это вне спецификации.)
hjust
контролирует горизонтальное выравнивание и vjust
контролирует вертикальное выравнивание.
Пример должен прояснить это:
td <- expand.grid(
hjust=c(0, 0.5, 1),
vjust=c(0, 0.5, 1),
angle=c(0, 45, 90),
text="text"
)
ggplot(td, aes(x=hjust, y=vjust)) +
geom_point() +
geom_text(aes(label=text, angle=angle, hjust=hjust, vjust=vjust)) +
facet_grid(~angle) +
scale_x_continuous(breaks=c(0, 0.5, 1), expand=c(0, 0.2)) +
scale_y_continuous(breaks=c(0, 0.5, 1), expand=c(0, 0.2))
![enter image description here]()
Чтобы понять, что происходит при изменении hjust
в тексте оси, необходимо понимать, что горизонтальное выравнивание для текста оси определяется не по оси x, а по всему графику (где это включает текст по оси y)., (Это, на мой взгляд, неудачно. Было бы гораздо полезнее иметь выравнивание относительно оси.)
DF <- data.frame(x=LETTERS[1:3],y=1:3)
p <- ggplot(DF, aes(x,y)) + geom_point() +
ylab("Very long label for y") +
theme(axis.title.y=element_text(angle=0))
p1 <- p + theme(axis.title.x=element_text(hjust=0)) + xlab("X-axis at hjust=0")
p2 <- p + theme(axis.title.x=element_text(hjust=0.5)) + xlab("X-axis at hjust=0.5")
p3 <- p + theme(axis.title.x=element_text(hjust=1)) + xlab("X-axis at hjust=1")
library(ggExtra)
align.plots(p1, p2, p3)
![enter image description here]()
Чтобы узнать, что происходит с vjust
меток оси:
DF <- data.frame(x=c("a\na","b","cdefghijk","l"),y=1:4)
p <- ggplot(DF, aes(x,y)) + geom_point()
p1 <- p + theme(axis.text.x=element_text(vjust=0, colour="red")) +
xlab("X-axis labels aligned with vjust=0")
p2 <- p + theme(axis.text.x=element_text(vjust=0.5, colour="red")) +
xlab("X-axis labels aligned with vjust=0.5")
p3 <- p + theme(axis.text.x=element_text(vjust=1, colour="red")) +
xlab("X-axis labels aligned with vjust=1")
library(ggExtra)
align.plots(p1, p2, p3)
![enter image description here]()
Ответ 2
Вероятно, наиболее точным является рисунок B.1 (d) книги ggplot2, приложения к которой доступны по адресу http://ggplot2.org/book/appendices.pdf.
![enter image description here]()
Однако не все так просто. hjust
vjust
выше, как это работает в geom_text
и theme_text
(иногда). Один из способов думать об этом - думать о рамке вокруг текста и о том, где контрольная точка находится относительно этой рамки, в единицах относительно размера рамки (и, таким образом, отличается для текстов разного размера). hjust
0.5 и vjust
0.5 vjust
прямоугольник в контрольной точке. Уменьшение hjust
сдвигает окно вправо на величину ширины окна, умноженную на 0.5-hjust
. Таким образом, когда hjust=0
, левый край блока находится в контрольной точке. При увеличении значения hjust
перемещается влево на величину ширины окна, умноженную на hjust-0.5
. Когда hjust=1
, прямоугольник перемещается на половину ширины прямоугольника влево от центра, что помещает правый край в контрольную точку. Если hjust=2
, правый край блока - это ширина блока слева от контрольной точки (центр равен 2-0.5=1.5
ширины блока слева от контрольной точки. Для вертикали меньше - вверх, а больше - вниз. Это эффективно что говорит этот рисунок B.1 (d), но он экстраполирует за пределы [0,1].
Но иногда это не работает. Например
DF <- data.frame(x=c("a","b","cdefghijk","l"),y=1:4)
p <- ggplot(DF, aes(x,y)) + geom_point()
p + opts(axis.text.x=theme_text(vjust=0))
p + opts(axis.text.x=theme_text(vjust=1))
p + opts(axis.text.x=theme_text(vjust=2))
Три последних участка идентичны. Я не знаю, почему это так. Кроме того, если текст поворачивается, то это сложнее. Рассматривать
p + opts(axis.text.x=theme_text(hjust=0, angle=90))
p + opts(axis.text.x=theme_text(hjust=0.5 angle=90))
p + opts(axis.text.x=theme_text(hjust=1, angle=90))
p + opts(axis.text.x=theme_text(hjust=2, angle=90))
У первого метки выровнены по левому краю (против нижнего края), у второго центрированы в каком-то поле, поэтому их центры выровнены, а у третьего выровнены по правому краю (таким образом, их правые стороны выровнены рядом с осью) Последнее, ну, я не могу объяснить в связной форме. Это имеет отношение к размеру текста, размеру самого широкого текста, и я не уверен, что еще.