每次我使用ggplot绘制图形时,我都会花一点时间尝试hjust和vjust在一行中的不同值

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

为了让轴标签在轴标签几乎接触轴的地方对齐,并且与它齐平(也就是说,与轴对齐)。然而,我真的不明白发生了什么。通常情况下,hjust = 0.5与hjust = 0.6给出的结果有很大的不同,例如,我无法通过摆弄不同的值来计算出它。

谁能给我一个关于hjust和vjust选项如何工作的全面解释?


可能最确定的是ggplot2书中的图B.1(d),其附录可在http://ggplot2.org/book/appendices.pdf上获得。

However, it is not quite that simple. hjust and vjust as described there are how it works in geom_text and theme_text (sometimes). One way to think of it is to think of a box around the text, and where the reference point is in relation to that box, in units relative to the size of the box (and thus different for texts of different size). An hjust of 0.5 and a vjust of 0.5 center the box on the reference point. Reducing hjust moves the box right by an amount of the box width times 0.5-hjust. Thus when hjust=0, the left edge of the box is at the reference point. Increasing hjust moves the box left by an amount of the box width times hjust-0.5. When hjust=1, the box is moved half a box width left from centered, which puts the right edge on the reference point. If hjust=2, the right edge of the box is a box width left of the reference point (center is 2-0.5=1.5 box widths left of the reference point. For vertical, less is up and more is down. This is effectively what that Figure B.1(d) says, but it extrapolates beyond [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))

第一个标签左对齐(相对于底部),第二个标签在某个方框中居中,因此它们的中心对齐,第三个标签右对齐(因此它们的右侧对齐于轴旁边)。最后一个,我无法用连贯的方式解释。它与文本的大小有关,最宽的文本的大小,我不确定还有什么。


hjust和vjust的值只在0到1之间定义:

0表示左对齐 1表示右对齐

资料来源:Hadley Wickham, 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)