Browse code

geom_facet

Guangchuang Yu authored on 23/05/2019 06:56:06
Showing 10 changed files

... ...
@@ -9,6 +9,7 @@ S3method(fortify,phylo4)
9 9
 S3method(fortify,phylo4d)
10 10
 S3method(fortify,phyloseq)
11 11
 S3method(fortify,treedata)
12
+S3method(ggplot_add,facet_plot)
12 13
 S3method(ggplot_add,facet_xlim)
13 14
 S3method(ggplot_add,scale_ggtree)
14 15
 S3method(groupClade,ggtree)
... ...
@@ -39,6 +40,7 @@ export(geom_aline)
39 40
 export(geom_balance)
40 41
 export(geom_cladelabel)
41 42
 export(geom_cladelabel2)
43
+export(geom_facet)
42 44
 export(geom_hilight)
43 45
 export(geom_hilight_encircle)
44 46
 export(geom_label)
... ...
@@ -1,5 +1,6 @@
1 1
 # ggtree 1.17.1
2 2
 
3
++ `geom_facet`, a geom layer version of `facet_plot` (2019-05-23, Thu)
3 4
 + update `scale_x_ggtree`, now we can use `gheatmap() + scale_x_ggtree()` (2019-05-22, Wed)
4 5
 + extend `xlim_expand` to work with `ggplot2` (2019-05-20, Tue)
5 6
   - <https://yulab-smu.github.io/treedata-book/chapter9.html#xlim_expand>
6 7
new file mode 100644
... ...
@@ -0,0 +1,76 @@
1
+##' label facet_plot output
2
+##'
3
+##' 
4
+##' @title facet_labeller
5
+##' @param p facet_plot output
6
+##' @param label labels of facet panels
7
+##' @return ggplot object
8
+##' @importFrom ggplot2 labeller
9
+##' @export
10
+##' @author Guangchuang Yu
11
+facet_labeller <- function(p, label) {
12
+    ## .panel <- panel_col_var(p)
13
+    ## lbs <- panel_col_levels(p)
14
+    lbs  <-  levels(p$data$.panel)
15
+    names(lbs)  <-  lbs
16
+    label <- label[names(label) %in% lbs]
17
+    lbs[names(label)]  <-  label
18
+
19
+    ## ff <- as.formula(paste(" . ~ ", .panel))
20
+    p + facet_grid(. ~ .panel, scales="free_x",
21
+                   labeller = labeller(.panel = lbs))
22
+}
23
+
24
+
25
+##' set relative widths (for column only) of facet plots
26
+##'
27
+##' 
28
+##' @title facet_widths
29
+##' @param p ggplot or ggtree object
30
+##' @param widths relative widths of facet panels
31
+##' @return ggplot object by redrawing the figure (not a modified version of input object)
32
+##' @author Guangchuang Yu
33
+##' @export
34
+##' @importFrom ggplot2 ggplot_gtable
35
+facet_widths <- function(p, widths) {
36
+    if (!is.null(names(widths))) {
37
+        ## if (is.ggtree(p) && !is.null(names(widths))) {
38
+        ## .panel <- levels(p$data$.panel)
39
+        .panel <- panel_col_levels(p)
40
+        w <- rep(1, length=length(.panel))
41
+        names(w) <- .panel
42
+        w[names(widths)] <- widths
43
+        widths <- w
44
+    }
45
+    gt  <- ggplot_gtable(ggplot_build(p))
46
+    for(i in seq_along(widths)) {
47
+        j <- gt$layout$l[grep(paste0('panel-', i), gt$layout$name)]
48
+        gt$widths[j] = widths[i] * gt$widths[j]
49
+    }
50
+    return(ggplotify::as.ggplot(gt))
51
+}
52
+
53
+panel_col_var <- function(p) {
54
+    m <- p$facet$params$cols[[1]]
55
+    if (is.null(m))
56
+        return(m)
57
+
58
+    ## rlang::quo_name(m)
59
+    rlang::quo_text(m)
60
+}
61
+
62
+panel_col_levels <- function(p) {
63
+    levels(p$data[[panel_col_var(p)]])
64
+}
65
+
66
+##' @importFrom ggplot2 facet_grid
67
+add_panel <- function(p, panel) {
68
+    df <- p$data
69
+    if (is.null(df[[".panel"]])) {
70
+        df[[".panel"]] <- factor("Tree")
71
+    }
72
+    levels(df$.panel) %<>% c(., panel)
73
+    p$data <- df
74
+    p + facet_grid(.~.panel, scales="free_x")
75
+}
76
+
... ...
@@ -3,8 +3,9 @@
3 3
 ##'
4 4
 ##' 'facet_plot()' automatically re-arranges the input 'data' according to the tree structure,
5 5
 ##' visualizes the 'data' on specific 'panel' using the 'geom' function with aesthetic 'mapping' and other parameters,
6
-##' and align the graph with the tree 'p' side by side.
6
+##' and align the graph with the tree 'p' side by side. 'geom_facet' is a 'ggplot2' layer version of 'facet_plot'
7 7
 ##' @title facet_plot
8
+##' @rdname facet-plot
8 9
 ##' @param p tree view
9 10
 ##' @param panel panel name for plot of input data
10 11
 ##' @param data data to plot by 'geom', first column should be matched with tip label of tree
... ...
@@ -20,85 +21,18 @@
20 21
 ##' @export
21 22
 ##' @author Guangchuang Yu
22 23
 facet_plot <- function(p, panel, data, geom, mapping=NULL, ...) {
23
-    p <- add_panel(p, panel)
24
-    df <- p %+>% data
25
-    p + geom(data=df, mapping=mapping, ...)
24
+    p + geom_facet(panel = panel, data = data,
25
+                   geom = geom, mapping = mapping, ...)
26 26
 }
27 27
 
28
-
29
-##' @importFrom ggplot2 facet_grid
30
-add_panel <- function(p, panel) {
31
-    df <- p$data
32
-    if (is.null(df[[".panel"]])) {
33
-        df[[".panel"]] <- factor("Tree")
34
-    }
35
-    levels(df$.panel) %<>% c(., panel)
36
-    p$data <- df
37
-    p + facet_grid(.~.panel, scales="free_x")
38
-}
39
-
40
-
41
-##' label facet_plot output
42
-##'
43
-##' 
44
-##' @title facet_labeller
45
-##' @param p facet_plot output
46
-##' @param label labels of facet panels
47
-##' @return ggplot object
48
-##' @importFrom ggplot2 labeller
49
-##' @export
50
-##' @author Guangchuang Yu
51
-facet_labeller <- function(p, label) {
52
-    ## .panel <- panel_col_var(p)
53
-    ## lbs <- panel_col_levels(p)
54
-    lbs  <-  levels(p$data$.panel)
55
-    names(lbs)  <-  lbs
56
-    label <- label[names(label) %in% lbs]
57
-    lbs[names(label)]  <-  label
58
-
59
-    ## ff <- as.formula(paste(" . ~ ", .panel))
60
-    p + facet_grid(. ~ .panel, scales="free_x",
61
-                   labeller = labeller(.panel = lbs))
62
-}
63
-
64
-
65
-##' set relative widths (for column only) of facet plots
66
-##'
67
-##' 
68
-##' @title facet_widths
69
-##' @param p ggplot or ggtree object
70
-##' @param widths relative widths of facet panels
71
-##' @return ggplot object by redrawing the figure (not a modified version of input object)
72
-##' @author Guangchuang Yu
28
+##' @rdname facet-plot
73 29
 ##' @export
74
-##' @importFrom ggplot2 ggplot_gtable
75
-facet_widths <- function(p, widths) {
76
-    if (!is.null(names(widths))) {
77
-        ## if (is.ggtree(p) && !is.null(names(widths))) {
78
-        ## .panel <- levels(p$data$.panel)
79
-        .panel <- panel_col_levels(p)
80
-        w <- rep(1, length=length(.panel))
81
-        names(w) <- .panel
82
-        w[names(widths)] <- widths
83
-        widths <- w
84
-    }
85
-    gt  <- ggplot_gtable(ggplot_build(p))
86
-    for(i in seq_along(widths)) {
87
-        j <- gt$layout$l[grep(paste0('panel-', i), gt$layout$name)]
88
-        gt$widths[j] = widths[i] * gt$widths[j]
89
-    }
90
-    return(ggplotify::as.ggplot(gt))
30
+geom_facet <- function(panel, data, geom, mapping=NULL, ...) {
31
+    params <- list(...)
32
+    structure(list(panel = panel, data = data,
33
+                   geom = geom, mapping = mapping,
34
+                   params = params), class = 'facet_plot')
91 35
 }
92 36
 
93
-panel_col_var <- function(p) {
94
-    m <- p$facet$params$cols[[1]]
95
-    if (is.null(m))
96
-        return(m)
97 37
 
98
-    ## rlang::quo_name(m)
99
-    rlang::quo_text(m)
100
-}
101 38
 
102
-panel_col_levels <- function(p) {
103
-    levels(p$data[[panel_col_var(p)]])
104
-}
105 39
new file mode 100644
... ...
@@ -0,0 +1,83 @@
1
+##' @importFrom rlang quo_name
2
+##' @importFrom ggplot2 ggplot_add
3
+##' @method ggplot_add facet_xlim
4
+##' @export
5
+ggplot_add.facet_xlim <- function(object, plot, object_name) {
6
+    var <- panel_col_var(plot)
7
+    free_x <- plot$facet$params$free$x
8
+    if (!is.null(free_x)) {
9
+        if (!free_x)
10
+            message('If you want to adjust xlim for specific panel, ',
11
+                    'you need to set `scales = "free_x"`')
12
+    }
13
+
14
+    dummy <- data.frame(x = object$x, .panel = object$panel)
15
+    if (!is.null(var)) {
16
+        names(dummy)[2] <- var
17
+    }
18
+
19
+    obj <- geom_blank(aes_(x = ~x), dummy, inherit.aes = FALSE)
20
+    ggplot_add(obj, plot, object_name)
21
+}
22
+
23
+
24
+##' @method ggplot_add facet_plot
25
+##' @export
26
+ggplot_add.facet_plot <- function(object, plot, object_name) {
27
+    plot <- add_panel(plot, object$panel)
28
+    df <- plot %+>% object$data
29
+    params <- c(list(data = df, mapping = object$mapping),
30
+                object$params)
31
+    obj <- do.call(object$geom, params)
32
+    ggplot_add(obj, plot, object_name)
33
+}
34
+
35
+##' @importFrom ggplot2 scale_x_continuous
36
+##' @importFrom ggplot2 scale_x_date
37
+##' @method ggplot_add scale_ggtree
38
+##' @export
39
+ggplot_add.scale_ggtree <- function(object, plot, object_name) {
40
+    mrsd <- get("mrsd", envir = plot$plot_env)
41
+    if (!is.null(mrsd) && class(plot$data$x) == "Date") {
42
+        x <- Date2decimal(plot$data$x)
43
+    } else {
44
+        x <- plot$data$x
45
+    }
46
+
47
+    breaks <- object$breaks
48
+    labels <- object$labels
49
+
50
+    if (length(breaks) == 0) {
51
+        breaks <- graphics::hist(x, breaks=5, plot=FALSE)$breaks
52
+    }
53
+    m <- attr(plot, "mapping")
54
+
55
+    if (!is.null(mrsd) && class(m$to) == "Date") {
56
+        to <- Date2decimal(m$to)
57
+    } else {
58
+        to <- m$to
59
+    }
60
+    
61
+    idx <- which(sapply(breaks, function(x) any(x > m$to)))
62
+    if (length(idx)) {
63
+        breaks <- breaks[-idx]
64
+    }
65
+
66
+    if (length(labels) == 0) {
67
+        labels <- breaks
68
+    }
69
+
70
+    if (length(breaks) != length(labels)) {
71
+        stop("breaks and labels should be in equal length.")
72
+    }
73
+
74
+    breaks <- c(breaks, to)
75
+    labels <- c(labels, gsub("\\.", "", as.character(m$from)))
76
+
77
+    if (!is.null(mrsd) && class(plot$data$x) == "Date") {
78
+        obj <- scale_x_date(breaks=decimal2Date(breaks), labels)
79
+    } else {
80
+        obj <- scale_x_continuous(breaks=breaks, labels=labels)
81
+    }
82
+    ggplot_add(obj, plot, object_name)
83
+}
... ...
@@ -13,52 +13,3 @@ scale_x_ggtree <- function(breaks = waiver(), labels = waiver()) {
13 13
 }
14 14
 
15 15
 
16
-##' @importFrom ggplot2 scale_x_continuous
17
-##' @importFrom ggplot2 scale_x_date
18
-##' @method ggplot_add scale_ggtree
19
-##' @export
20
-ggplot_add.scale_ggtree <- function(object, plot, object_name) {
21
-    mrsd <- get("mrsd", envir = plot$plot_env)
22
-    if (!is.null(mrsd) && class(plot$data$x) == "Date") {
23
-        x <- Date2decimal(plot$data$x)
24
-    } else {
25
-        x <- plot$data$x
26
-    }
27
-
28
-    breaks <- object$breaks
29
-    labels <- object$labels
30
-
31
-    if (length(breaks) == 0) {
32
-        breaks <- graphics::hist(x, breaks=5, plot=FALSE)$breaks
33
-    }
34
-    m <- attr(plot, "mapping")
35
-
36
-    if (!is.null(mrsd) && class(m$to) == "Date") {
37
-        to <- Date2decimal(m$to)
38
-    } else {
39
-        to <- m$to
40
-    }
41
-    
42
-    idx <- which(sapply(breaks, function(x) any(x > m$to)))
43
-    if (length(idx)) {
44
-        breaks <- breaks[-idx]
45
-    }
46
-
47
-    if (length(labels) == 0) {
48
-        labels <- breaks
49
-    }
50
-
51
-    if (length(breaks) != length(labels)) {
52
-        stop("breaks and labels should be in equal length.")
53
-    }
54
-
55
-    breaks <- c(breaks, to)
56
-    labels <- c(labels, gsub("\\.", "", as.character(m$from)))
57
-
58
-    if (!is.null(mrsd) && class(plot$data$x) == "Date") {
59
-        obj <- scale_x_date(breaks=decimal2Date(breaks), labels)
60
-    } else {
61
-        obj <- scale_x_continuous(breaks=breaks, labels=labels)
62
-    }
63
-    ggplot_add(obj, plot, object_name)
64
-}
... ...
@@ -25,27 +25,6 @@ xlim_expand <- function(xlim, panel) {
25 25
     structure(list(x = xlim, panel = panel), class = "facet_xlim")
26 26
 }
27 27
 
28
-##' @importFrom rlang quo_name
29
-##' @importFrom ggplot2 ggplot_add
30
-##' @method ggplot_add facet_xlim
31
-##' @export
32
-ggplot_add.facet_xlim <- function(object, plot, object_name) {
33
-    var <- panel_col_var(plot)
34
-    free_x <- plot$facet$params$free$x
35
-    if (!is.null(free_x)) {
36
-        if (!free_x)
37
-            message('If you want to adjust xlim for specific panel, ',
38
-                    'you need to set `scales = "free_x"`')
39
-    }
40
-
41
-    dummy <- data.frame(x = object$x, .panel = object$panel)
42
-    if (!is.null(var)) {
43
-        names(dummy)[2] <- var
44
-    }
45
-
46
-    obj <- geom_blank(aes_(x = ~x), dummy, inherit.aes = FALSE)
47
-    ggplot_add(obj, plot, object_name)
48
-}
49 28
 
50 29
 ##' reverse timescle x-axis
51 30
 ##'
52 31
similarity index 84%
53 32
rename from man/facet_plot.Rd
54 33
rename to man/facet-plot.Rd
... ...
@@ -2,9 +2,12 @@
2 2
 % Please edit documentation in R/facet_plot.R
3 3
 \name{facet_plot}
4 4
 \alias{facet_plot}
5
+\alias{geom_facet}
5 6
 \title{facet_plot}
6 7
 \usage{
7 8
 facet_plot(p, panel, data, geom, mapping = NULL, ...)
9
+
10
+geom_facet(panel, data, geom, mapping = NULL, ...)
8 11
 }
9 12
 \arguments{
10 13
 \item{p}{tree view}
... ...
@@ -28,7 +31,7 @@ plot tree associated data in an additional panel
28 31
 \details{
29 32
 'facet_plot()' automatically re-arranges the input 'data' according to the tree structure,
30 33
 visualizes the 'data' on specific 'panel' using the 'geom' function with aesthetic 'mapping' and other parameters,
31
-and align the graph with the tree 'p' side by side.
34
+and align the graph with the tree 'p' side by side. 'geom_facet' is a 'ggplot2' layer version of 'facet_plot'
32 35
 }
33 36
 \examples{
34 37
 tr <- rtree(10)
... ...
@@ -1,5 +1,5 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/facet_plot.R
2
+% Please edit documentation in R/facet-utilities.R
3 3
 \name{facet_labeller}
4 4
 \alias{facet_labeller}
5 5
 \title{facet_labeller}
... ...
@@ -1,5 +1,5 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/facet_plot.R
2
+% Please edit documentation in R/facet-utilities.R
3 3
 \name{facet_widths}
4 4
 \alias{facet_widths}
5 5
 \title{facet_widths}