在ggplot2中左对齐标题,或为ggtitle设置绝对位置

48

我想要像这样的图中左对齐标题

ggplot(data = economics, aes(x = date, y = unemploy)) +
 geom_line() +
 ggtitle("Unemployment in USA between 1967 and 2007") +
 xlab("") +
 ylab("Unemployed [thousands]")

ggplot2基础图示

第一次尝试

ggplot(data = economics, aes(x = date, y = unemploy)) + geom_line() +
 ggtitle("Unemployment in USA for some years") +
 xlab("") +
 ylab("Unemployed [thousands]") +
 theme(plot.title = element_text(hjust = -0.45, vjust=2.12)))

在此输入图片描述

太棒了,成功了!但是等等……还有更多的事情……现在我想把标题改成别的什么。

ggplot(data = economics, aes(x = date, y = unemploy)) +
 geom_line() +
 ggtitle("Unemployment in USA between 1967 and 2007") +
 xlab("") +
 ylab("Unemployed [thousands]") +
 theme(plot.title = element_text(hjust = -0.45, vjust=2.12))

新标题

现在我需要调整 hjust... :(

问题

如何使标题左对齐(大约比 y 轴标签左侧多几个像素),并且可以一次又一次地重复此操作,而不会影响 hjust 的值?或者说 hjust 和字符串长度之间的关系是什么?

我已经尝试根据 这个问题 手动注释,但由于某种原因只得到了标题而没有别的内容-还出现了一个错误。

谢谢!


可能是如何在ggplot2中调整标题位置的问题的重复。 - user3710546
1
@user3710546 - 这两个问题不是重复的 - 这个问题是关于左边框的 - 另一个问题只是想要左对齐。 - MatthewR
6个回答

64
这个问题参考了 tidyverse/ggplot2 的已解决问题: https://github.com/tidyverse/ggplot2/issues/3252 并且在 ggplot2 (开发版本) 中实现了:https://github.com/tidyverse/ggplot2/blob/15263f7580d6b5100989f7c1da5d2f5255e480f9/NEWS.md 主题增加了两个新参数,plot.title.position 和 plot.caption.position,可用于自定义图表标题/副标题和图表说明相对于整体图表的位置(@clauswilke,#3252)。
为了遵循您的示例作为reprex:
# First install the development version from GitHub:
#install.packages("devtools") #If required
#devtools::install_github("tidyverse/ggplot2")

library(ggplot2)
packageVersion("ggplot2")
#> [1] '3.2.1.9000'

ggplot(data = economics, aes(x = date, y = unemploy)) + 
  geom_line() +
  labs(x=NULL,
       y="Unemployed [thousands]",
       title = "Unemployment in USA for some years",
       subtitle = "A subtitle possibly",
       caption  = "NOTE: Maybe a caption too in italics.") +
  theme(plot.caption = element_text(hjust = 0, face= "italic"), #Default is hjust=1
        plot.title.position = "plot", #NEW parameter. Apply for subtitle too.
        plot.caption.position =  "plot") #NEW parameter

这是由reprex包(v0.3.0)于2019年09月04日创建的


33

除非有人提出更好的解决方案,否则一种方法可能是类似于...

library(ggplot2)
library(grid)
library(gridExtra)
p <- ggplot(data = economics, aes(x = date, y = unemploy)) +
    geom_line() +
    labs(x = NULL, y = "Unemployed [thousands]", title = NULL)

title.grob <- textGrob(
    label = "Unemployment in USA for some years",
    x = unit(0, "lines"), 
    y = unit(0, "lines"),
    hjust = 0, vjust = 0,
    gp = gpar(fontsize = 16))

p1 <- arrangeGrob(p, top = title.grob)
grid.draw(p1)

输入图片描述


1
谢谢!非常好!如果你没有说“直到有人提出更好的解决方案”,我可能会立刻接受这个。 :) 谢谢你的快速回复! - bytesinflight
@konvas 如何将标题移到绘图区域的右上角? “hjust” 可以使用,但是“vjust” 对我无效。 欢迎提供建议!谢谢。 - Meli
你认为这个方案更好吗?链接 - Claus Wilke
@ClausWilke 怎么做呢?这个想法和 IMO 没必要的新名称("ggdraw","draw_text")完全相同。此外,在一个不可见的 ggplot2 中包装整个东西只为添加一个注释在这种情况下似乎过度和低效。 - baptiste
@babtiste 略过这种方法是否好的问题,我想为“draw_*”函数提供一种辩护。它们是“geom_*”的包装器,(i)不需要数据框作为输入;(ii)不进行美学映射;(iii)不继承美学映射。它们非常适合快速的一次性注释。你可以用geoms做同样的事情,但通常需要至少两倍的代码量。 - Claus Wilke
至于ggdraw,我发现它非常有用,因为它可以在跨越整个绘图区域的全局坐标系上放置注释。这在基本R中很容易实现,但在ggplot2中无法实现。你可以使用grid来实现这一点,但我喜欢在这个全局坐标系中使用所有ggplot2功能的便利性。 - Claus Wilke

15
自从ggplot 3.3.0发布以来,您还可以使用plot.title.position = "plot"来定位标题和plot.caption.position = "plot副标题在完整图的左侧。
ggplot(data = economics, aes(x = date, y = unemploy)) +
    geom_line() +
    ggtitle("Unemployment in USA between 1967 and 2007") +
    xlab("") +
    ylab("Unemployed [thousands]") +
    theme(plot.title.position = "plot")

输入图像描述


https://www.tidyverse.org/blog/2020/03/ggplot2-3-3-0/#grab-bag - writer_typer

14

您可以手动调整ggplot输出的布局。首先,我们设置基本图:

library(ggplot2)
p <- ggplot(data = economics, aes(x = date, y = unemploy)) +
 geom_line() +
 labs(title = "Unemployment in USA between 1967 and 2007", 
      x = NULL, y = "Unemployed [thousands]")

我们现在可以将ggplot对象转换为gtable对象,并检查绘图中元素的布局。请注意,title位于网格的第四列,与主面板相同的列。
g <- ggplotGrob(p)
g$layout
#    t l  b r  z clip       name
# 17 1 1 10 7  0   on background
# 1  5 3  5 3  5  off     spacer
# 2  6 3  6 3  7  off     axis-l
# 3  7 3  7 3  3  off     spacer
# 4  5 4  5 4  6  off     axis-t
# 5  6 4  6 4  1   on      panel
# 6  7 4  7 4  9  off     axis-b
# 7  5 5  5 5  4  off     spacer
# 8  6 5  6 5  8  off     axis-r
# 9  7 5  7 5  2  off     spacer
# 10 4 4  4 4 10  off     xlab-t
# 11 8 4  8 4 11  off     xlab-b
# 12 6 2  6 2 12  off     ylab-l
# 13 6 6  6 6 13  off     ylab-r
# 14 3 4  3 4 14  off   subtitle
# 15 2 4  2 4 15  off      title
# 16 9 4  9 4 16  off    caption

为了使标题与图表的左边缘对齐,我们可以将 l 的值改为 1。
g$layout$l[g$layout$name == "title"] <- 1

绘制修改后的网格:

grid::grid.draw(g)

结果: 在此输入图片描述

这是一个非常好的解决方案。我如何将其放入我的每个图形绘制例程中? - canIchangethis
如何保存这个新的“last”和正确的图表?@Weihuang Wong - canIchangethis
@canIchangethis 请参考 https://dev59.com/vF0b5IYBdhLWcg3wA9Eb。 - Weihuang Wong
谢谢,我在评论后自己解决了问题,但忘记删除了!无论如何,感谢您指出正确的位置! - canIchangethis

8
我在cowplot中编写了ggdraw()图层,特别是为了能够轻松地在绘图的任何位置进行注释。它设置了一个坐标系,覆盖整个绘图区域,而不仅仅是绘图面板,并且在x和y方向上从0到1运行。使用这种方法,您可以轻松地将标题放置在任何想要的位置。
library(cowplot)
theme_set(theme_gray()) # revert to ggplot2 default theme

p <- ggplot(data = economics, aes(x = date, y = unemploy)) +
  geom_line() +
  ggtitle("") + # make space for title on the plot
  xlab("") +
  ylab("Unemployed [thousands]")

ggdraw(p) + draw_text("Unemployment in USA between 1967 and 2007", 
                      x = 0.01, y = 0.98, hjust = 0, vjust = 1,
                      size = 12)  # default font size is 14, 
                                  # which is too big for theme_gray()

enter image description here


非常高兴能够使用cowplot来解决这个问题!! ;) - Seymour
1
尽管它只在R studio的Plots部分起作用。如果我试图“放大”它或保存它,绘图就会失去它们的对齐。为什么? - Seymour

5
另一种方法是利用theme()。 使用labs函数标记所有标题,x =表示x轴,y =表示y轴,title =表示图表标题,fill =colour =如果您有想要添加标题的图例。 在theme()内部是hjust = 0,这将使图表标题左对齐。 您可以删除hjust = 0,然后图表标题将居中对齐。
labs(x = 'Sex', y = 'Age Mean', title = 'Suicide 2003-2013 Age Mean by Sex') +
  theme(plot.title = element_text(family = 'Helvetica', 
                              color = '#666666', 
                              face = 'bold', 
                              size = 18, 
                              hjust = 0))

9
他正在尝试与左边框对齐,而不是左边轴线。 - MatthewR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接