Что делать и делать, когда делаете сюжет с помощью 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))

У первого метки выровнены по левому краю (против нижнего края), у второго центрированы в каком-то поле, поэтому их центры выровнены, а у третьего выровнены по правому краю (таким образом, их правые стороны выровнены рядом с осью) Последнее, ну, я не могу объяснить в связной форме. Это имеет отношение к размеру текста, размеру самого широкого текста, и я не уверен, что еще.