【问题标题】:ggplot2: margins for annotations outside of plotggplot2:绘图外注释的边距
【发布时间】:2018-03-02 12:50:15
【问题描述】:

我遇到了与这个问题几乎完全相同的问题:Multi-row x-axis labels in ggplot line chart。接受的答案在大多数情况下对我有用,但根据我的情节大小,注释有时会从我的情节中消失。

我尝试过处理相对于 y 比例的绘图和图例边距,但它并没有像我希望的那样工作。这是我到目前为止所得到的:

library(magrittr)
library(ggplot2)

test <- structure(list(
    area = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,
                       2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L),
                     .Label = c("A", "B", "C"),
                     class = "factor"),
    Year = c(2015L, 2015L, 2015L, 2015L, 2016L, 2016L, 2016L, 2016L, 2017L,
             2017L, 2017L, 2015L, 2015L, 2015L, 2015L, 2016L, 2016L, 2016L,
             2016L, 2017L, 2017L, 2017L),
    Quarter = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L,
                2L, 3L, 4L, 1L, 2L, 3L),
    rate = c(0.52, 0.35, 0.23, 0.36, 0.21, 0.17, 0.33, 0.26, 0.3, 0.31, 0.24,
             0.24, 0.29, 0.42, 0.15, 0.36, 0.33, 0.41, 0.27, 0.34, 0.33, 0.25)),
    class = c("tbl_df", "tbl", "data.frame"),
    row.names = c(NA, -22L),
    .Names = c("area", "Year", "Quarter", "rate"))

yMax <- max(test$rate) * 1.1
yMin <- yMax/7

fig2 <- (ggplot(test,
                mapping = aes(x = interaction(Year, Quarter, lex.order = TRUE),
                              y = rate, group = area, color = area)) +
             geom_line() +
             coord_cartesian(ylim = c(0, yMax), expand = TRUE) +
             scale_x_discrete(labels = paste0("Q", rep(1:4, 3))) +
             scale_y_continuous(name = "Rate", expand = c(0,0)) +
             annotate(geom = "text", label = unique(test$Year),
                      x = 2.5 + 4 * (0:2),
                      y = -yMin,
                      size = 5, vjust = 0) +
             annotate(geom = "segment",
                      x = c(4.5, 8.5), xend = c(4.5, 8.5),
                      y = 0, yend = -yMin * 1.1) +
             theme(plot.margin = margin(b = yMin/2, unit = "native"),
                   axis.title.x = element_blank(),
                   panel.background = element_blank(),
                   axis.line = element_line(),
                   legend.position = "bottom",
                   legend.margin = margin(t = 30, unit = "native"),
                   legend.background = element_rect(fill = alpha("red", 0.5)))
) %>%
    ggplotGrob() %>% 
    (function(x) {
        x$layout$clip[x$layout$name == "panel"] <- "off"
        return(x)
    }); grid::grid.draw(fig2)

在一个尺寸下,情节看起来不错,但如果我增加情节的高度,岁月就会开始与传说发生冲突,如果我把它做得更高,它们就会从底部消失。

我很困惑为什么图例边距不随着情节的大小而缩放,因为如果是这样,我认为这会解决我的问题。另外,我很困惑为什么 30 个原生单位的图例边距与约 0.04 个原生单位的地块边距大小差不多?

情节按照我的意愿布置(红色传奇背景只是为了让我可以看到发生了什么):

更高的情节开始出现问题:

【问题讨论】:

  • 您愿意将您的图例移到顶部吗?
  • @Djork 我宁愿不这样做,但无论如何我看不出这会如何影响年份注释如果它非常高的话会从情节底部掉下来?我想要一个无需考虑this 发生的解决方案。
  • 只是因为如果我将图例移到顶部,输出看起来最一致。是 native 单位给我造成了问题。
  • @Djork 哦,你是对的,移动图例确实可以缓解这个问题。但它似乎仍然不太正确,底部边距在像素或 y 轴单位中仍然不一致......

标签: r ggplot2


【解决方案1】:

@Oliver 将plot.margin 单位更改为linesincm 对我有用,问题在于native 单位的缩放。这个解决方案对你有用吗?

fig2 <- (ggplot(test,
                mapping = aes(x = interaction(Year, Quarter, lex.order = TRUE),
                              y = rate, group = area, color = area)) +
           geom_line() +
           coord_cartesian(ylim = c(0, yMax), expand = TRUE) +
           scale_x_discrete(labels = paste0("Q", rep(1:4, 3))) +
           scale_y_continuous(name = "Rate", expand = c(0,0)) +
           annotate(geom = "text", label = unique(test$Year),
                    x = 2.5 + 4 * (0:2),
                    y = -yMin,
                    size = 5, vjust = 0) +
           annotate(geom = "segment",
                    x = c(4.5, 8.5), xend = c(4.5, 8.5),
                    y = 0, yend = -yMin * 1.1) +
           theme(plot.margin = margin(c(1, 1, 3, 1), unit="lines"),
                 axis.title.x = element_blank(),
                 panel.background = element_blank(),
                 axis.line = element_line(),
                 legend.position = "bottom",
                 legend.margin = margin(c(3, 1, 1, 1), unit="lines"),
                 legend.background = element_rect(fill = alpha(0.5)))
                 ) %>%
  ggplotGrob() %>% 
  (function(x) {
    x$layout$clip[x$layout$name == "panel"] <- "off"
    return(x)
  }); grid.draw(fig2)

我将legend.background = element_rect(fill = alpha("red", 0.5)) 更改为legend.background = element_rect(fill = alpha(0.5)),因为上边距显示为红色并与辅助轴标题重叠。

【讨论】:

  • 嗯,与图例仍有重叠,和/或情节下方的边距非常大。我首先选择native 单位的原因是因为我认为它们会响应情节的高度。次要 x 轴标签的位置总是会响应高度,因为它们位于 Y 轴上,所以我想绘图边距和图例位置也必须响应?
  • 您要打印到文件吗?你有想要的人物高宽比吗?
  • 我打算在 Rmd 中使用该图,并将其编织为 html。我还没有弄清楚尺寸到底是多少,我希望在我需要更大或更小的数字时不必手动更改间距,你知道吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多