使用端点/ ggplot的中断计算设置ggplot网格线

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用端点/ ggplot的中断计算设置ggplot网格线相关的知识,希望对你有一定的参考价值。

我有一个ggplot问题,我正在尝试用非常小的外观制作线条图。我已经摆脱了传说,转而支持每行右侧的文字标签。如果标签不是那么长,它可能不那么引人注目,但如果网格线停在最大x值(在这种情况下,在2015年),我会更好。

library(tidyverse)

df <- structure(list(industry = c("Accommodation & Food Services", "Construction", "Health Care & Social Asst.", "Retail Trade", 
        "Accommodation & Food Services", "Construction", "Health Care & Social Asst.", "Retail Trade"), 
    year = c(2002L, 2002L, 2002L, 2002L, 2015L, 2015L, 2015L, 2015L), 
    value = c(6.977, 5.264, 17.065, 14.528, 8.032, 4.648, 20.547, 12.568)), 
    class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -8L), 
    .Names = c("industry", "year", "value"))

ggplot(df, aes(x = year, y = value, color = industry)) +
  geom_line() +
  geom_text(aes(label = industry), data = . %>% filter(year == max(year)), size = 3, hjust = 0, nudge_x = 0.1) +
  scale_x_continuous(expand = expand_scale(mult = c(0.05, 0.85)), breaks = c(min(df$year), max(df$year)), name = NULL) +
  scale_y_continuous(limits = c(0, NA), name = "Value (thousands)") +
  theme_minimal() +
  theme(legend.position = "none", 
        panel.grid.major.x = element_blank(), 
        panel.grid.minor = element_blank())

我想避免因为我有几个情节并想要快速将它们放在一起而进行的grob-hacking完成in this answer

到目前为止我提出的解决方案是通过制作一个geom_segment来创建伪网格线,该数据具有常规y值的虚拟数据,该y值从最早的年份开始到最后一年结束。这没关系,因为我知道我想要什么y-breaks,并且可以设置scale_y_continuous来匹配geom_segment

break_df <- tibble(x1 = 2002, x2 = 2015, y = seq(0, 20, by = 5))

ggplot(df, aes(x = year, y = value, color = industry)) +
  geom_segment(aes(x = x1, xend = x2, y = y, yend = y), data = break_df, inherit.aes = F, size = 0.4, color = "gray85") +
  geom_line() +
  geom_text(aes(label = industry), data = . %>% filter(year == max(year)), size = 3, hjust = 0, nudge_x = 0.1) +
  scale_x_continuous(expand = expand_scale(mult = c(0.05, 0.85)), breaks = c(min(df$year), max(df$year)), name = NULL) +
  scale_y_continuous(limits = c(0, NA), name = "Value (thousands)", breaks = break_df$y) +
  theme_minimal() +
  theme(legend.position = "none", 
        panel.grid = element_blank())

reprex package创建于2018-05-24(v0.2.0)。

我想知道的是ggplot如何计算休息时间,如果有一个函数它使用我可以利用它?就像有一些内部计算的休息时间,我可以提供给geom_segmentscale_y_continuous,所以他们匹配,没有我设置一个单独的休息信息数据框。

或者,也许这是一个愚蠢的方法,有一个更好的方式来获得我想要的网格线。我想也许有办法用trans function这样做,比如建造一个trans_new(),但我不知道如何去做。

提前致谢!

答案

我想提出一种使用annotation_custom()的替代方法,它实现了类似的外观,至少在这种情况下:

ggplot(df, aes(x = year, y = value, color = industry)) +
  geom_line() + 
  annotation_custom(
    grob = grid::rectGrob(gp = grid::gpar(col = NA, fill = "white")),
    xmin = max(df$year)
  ) +
  geom_text(aes(label = industry), data = . %>% filter(year == max(year)), 
            size = 3, hjust = 0, nudge_x = 0.1) +

  # note: my version of ggplot2 doesn't have the expand_scale function, but I suppose
  # it isn't critical to the question here
  scale_x_continuous(expand = c(0.2, 0), breaks = c(min(df$year), max(df$year)), 
                     name = NULL) +
  scale_y_continuous(limits = c(0, NA), name = "Value (thousands)") +
  theme_minimal() +
  theme(legend.position = "none", 
        panel.grid.major.x = element_blank(), 
        panel.grid.minor = element_blank())

plot

annotation_custom的默认位置参数是Inf / -Inf,将显示的grob拉伸到绘图面板的所有四个边缘,因此指定xmin = max(df$year)足以覆盖max(df$year)右侧的所有内容的网格线。

这个技巧最适用于没有可见panel.border组件的ggplot主题,例如theme_minimaltheme_greytheme_dark。如果你正在使用theme_bw / theme_linedraw / theme_light,那么幻觉变得不那么有效了。 (至于theme_classic / theme_void,他们没有网格线,所以两种方式无关紧要。)

以上是关于使用端点/ ggplot的中断计算设置ggplot网格线的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化:自定义设置X轴上的时间间隔(中断以年为单位),使用scale_x_date()自定义设置坐标轴间隔和标签添加标题副标题题注信息

R语言ggplot2可视化:自定义设置X轴上的时间间隔(中断以月为单位),使用scale_x_date()自定义设置坐标轴间隔和标签添加标题副标题题注信息

使用 ggplot2 在小中断处放置轴标签

使用ggplot2,我可以在轴上插入一个中断吗?

如何掌握ggplot中的x轴中断?

控制单个中断/标签 Facet Grid / ggplot2