lets-plot-kotlin
lets-plot-kotlin copied to clipboard
Heatmap with dendrogram
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
wow, that would be huge contribution! Do I understand correctly you are using lets-plot Kotlin API?
yes, correct, we use Kotlin API
in this event let me transfer you to the LPK project. Disregard scary notifications.
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?
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
Sounds great!
GGBunch example: https://nbviewer.org/github/JetBrains/lets-plot-kotlin/blob/master/docs/examples/jupyter-notebooks/ggbunch.ipynb
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.
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](https://user-images.githubusercontent.com/3834261/176537985-c877dc4a-7c2b-4609-a687-7ab18998362b.png)
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](https://user-images.githubusercontent.com/3834261/176538300-6d233f05-b1dc-4c37-aa6c-a6e98cc8d287.png)
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](https://user-images.githubusercontent.com/3834261/176538659-ffa1aa3a-3666-4596-bf29-7eac3aa404e9.png)
Hi Stanislav, congratulations, it looks awesome!
Not sure what the second + statCompareMeans()
adds in the last (boxplot) test.
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.