如何在使用表达式生成的ggplot2图中对齐标题和副标题

5

我正在使用以下代码在 ggplot2 中生成一个简单的箱线图:

# Libs data
data("mtcars"); require(ggplot2); require(ggthemes)
# Chart
ggplot(data = mtcars) +
  geom_boxplot(aes(y = wt, x = as.factor(am)),
               fill = "gray87") +
  xlab("AM") +
  ylab("WT") +
  theme_gdocs() +
  ggtitle("WT by AM") +
  theme(axis.title.y = element_text(angle = 90),
        axis.ticks = element_line(colour = "black", linetype = "solid",
                                  size = 0.5),
        panel.grid = element_line(colour = "gray"))

生成的图表非常简单: 第一个图表

任务

我想为我的图表添加副标题并对其呈现方式进行一些控制。我正在遵循此讨论并使用以下代码:

# Chart
ggplot(data = mtcars) +
  geom_boxplot(aes(y = wt, x = as.factor(am)),
               fill = "gray87") +
  xlab("AM") +
  ylab("WT") +
  theme_gdocs() +
  ggtitle(expression(atop("WT by AM", 
                          atop(italic("Some crucial note that has to be here"), "")))) +
  theme(axis.title.y = element_text(angle = 90),
        axis.ticks = element_line(colour = "black", linetype = "solid",
                                  size = 0.5),
        panel.grid = element_line(colour = "gray"))

我得到了以下的图表: second attempt
这看起来非常糟糕,我想改变一些东西:
  1. 副标题标题都左对齐
  2. 减少两行之间的空白
  3. 保持字体加粗

尝试

我尝试了不同的方法,例如下面的代码:

ggplot(data = mtcars) +
  geom_boxplot(aes(y = wt, x = as.factor(am)),
               fill = "gray87") +
  xlab("AM") +
  ylab("WT") +
  theme_gdocs() +
  ggtitle(expression(atop("WT by AM", 
                          atop(italic("Stupid note"), "")))) +
  theme(axis.title.y = element_text(angle = 90),
        axis.ticks = element_line(colour = "black", linetype = "solid",
                                  size = 0.5),
        panel.grid = element_line(colour = "gray"),
        plot.title = element_text(size = 16, colour = "black", hjust = -1))

但它完全隐藏了标题:

missing title


1
hjust 必须在 0 和 1 之间。另外,您需要斜体字吗?否则,您可以使用 ggtitle("WT by AM\n这里必须有一些关键说明") - Roland
@Roland 感谢您的关注。我知道我可以使用\n来换行,就像这里讨论的,但我更想驯服expression,以便我可以强制它表现出我想要的样子。我知道这可能有点琐碎。 - Konrad
1
我认为你不能将atop与左对齐结合使用。祝好运。 - Roland
@Roland 谢谢,我们会看看情况如何。我希望 expression 很灵活。最后,我不认为这是一个奇怪的请求。顺便说一下,我使用 hjust = 0.5 创建了一个漂亮的图表版本,并将标题放在中心位置。话虽如此,我更喜欢保持接近使用 theme_gdocs() 提供的样式,因为我很喜欢它。 - Konrad
你能更具体地说明一下“减少两行之间的空白”吗?你是指文本行(标题、副标题)吗?还是箱线图的线条(哪些线条)?另外,你是如何将表达式传递到atop中的?因为我只能让它传递文字字面量--例如,如果我放入atop(eval(foo)),它会在标题中直接放置“eval(foo)”。 - C8H10N4O2
显示剩余2条评论
3个回答

4

在Github上有一个新版本的ggplot2(2.1.0.9000+),可以解决你的问题。更多信息请参见Bob Rudis的小品文。

devtools::install_github("hadley/ggplot2")  # Until the new version is available on CRAN
library(ggplot2)
library(ggthemes)  # Only necessary because the OP used theme_gdocs()

ggplot(data = mtcars) +
  geom_boxplot(aes(y = wt, x = as.factor(am)), fill = "gray87") +
  xlab("AM") +
  ylab("WT") +
  theme_gdocs() +
  ggtitle("WT by AM", subtitle = "pearl of wisdom") +  # subtitle is a new argument. Both are now left-justified by default
  theme(plot.title=element_text(margin=margin(b=0), size = 20), plot.subtitle=element_text(margin=margin(t=5, b = 10)))  # Changing the size and margins of the title and subtitles to give the OP some options.

Title and Subtitle Image


非常感谢您对这个问题的关注。这是一个非常有用的建议。 - Konrad
1
那还在开发分支上吗? - ABCD

3

在“愚蠢但有效”的文件中,您可以在中心右侧添加空格以强制左对齐。正确数量的空格可以使用数学计算确定,但我无法看到如何将字符串变量传回atop

# Chart
ggplot(data = mtcars) +
  geom_boxplot(aes(y = wt, x = as.factor(am)), fill = "gray87") +
  xlab("AM") + ylab("WT") + theme_gdocs() +
  ggtitle(expression(atop("WT by AM                            ", 
                          atop(italic("Some crucial note that has to be here"), "")))) +
  theme(axis.title.y = element_text(angle = 90),
        axis.ticks = element_line(colour = "black", linetype = "solid", size = 0.5),
        panel.grid = element_line(colour = "gray"))

enter image description here


非常感谢您的关注和回答。这是一个不太光彩的技巧,但它确实有效。 - Konrad

1

它是否必须使用“expression”命令?我在ggplot2中进行了这项工作,但我想这也适用于ggplot,因为它们都使用plotmath。

您可以使用bquote和atop根据字符串差异的长度添加空格。您可以通过bquote的paste中的.()从环境中获取源。

bquote(atop(
       paste("WT by AM", .(paste0(replicate(nchar("Some Crucial Note that Has to Be Here") - nchar("WT by AM"), " "), collapse = ""), 
       paste("Some Crucial Note that Has to Be Here")
            ) 
       )

关于调整不同空间大小(由于字体大小而引起)的问题,我会在复制中对长度表达式乘以一个数字(如果得到分数,请使用floor或ceiling)。
编辑:但是,“”和“a”的字符在绘制时具有不同的长度,因此即使将空格数作为字符串长度差异也不完美。

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