GithubHelp home page GithubHelp logo

Comments (6)

hadley avatar hadley commented on September 18, 2024

Are you sure you should be using compute_group() and not compute_panel()?

from ggtree.

GuangchuangYu avatar GuangchuangYu commented on September 18, 2024

@hadley it works by using compute_panel(). Thank you!

from ggtree.

GuangchuangYu avatar GuangchuangYu commented on September 18, 2024

@hadley Sorry to bother you. I have another issue.

require(ape)
require(ggtree)
x=rmtree(3, 10)
df=fortify(x)
> head(df)
          node parent branch.length         x y label isTip    branch angle
Tree #1.1    1     13    0.03709821 0.6850552 2    t8  TRUE 0.6665061    18
Tree #1.2    2     13    0.65754318 1.3055002 3    t1  TRUE 0.9767286   -18
Tree #1.3    3     12    0.88514687 1.1904847 1   t10  TRUE 0.7479112    54
Tree #1.4    4     16    0.27829065 1.3919800 5    t3  TRUE 1.2528347   -90
Tree #1.5    5     16    0.37527841 1.4889678 6    t5  TRUE 1.3013286  -126
Tree #1.6    6     15    0.01499930 0.9624178 4    t6  TRUE 0.9549182   -36
              .id
Tree #1.1 Tree #1
Tree #1.2 Tree #1
Tree #1.3 Tree #1
Tree #1.4 Tree #1
Tree #1.5 Tree #1
Tree #1.6 Tree #1

geom_tree2() now works fine with phylo object, but not multiPhylo (a list of phylo). If the object is multiPhylo, after fortify() the df will have an additional column, .id.

What I expected is:

ggplot(df) + geom_tree() + facet_wrap(~.id)

screenshot 2016-01-22 10 57 21

But geom_tree2 only output the first panel.

ggplot(df) + geom_tree2() + facet_wrap(~.id)

screenshot 2016-01-22 10 57 15

The data has no problem, as I can scale the color based on .id.

ggplot(df) + geom_tree2() + aes(color=.id)

screenshot 2016-01-22 11 05 21

It seems that I should write a compute_layer() function. I read some source code of ggplot2, but it is too complicated for me. Can you give me some hints?

from ggtree.

hadley avatar hadley commented on September 18, 2024

compute_panel should take care of this for you - have you checked to verify that it's called three times?

from ggtree.

GuangchuangYu avatar GuangchuangYu commented on September 18, 2024
geom_tree <- function(layout="rectangular", ...) {
    x <- y <- parent <- NULL
    lineend  = "round"
    if (layout == "rectangular" || layout == "fan" || layout == "circular") {
        list(
            geom_segment(aes(x    = x[parent],
                             xend = x,
                             y    = y,
                             yend = y),
                         lineend  = lineend, ...),

            geom_segment(aes(x    = x[parent],
                             xend = x[parent],
                             y    = y[parent],
                             yend = y),
                         lineend  = lineend, ...)
            )
    } else if (layout == "slanted" || layout == "radial" || layout == "unrooted") {
        geom_segment(aes(x    = x[parent],
                         xend = x,
                         y    = y[parent],
                         yend = y),
                     lineend  = lineend, ...)
    }
}

To allow subsetting (i.e. x[parent]) properly, I change the parent node number in fortify.multiPhylo().

fortify.multiPhylo <-  function(model, data, layout="rectangular", 
                                ladderize=TRUE, right=FALSE, mrsd=NULL, ...) {

    df.list <- lapply(model, function(x) fortify(x, layout=layout, ladderize=ladderize, right=right, mrsd=mrsd, ...))
    if (is.null(names(model))) {
        names(df.list) <- paste0("Tree ", "#", seq_along(model))
    } else {
        names(df.list) <- names(model)
    }
    df <- do.call("rbind", df.list)
    df$.id <- rep(names(df.list), times=sapply(df.list, nrow))
    df$.id <- factor(df$.id, levels=names(df.list))

    nNode <- sapply(df.list, nrow)
    nNode2 <- cumsum(c(0, nNode[-length(nNode)])) 
    df$parent <- df$parent + rep(nNode2, times=nNode)
    return(df)
}

It works fine. So ggplot use the whole data frame in each panel when using facet_wrap(), otherwise subsetting will be failed.

But for geom_tree2, https://github.com/GuangchuangYu/ggtree/blob/master/R/geom_tree.R#L1-L144, only the first panel was plotted correctly and I am sure the compute_panel was called three times.

I test it without modify the parent node number, and it works with facet_wrap()

fortify.multiPhylo2 <-  function(model, data, layout="rectangular", 
                                ladderize=TRUE, right=FALSE, mrsd=NULL, ...) {

    df.list <- lapply(model, function(x) fortify(x, layout=layout, ladderize=ladderize, right=right, mrsd=mrsd, ...))
    if (is.null(names(model))) {
        names(df.list) <- paste0("Tree ", "#", seq_along(model))
    } else {
        names(df.list) <- names(model)
    }
    df <- do.call("rbind", df.list)
    df$.id <- rep(names(df.list), times=sapply(df.list, nrow))
    df$.id <- factor(df$.id, levels=names(df.list))

    ## nNode <- sapply(df.list, nrow)
    ## nNode2 <- cumsum(c(0, nNode[-length(nNode)])) 
    ## df$parent <- df$parent + rep(nNode2, times=nNode)
    return(df)
}

screenshot from 2016-01-25 00 06 32

With geom_tree2(), facet_wrap() use the subset of data in each panel. This is the reason why it fail with fortify.multiPhylo but not fortify.multiPhylo2.

So fortify.multiPhylo + geom_tree + facet_wrap works,
and fortify.multiPhylo2 + geom_tree2 + facet_wrap works too.

Q1

Why facet_wrap() behave different with geom_tree (use whole data in each panel) and geom_tree2 (use data subset in each panel)?

Q2

Is there any way to group the data, so that ggplot()+geom_tree2() can plot the trees correctly without changing the parent node number?

from ggtree.

GuangchuangYu avatar GuangchuangYu commented on September 18, 2024

Q2 was solved by keeping the original parent node number un-changed with updated Stat.

Q1 is still an open question. Why the calculation procedure of facet_wrap() is different in geom_tree and geom_tree2?

from ggtree.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.