Що роблять hjust та vjust при створенні сюжету за допомогою ggplot?


159

Кожен раз, коли я створюю сюжет за допомогою ggplot, я витрачаю трохи, пробуючи різні значення для hjust та vjust у такій лінії, як

+ opts(axis.text.x = theme_text(hjust = 0.5))

щоб змусити мітки осі вирівнюватися там, де мітки осі майже торкаються осі, і наближаються до неї (виправдано до осі, так би мовити). Однак я не дуже розумію, що відбувається. Часто hjust = 0.5дає такі різко різні результати hjust = 0.6, наприклад, як, наприклад, я не зміг це зрозуміти, просто граючи з різними значеннями.

Чи може хтось вказати мені на всебічне пояснення того, як працюють варіанти hjust та vjust?


1
Я наводив конкретний приклад у коментарях до першої відповіді. Мабуть, використання цифр поза 0-1 є невизначеним, що, якщо не пояснює, чому hjust = -1 має химерну поведінку, принаймні пояснює, що химерного слід очікувати.
Вільям Ганн

Відповіді:


277

Значення 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))

введіть тут опис зображення


Щоб зрозуміти, що відбувається при зміні 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)

введіть тут опис зображення


Щоб дізнатися, що відбувається з 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)

введіть тут опис зображення


1
Отже, у випадку кута = 45, коли у мене є мітки осі різної довжини, скажімо, від 25 до 5 символів, вони не вирівнюються ні вправо, ні вліво від меж слова. Погляньте на осі тут. Якби я застосував кут = 45, як би я зробив їх правильно виправданими та нахилом до осі?
Вільям Ганн

Я спробував це, і я отримую Error in grid.Call("L_textBounds", as.graphicsAnnot(x$label), x$x, x$y, : Polygon edge not found (zero-width or zero-height?)для vjust = .72і вище.
Вільям Ганн

1
@WilliamGunn Я пропоную вам поставити нове запитання зі своїм кодом.
Андрі

1
оскільки опція застаріла, як ми регулюємо положення заголовка осі?
Сайрус Мухаммедіан

1
@CyrusMohammadian, я відредагував цю відповідь, щоб працювати з поточним синтаксисом ggplot2.
Краплі

16

Напевно, найбільш остаточним є рисунок B.1 (d) книги ggplot2, додатки до якого доступні на веб- сторінці http://ggplot2.org/book/appendices.pdf .

введіть тут опис зображення

Однак це не зовсім так просто. hjustі vjustяк описано, як це працює в ( geom_textі theme_textіноді). Один із способів думати про це - думати про поле навколо тексту та там, де опорна точка знаходиться відносно цього поля, в одиницях відносно розміру поля (і, таким чином, відрізняється для текстів різної величини). hjust0,5 і vjust0,5 центру коробки на опорній точці. Зменшення 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))

Перший має мітки зліва виправданими (проти низу), другий розміщений у певній коробці, щоб їх центри були вирівняні, а третій - право виправданий (тому їх права сторона вирівнюється поруч із віссю). Останній, ну, я не можу пояснити узгоджено. Це має щось спільне з розміром тексту, розміром самого широкого тексту, і я не впевнений, що ще.


Дякую за це, це допомагає у випадку, коли кут = 90, але те, чого я не отримую, - це те, чому правильне обгрунтування міток більше не працює, коли замість кута = 90 я використовую кут = 45. Я розумію поведінку кута = 45, hjust = 0, але кут = 45, hjust = -1 просто химерний.
Вільям Ганн

Ваш перший приклад насправді працює. Ви вважаєте, що це не працює, тому що всі ваші етикетки мають однакову висоту. Спробуйте ще раз DF <- data.frame(x=c("a\na","b","cdefghijk","l"),y=1:4)- тобто з \nрядком рядка в одному з назв.
Андрі

@William, я думаю, @Andrie має це правильно; hjustі vjustвизначаються лише між 0 і 1; поведінка поза цим діапазоном не потребує сенсу.
Брайан Діггс

@Andrie, ти маєш рацію. Але мені все ще важко скласти цілісну ментальну модель у випадку осі / тексту осі. Для тексту осі hjust=0вирівнюємо лівий край тиком; hjust=0.5центри на тик; hjust=1вирівняє правий край тиком (рухоме поле відносно опорної точки). Але vjustвирівнюється всередині коробки розмір найвищої мітки.
Брайан Діггс

@BrianDiggs У разі vjustміток осі всі мітки одночасно вирівнюються між собою. Отже, всі верхні краї вирівнюються коли, vjust=1а також всі нижні краї, коли vjust=0. Це має для мене ідеальний сенс.
Андрі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.