Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heatmap with dendrogram #94

Open
PoslavskySV opened this issue Oct 27, 2021 · 11 comments
Open

Heatmap with dendrogram #94

PoslavskySV opened this issue Oct 27, 2021 · 11 comments
Milestone

Comments

@PoslavskySV
Copy link

Dear Colleagues,

we are very exited using your library in our projects and thank you for developing it. Our team is quite eager to know whether you have plans to add a dendrogram and heatmap with dendrogram in the upcoming releases? If you don't have such plans and since we need these kind of plots very much, probably you may give us a guide how we can implement these plots, then we will be able to make a proper PR.

Warm regards,
Stanislav

@alshan
Copy link
Collaborator

alshan commented Oct 27, 2021

wow, that would be huge contribution! Do I understand correctly you are using lets-plot Kotlin API?

@PoslavskySV
Copy link
Author

yes, correct, we use Kotlin API

@alshan
Copy link
Collaborator

alshan commented Oct 28, 2021

in this event let me transfer you to the LPK project. Disregard scary notifications.

@alshan alshan transferred this issue from JetBrains/lets-plot Oct 28, 2021
@alshan
Copy link
Collaborator

alshan commented Oct 28, 2021

We didn't plan to release dendrogram any time soon and if you are willing to put efforts in this task it would be great.

The 1st step would be implement dendrogram as a separate plot similar to the ggdendro package. I.e. using geom_segment() and perhaps geom_text().

Dendrogram API we can put to the "jetbrains.letsPlot.bistro" package next to CorrPlot.

Dont worry about plot orientation - we are releasing coord_flip() pretty soon.

The next step would be the heatmap combo. We don't have 'marginal plot' feature yet so unfortunately you will have to compute sizes and positions of plots manually and use GGBunch to combine heatmap and dendrograms in one figure.

How does it sound?

@PoslavskySV
Copy link
Author

Hi Igor,

thank you very much for a quick response. We looked in the sources of ggdendro and an example of CorrPlot. I think it is pretty straightforward, so we will try to implement dendrogram that way. But I'm still not sure how to use GGBunch to combine dendrogram and heatmap, so we'll investigate this further. Meanwhile, we'll start with dendrogram and come back if any questions arise. Once we will be ready, we open PR. Thank you very much for the help.

With best wishes,
Stanislav

@alshan
Copy link
Collaborator

alshan commented Oct 29, 2021

Sounds great!

@alshan
Copy link
Collaborator

alshan commented Oct 29, 2021

@alshan
Copy link
Collaborator

alshan commented Jun 28, 2022

Hi Stanislav, how is dendrogram going?
In v3.3.0 we've added ggmarginal() which could help to add dendrogram on a plot margin.
Top/bottom margins should work right away. Left/right margin will require setting orientation="y" to the dendrogram geometry layer.

Doc: ggmarginal.

@PoslavskySV
Copy link
Author

PoslavskySV commented Jun 29, 2022

Hi Igor,

I've implemented heatmap and dendrogram, but not in a conventional ggplot way, so I'm not sure how it could be helpful for the lets-plot project; there are fundamentally things which may not be done in a ggplot way (e.g. several different fill scales etc). Our library (just made it public, its in the wip, no docs still; the license will be changed later to apache) combines ggpubr, ggdendro, heatmap2 and other addon packages for ggplot.

I will be happy to discuss with you how we can make it more useful for lets-plot project!

Few examples:

Heatmaps with clustering

https://github.com/milaboratory/miplots/blob/master/src/test/kotlin/com/milaboratory/miplots/heatmap/HeatmapTest.kt

val plt = Heatmap(
    TestData.sampleMatrix(15, 15), "x", "y", "z",
    xOrder = Hierarchical(),
    yOrder = Hierarchical()
)
    .withBorder()
    .withColorKey(
        "xcat", Top,
        sep = 0.1, pallete = Categorical.Triadic9Bright,
        label = "X Cat", labelPos = Left, labelSep = 0.2, labelSize = 2.0
    )
    .withColorKey(
        "ycat", Right,
        sep = 0.1, pallete = Categorical.Triadic9Bright,
        label = "Y Cat", labelPos = Top, labelSep = 0.2, labelSize = 2.0, labelAngle = 90.0
    )
    .withDendrogram(Top)
    .withDendrogram(Right)
    .withLabels(Left, sep = 0.2)
    .withLabels(Bottom, sep = 0.2, angle = 45)
    .withFillLegend(Bottom, title = "Awesome Z label", textSize = 1.5, sizeUnit = "x")

image

Dendro

https://github.com/milaboratory/miplots/blob/master/src/test/kotlin/com/milaboratory/miplots/dendro/GGDendroTest.kt

val tree =
    root {
        repeat(2) {
            node {
                repeat(2) {
                    node {
                        repeat(2) {
                            node {
                                repeat(2) {
                                    node()
                                }
                            }
                        }
                    }
                }
            }
        }
    }

GGDendroPlot(
    tree,
    rpos = Left
) {
    color = label
}
    .withLabels(label)
    .withAlignmentLayer(alignment)

image

Statistics

https://github.com/milaboratory/miplots/blob/master/src/test/kotlin/com/milaboratory/miplots/stat/xdiscrete/statCompareMeansTest.kt

GGBoxPlot(
        toothGrowth,
        x = "dose",
        y = "len"
    ) {
        fill = "dose"
    } + statCompareMeans(
        allComparisons = true,
        method = TestMethod.KruskalWallis,
        multipleGroupsMethod = TestMethod.KruskalWallis
    ) + statCompareMeans()

image

@alshan
Copy link
Collaborator

alshan commented Jun 30, 2022

Hi Stanislav, congratulations, it looks awesome!

Not sure what the second + statCompareMeans() adds in the last (boxplot) test.

@PoslavskySV
Copy link
Author

The last + statCompareMeans() adds the overall p-value layer (between all three groups), and the first one adds pairwise p-values. Not sure that it is a good way to do, but I tried to mimicrate how it done in ggpubr.

@alshan alshan added this to the 2024Q3 milestone Jul 1, 2024
@alshan alshan modified the milestones: 2024Q3, 2024Q4 Oct 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants