简体   繁体   English

ggplot2:图外注解的边距

[英]ggplot2: margins for annotations outside of plot

I've got almost the exact same problem as this question: Multi-row x-axis labels in ggplot line chart . 我遇到了与该问题几乎完全相同的问题: ggplot折线图中的多行x轴标签 The accepted answer works for me most of the way, but depending on the size of my plot, the annotations sometimes fall off my plot. 可接受的答案在大多数情况下对我都有效,但是根据我的情节的大小,注释有时会落在我的情节上。

I've tried messing around with plot and legend margins relative to the y scale, but it hasn't worked as I'd hoped. 我试图弄乱相对于y比例尺的图和图例边距,但是它没有达到我希望的那样。 This is what I've got so far: 到目前为止,这是我得到的:

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)

At one size, the plot looks fine, but if I increase the height of the plot, the years start to clash with the legend, and if I make it even taller, they just disappear off the bottom. 以一种尺寸看,情节看起来不错,但是如果我增加情节的高度,年份就会与图例发生冲突,如果我把它提高得更高,它们只会从底部消失。

I'm confused as to why the legend margin doesn't scale along with the size of the plot, because if it did I think that would fix my issue. 我对图例边距为什么不随地块的大小而缩放感到困惑,因为如果这样做,我认为这将解决我的问题。 Also, I'm very confused why a legend margin of 30 native units is about the same size as the plot margin of ~0.04 native units? 另外,我非常困惑,为什么图例边距为30个本机单位与图边距〜0.04个本机单位大约相同?

Plot laid out as I would like (red legend background was just so I could see what was going on): 按照我的意愿进行布局(红色图例背景只是为了让我看到发生了什么): 常规高度

Taller plot starting to have problems: 较高的地块开始出现问题: 高(问题图)

@Oliver changing the plot.margin units to lines , in , cm works for me, the issue was with the scaling in native units. @Oliver将plot.margin单位更改为linesincm对我plot.margin ,问题在于native单位的缩放。 Would this solution work for you? 该解决方案对您有用吗?

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)

I changed the legend.background = element_rect(fill = alpha("red", 0.5)) to legend.background = element_rect(fill = alpha(0.5)) as the upper margin is being shaded red and overlapping with the secondary axis titles. 我将legend.background = element_rect(fill = alpha("red", 0.5))更改为legend.background = element_rect(fill = alpha(0.5))因为上边距被legend.background = element_rect(fill = alpha(0.5))成红色并与辅助轴标题重叠。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM