始终将ggplot标题居中于PANEL而非PLOT

10
默认情况下,ggplot标题与plot.background元素左对齐。其他人指出,您可以使用plot.title = element_text(hjust = 0.5)来居中标题。 然而,我想要将标题居中到整个面板,而不仅仅是图表。我过去通过修改hjust的值来将标题居中,但是hjust的值取决于标题的长度,这使得批量生成图形时设置起来非常麻烦。
是否有可能始终将ggplot的标题元素设置为在panel.background上居中?
library(reprex)
library(tidyverse)
data(mtcars)

mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  labs(title="This title is left-aligned to the plot")

mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  labs(title="This title is center-aligned to the plot width.")+
  theme(plot.title = element_text(hjust = 0.5))

mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  labs(title="Short title, still works")+
  theme(plot.title = element_text(hjust = 0.5))

mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  labs(title="This title is roughly center-aligned to panel")+ 
  theme(plot.title = element_text(hjust = 0.37)) # I know I can adjust this, but it would require a manual fix each time

@user20650的建议

p <- mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  #labs(title="Short title, still works")+
  theme(plot.title = element_text(hjust = 0.5)) 

gridExtra::grid.arrange( top=grid::textGrob("This title is center-aligned to panel"),p  )

该内容由reprex软件包(版本为v0.2.1)于2018年9月24日创建


2
一种方法是将textGrob与图表标题rbind在一起。以下是使用grid.arrange的一种方法,它可以为您完成工作:gridExtra::grid.arrange( top=grid::textGrob("此标题大致居中对齐于面板"), p ) - user20650
@user20650,这看起来不错,我之前研究过Grid.arrange,但没有像这样的。如果我为副标题堆叠另一个textGrob,有没有参数可以让我摆脱填充?如果我使用你的gridExtra::grid.arrange(top=grid::textGrob("This title is roughly center-aligned to panel"), grid::textGrob("subtitle"), p ),textgrobs肯定在整个面板上居中,但是有很多垂直间距。有什么方法可以减少这个间距吗?理想情况下,我希望保持标题和副标题文本分开,以便我可以以不同的方式进行样式设置。 - grad_student
2
grid.arrange( top=grobTree(textGrob("这个标题"), textGrob("\n\n这个副标题", gp=gpar(cex=0.8))), p, padding=unit(2, "line")) :不确定在增加标题字体大小等方面会有多强的稳健性。 - user20650
1
@user20650,谢谢!目前来看,我想我会采纳你的建议。它实际上非常有效,因为所有图表的标题和副标题字体大小都是标准化的,所以一旦我找到了在副标题文本中放置正确数量的换行符,它就不需要更改了。我将使用你的代码更新我的问题。 - grad_student
能否将标题与条形图的左侧对齐? - MartineJ
显示剩余2条评论
3个回答

6
现在主题有一个选项可以调用plot.title.position来将绘图标题居中于整个绘图区域,而不仅仅是绘图面板上方。如果在theme()中设置plot.title.position = "plot",它将把标题和副标题居中到整个绘图区域,而不仅仅是在面板上方。
library(reprex)
library(tidyverse)
data(mtcars)

mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  labs(title="This title is center-aligned to the plot width.")+
  theme(plot.title = element_text(hjust = 0.5),
        plot.title.position = "plot")

This title is center-aligned to the plot width.


3

一种方法是改变标题 grob 的位置,使其从左边开始:

p <- mtcars %>% 
  rownames_to_column(var = "model") %>% 
  top_n(8,wt) %>% 
  ggplot(aes(x =model, y = wt))+
  geom_col()+
  coord_flip()+
  labs(title="This title is left-aligned to the plot") +
  theme(plot.title = element_text(hjust = 0.5))

library(gridExtra)
g <- ggplotGrob(p)
g$layout$l[g$layout$name == "title"] <- 1
grid::grid.draw(g)

enter image description here


我喜欢这个解决方案,因为它允许我继续使用实验参数,但我担心保存为png格式?创建图形后,我的工作流程是使用ggsave保存为png。似乎使用ggplotGrob不是ggsave接受的对象之一? - grad_student
ggsave("test.png") 对我来说很有效,因为它默认保存最后一个显示的图。或者根据这里的讨论 https://dev59.com/u2Qn5IYBdhLWcg3wJ0UO,也可以使用 ggsave("test.png", arrangeGrob(g)) - Weihuang Wong

0
另一个选择是使用patchwork库及其plot_annotation,这样你就会有:
mtcars %>% 
     rownames_to_column(var = "model") %>% 
     top_n(8,wt) %>% 
     ggplot(aes(x =model, y = wt))+
     geom_col()+
     coord_flip()+
     patchwork::plot_annotation(title="This title is very long and centered on the whole plot", 
          theme = theme(plot.title = element_text(hjust = 0.5)))

enter image description here


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