美文网首页R生信修炼
Writing ggplot2 extensions

Writing ggplot2 extensions

作者: 吴十三和小可爱的札记 | 来源:发表于2019-12-23 18:37 被阅读0次

    New themes

    新的themes 是最简单的扩展套件,基本上就是ggplot2 的theme的参数叠加,需要注意的是参数: complete = TRUE。

    print(theme_grey):从0开始构建新的theme(所需参数非常多)。

    print(theme_bw):以theme_grey 为基础,通过%+replace%替换theme_grey 中的一些参数,形成新的主题。

    function (base_size = 11, base_family = "", base_line_size = base_size/22, base_rect_size = base_size/22) 
    {
     theme_grey(base_size = base_size, base_family = base_family, base_line_size = base_line_size, base_rect_size = base_rect_size) %+replace% 
     theme(panel.background = element_rect(fill = "white", 
     colour = NA), panel.border = element_rect(fill = NA, 
     colour = "grey20"), panel.grid = element_line(colour = "grey92"), 
     panel.grid.minor = element_line(size = rel(0.5)), 
     strip.background = element_rect(fill = "grey85", 
     colour = "grey20"), legend.key = element_rect(fill = "white", 
     colour = NA), complete = TRUE)
    }
    

    print(theme_minimal):以theme_bw 为基础,修改一些关键点生成。

    ggplot2-ggproto

    ggproto 是一个基于原型的OO( object-oriented)系统,该系统灵感源于proto包。它模糊了类和实例(classes and instances)之间的界限,干净利落地支持跨包继承(Inherits),使之具有更快的性能。所有ggplot2对象都是使用ggproto 系统构建的,它维护了ggplot2 所需的proto features。换句话说,如果需要创建新的统计Stat、Geom、Position、Scale或者主题系统,就需要了解ggproto 这个OO system

    Person <- ggproto("Person", NULL,
     first = "",
     last = "",
     birthdate = NA,
    
     full_name = function(self) {
     paste(self$first, self$last)
     },
     age = function(self) {
     days_old <- Sys.Date() - self$birthdate
     floor(as.integer(days_old) / 365.25)
     },
     description = function(self) {
     paste(self$full_name(), "is", self$age(), "old")
     }
    )
    

    在这个ggproto 系统中,"Person"是该ggproto对象的class name,NULL 表示没有父对象(从0开始创建),接着是一系列参数和function。参数self 为 function 提供实施目标,而function 的运行的输出结果也能被self 参数用调用。

    Me <- ggproto(NULL, Person,
     first = "Thomas Lin",
     last = "Pedersen",
     birthdate = as.Date("1985/10/12")
    )
    

    此时,ggproto对象Me继承自Person 对象,Me 里面的参数可以调用Person 对象的function。

    Me$description()
    # "Thomas Lin Pedersen is 34 old"
    ​
    Me$full_name()
    #"Thomas Lin Pedersen"
    ​
    Me$birthdate
    "1985-10-12"
    

    延伸阅读,ggproto_parent() function。

    ggplot2 中的ggproto 系统是stateless的,换句话说,ggproto类别对象建立后就是稳定不变的,它们类似于量产的零件,我们在ggplot2 基础上进行构建时,只需要调用不同的零件就行了。

    例如,在创建GeomErrorbar这个系统时,调用或者继承了GeomLinerange中的setup_params。

    GeomErrorbar <- ggproto(
     # ...
     setup_params = function(data, params) {
     GeomLinerange$setup_params(data, params)
     }
     # ...
    }
    

    一般来说,如果需要创建一个新的ggplot2的统计变换(stat),只需要创建一个ggproto,并申明它继承(Inherits)于Stat就可以了,如ggproto("StatChull", Stat...)。创建新的geom也一样:ggproto("GeomSimplePoint", Geom...)。

    创建新的stat

    Stat 主要封装了compute_layer(), compute_panel(), and compute_group()等一连串的call 。一般来说,compute_layer() 通过compute_panel() 中的panel 分割纵列,而compute_panel() 通过compute_group() 中的group 分割数据纵列,最终将计算结果重新组装。

    setup_params() 接受构建layer data时规定的参数,返回的是一个参数名与compute_中的参数名相同的参数 list,用于设定需要计算的数据和参数信息。当setup_params() 设定后,setup_data() 会运行一次,用于接受修改好的layer data,返回的是一个layer data。

    StatChull <- ggproto("StatChull", Stat,
     required_aes = c("x", "y"),
     compute_group = function(data, scales) {
     data[chull(data$x, data$y), , drop = FALSE]
     }
    )
    

    上面的代码创建了一个简单的stat,前两个参数是它的名字和来源(继承自什么,Stat—也是一个ggproto系统),第三个是需要的美学参数(需要做统计变换的列),第四个是统计变换。data就是data frame, scales 是包含x,y的scales。chull(){grDevices} 函数返回位于凸壳位置的点的列索引,索引按顺时针方向排列;drop将数据降低一个维度(data.frame — list)。

    <setup_params() 接受构建layer data时规定的参数,返回的是一个参数名与compute_中的参数名相同的参数 list。

    setup_data() 接受修改好的layer data,返回的是一个layer data。

    layer可以用list包起来,一次可以添加多个layer>

    相关文章

      网友评论

        本文标题:Writing ggplot2 extensions

        本文链接:https://www.haomeiwen.com/subject/snktoctx.html