首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用ggproto扩展ggplot2盒图?

如何用ggproto扩展ggplot2盒图?
EN

Stack Overflow用户
提问于 2016-01-19 12:20:03
回答 1查看 1.7K关注 0票数 7

我经常在我的作品中使用盒形图,喜欢ggplot2美学。但是标准geom_boxplot缺少两件对我很重要的东西:胡须末端和中间标签。感谢这里的信息,我编写了一个函数:

代码语言:javascript
复制
gBoxplot <- function(formula = NULL, data = NULL, font = "CMU Serif", fsize = 18){
  require(ggplot2)
  vars <- all.vars(formula)
  response <- vars[1]
  factor <- vars[2]
  # A function for medians labelling
  fun_med <- function(x){
    return(data.frame(y = median(x), label = round(median(x), 3)))
  }
  p <- ggplot(data, aes_string(x = factor, y = response)) +
  stat_boxplot(geom = "errorbar", width = 0.6) +
  geom_boxplot() +
  stat_summary(fun.data = fun_med, geom = "label", family = font, size = fsize/3, 
                                                                         vjust = -0.1) +
  theme_grey(base_size = fsize, base_family = font)
  return(p)
}

还有字体设置,但这仅仅是因为我懒得做一个主题。下面是一个示例:

代码语言:javascript
复制
gBoxplot(hwy ~ class, mpg)

对我来说已经足够好了,但是也有一些限制(不能使用自动躲避等等),最好是基于geom_boxplot来制作一个新的geom。我读过扩展ggplot2,但无法理解如何实现它。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-18 15:07:45

所以一直在想这件事。基本上,当您创建一个新的原语时,通常会编写以下内容的组合:

  1. 一个layer-function
  2. stat-ggproto
  3. 一个geom-ggproto

只有layer-function对用户是可见的。您只需要编写一个stat-ggproto,如果您需要一些新的方式来转换您的数据,使您的原语。而且你只需要写一个geom-ggproto,如果你有一些新的网格图形要创建。

在这种情况下,我们基本上是在堆肥已经存在的layer-function,我们实际上不需要编写新的ggprotos。编写一个新的layer-function.就足够了这个layer-function将创建您已经使用的三个层,并按您所希望的方式映射参数。在这种情况下:

  • Layer1 -使用geom_errorbarstat_boxplot来获取我们的错误条
  • Layer2 -使用geom_boxplotstat_boxplot创建方框
  • Layer3 --用户geom_labelstat_summary --创建文本框中间的平均值的文本标签。

当然,您可以编写一个新的stat-ggproto和一个新的geom-ggproto来同时完成所有这些事情。或者你可以把stat_summarystat_boxplot合二为一,还有三个geom-protos,这是用一个层来完成的。但是,除非我们有效率问题,否则没有什么意义。

总之,这是代码:

代码语言:javascript
复制
geom_myboxplot <- function(formula = NULL, data = NULL,
                           stat = "boxplot", position = "dodge",coef=1.5,
                           font = "sans", fsize = 18, width=0.6,
                           fun.data = NULL, fun.y = NULL, fun.ymax = NULL,
                           fun.ymin = NULL, fun.args = list(),
                           outlier.colour = NULL, outlier.color = NULL,
                           outlier.shape = 19, outlier.size = 1.5,outlier.stroke = 0.5,
                           notch = FALSE,  notchwidth = 0.5,varwidth = FALSE,
                           na.rm = FALSE, show.legend = NA,
                           inherit.aes = TRUE,...) {
    vars <- all.vars(formula)
    response <- vars[1]
    factor <- vars[2]
    mymap <- aes_string(x=factor,y=response)
    fun_med <- function(x) {
        return(data.frame(y = median(x), label = round(median(x), 3)))
    }
    position <- position_dodge(width)
    l1 <- layer(data = data, mapping = mymap, stat = StatBoxplot,
            geom = "errorbar", position = position, show.legend = show.legend,
            inherit.aes = inherit.aes, params = list(na.rm = na.rm,
                coef = coef, width = width, ...))
    l2 <- layer(data = data, mapping = mymap, stat = stat, geom = GeomBoxplot,
            position = position, show.legend = show.legend, inherit.aes = inherit.aes,
            params = list(outlier.colour = outlier.colour, outlier.shape = outlier.shape,
                outlier.size = outlier.size, outlier.stroke = outlier.stroke,
                notch = notch, notchwidth = notchwidth, varwidth = varwidth,
                na.rm = na.rm, ...))
    l3 <- layer(data = data, mapping = mymap, stat = StatSummary,
            geom = "label", position = position, show.legend = show.legend,
            inherit.aes = inherit.aes, params = list(fun.data = fun_med,
                fun.y = fun.y, fun.ymax = fun.ymax, fun.ymin = fun.ymin,
                fun.args = fun.args, na.rm=na.rm,family=font,size=fsize/3,vjust=-0.1,...))
    return(list(l1,l2,l3))
}

它允许您创建自定义的方框,它现在如下所示:

代码语言:javascript
复制
ggplot(mpg) +
  geom_myboxplot( hwy ~ class, font = "sans",fsize = 18)+
  theme_grey(base_family = "sans",base_size = 18 )

他们看起来是这样的

Note:我们实际上不必使用layer函数,我们可以使用原始的stat_boxplotgeom_boxplotstat_summary调用来代替它们。但是,如果我们想要能够从我们的自定义框图中控制它们,我们仍然需要填写所有的参数,所以我认为这种方式更清晰--至少从结构的角度来看,而不是从功能的角度。也许不是,这是品味的问题.

另外,我没有那种字体看起来更好看。但我不想追踪和安装它。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34876683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档