【问题标题】:Aligning title, subtitle and caption for horizontal ggplot barchart对齐水平ggplot条形图的标题,副标题和标题
【发布时间】:2016-12-12 16:57:37
【问题描述】:

我想在水平 ggplot2 条形图中左对齐 plot.titleplot.subtitleplot.caption

例子:

library("ggplot2") # ggplot2 2.2
df <- data.frame(type=factor(c("Brooklyn",
                               "Manhatten and\n Queens")),
                 value=c(15,30))

# manual hjust for title, subtitle & caption
myhjust <- -0.2

ggplot(df,
       aes(x=type, y=value)) +
  geom_bar(stat='identity') +
  coord_flip() +
  labs(
    title = "This is a nice title",
    subtitle = "A subtitle",
    caption  = "We even have a caption. A very long one indeed.") +
  theme(axis.title=element_blank(),
        plot.title=element_text(hjust = myhjust),
        plot.subtitle=element_text(hjust = myhjust ),
        plot.caption=element_text(hjust = myhjust))

如何将所有 3 个 labs 元素(plot.titleplot.subtitleplot.caption)与 axis.text 的开始位置(红色垂直线,Manhatten 的“M”)对齐?

另外:为什么固定的myhjust 会导致plot.titleplot.subtitleplot.caption 出现3 个不同的水平位置?

【问题讨论】:

  • 这是一个很好的问题,插图很好,解释也很清楚。这是我在使用 ggplot 时经常遇到的问题。虽然下面的 grid.arrange() 替代方案是可行的,但对我来说,这并不是这个问题的完整答案。例如,为什么相同的 hjust 值不会对标题、副标题和标题产生相同的影响?我认为答案是在每种情况下,参考点都是文本字符串的中间。虽然这对于居中对齐的文本是明智的,但它不适用于绘图区域之外的左对齐或右对齐。看起来这应该是一个简单的设置。

标签: r plot ggplot2


【解决方案1】:

这个问题是指这个 github 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) .

以您的榜样为代表:

# 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'

df <- data.frame(type=factor(c("Brooklyn","Manhatten and\n Queens")),
                 value=c(15,30))

ggplot(df, aes(x=type, y=value)) +
  geom_bar(stat='identity') +
  coord_flip() +
  labs(title = "This is a nice title",
       subtitle = "A subtitle",
       caption  = "We even have a caption. A very long one indeed.") +
  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 package (v0.3.0) 于 2019 年 9 月 4 日创建

【讨论】:

    【解决方案2】:

    虽然您可以编辑这三个 grobs,但您也可以:

    library(gridExtra)
    library(grid)
    
    grid.arrange(
      textGrob("This is a nice title", 
               gp=gpar(fontsize=16, col="#2b2b2b"), 
               x=unit(0.005, "npc"), just=c("left", "bottom")),
      textGrob("A subtitle",  
               gp=gpar(fontsize=12, col="#2b2b2b"), 
               x=unit(0.005, "npc"), just=c("left", "bottom")),
      ggplot(df, aes(x=type, y=value)) +
        geom_bar(stat='identity') +
        coord_flip() +
        theme(axis.title=element_blank()),
      textGrob("We even have a caption. A very long one indeed.", 
               gp=gpar(fontsize=9, col="#2b2b2b"), 
               x=unit(0.005, "npc"), just=c("left", "bottom")),
      ncol=1,
      heights=c(0.075, 0.025, 0.85, 0.05)
    )
    

    为它制作一个包装器,将其放入个人 pkg 中。繁荣。完成。


    library(ggplot2)
    library(gridExtra)
    library(grid)
    
    df <- data.frame(type=factor(c("Brooklyn","Manhatten and\n Queens")), value=c(15,30))
    
    ggplot(df, aes(x=type, y=value)) +
      geom_bar(stat='identity') +
      coord_flip() +
      theme(axis.title=element_blank()) +
      theme(plot.margin=margin(l=0, t=5, b=5))-> gg
    
    flush_plot <- function(x, title, subtitle, caption) {
      tg <- function(label, ...) {
        textGrob(label,  x=unit(0, "npc"), just=c("left", "bottom"),
                 gp=do.call(gpar, as.list(substitute(list(...)))[-1L])) }
      grid.arrange(
        tg(title, fontsize=16, col="#2b2b2b"),
        tg(subtitle, fontsize=12, col="#2b2b2b"), x,
        tg(caption, fontsize=9, col="#2b2b2b"),
        ncol=1, heights=c(0.075, 0.025, 0.85, 0.05)
      )
    }
    
    flush_plot(gg, "This is a nice title", "A subtitle", 
               "We even have a caption. A very long one indeed.")
    

    【讨论】:

    • 这似乎对齐了标题、副标题和标题,但不是 y 轴标签。
    • plot.margin = unit(c(0,0,0,0),"line") 会解决这个问题
    • @hrbrmstr 很好的答案!但老实说:我更喜欢纯 ggplot2 解决方案,尽管代码更少......如果有一个 /-:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 2011-01-26
    • 1970-01-01
    • 2014-05-27
    • 2021-02-18
    • 1970-01-01
    • 2014-02-05
    相关资源
    最近更新 更多