MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.4k stars 310 forks source link

Heatmaps (clustering), dendrograms/trees #398

Open versipellis opened 5 years ago

versipellis commented 5 years ago

I'd love to see heatmaps support Clustering.jl's Hierarchical Clustering, sort of something like R's own heatmap.2 (https://www.rdocumentation.org/packages/gplots/versions/3.0.1.1/topics/heatmap.2) where the clustering can be plotted as dendrograms in addition to the heatmaps. I imagine something like this could be done with layouts and line primitives, but I'm only just getting started on Makie and am not sure if that's possible.

asinghvi17 commented 5 years ago

I think there's a Plots recipe for it, so it should be possible using Makie; however, the layouting will be a bit of a pain until we can implement a better system.

KronosTheLate commented 2 years ago

Any news? Would love to have makie recipes for dendrograms and trees.

SimonDanisch commented 2 years ago

Someone needs to write a recipe for it... I don't know of anyone working on it right now!

jbrea commented 2 years ago

I was also looking for this, and found an easy solution to plot dendrograms (without a recipe) using a modified version of StatsPlots.treeposition:

function treepositions(hc::Hclust; useheight = true, orientation = :vertical)
    order = StatsBase.indexmap(hc.order)
    nodepos = Dict(-i => (float(order[i]), 0.0) for i in hc.order)
    xs = []
    ys = []
    for i in 1:size(hc.merges, 1)
        x1, y1 = nodepos[hc.merges[i, 1]]
        x2, y2 = nodepos[hc.merges[i, 2]]
        xpos = (x1 + x2) / 2
        ypos = useheight ?  hc.heights[i] : (max(y1, y2) + 1)
        nodepos[i] = (xpos, ypos)
        push!(xs, [x1, x1, x2, x2])
        push!(ys, [y1, ypos, ypos, y2])
    end
    if orientation == :horizontal
        return ys, xs
    else
        return xs, ys
    end
end
function dendrogram(h; color = :blue, kwargs...)
    CairoMakie.Axis(Figure()[1, 1])
    for (x, y) in zip(treepositions(h; kwargs...)...)
        lines!(x, y; color)
    end
    current_figure()
end
pascalschulthess commented 2 years ago

Very nice functions. Thanks @jbrea. How would I implement colouring the lines in the dendrogram by cluster membership after I defined the number of clusters and determined the membership with e.g. cutree(h, k=4)?

jbrea commented 2 years ago

Good question @pascalschulthess :) I guess I would modify the treepositions function to return not only a list of xs and ys but also a list of colors. Based on the output of cutree and the hc structure it should be possible to determine the correct color for each node. But it would take me some time to figure everything out.

kescobo commented 1 year ago

See here for relevant discussion attached to StatsPlots regarding adding colors.

I'd like to get this recipe built - have you put any additional effort into making a PR for this, or a separate package? I'm happy to take over, but don't want to butt in if you have it in hand.

jbrea commented 1 year ago

I didn't work on this, but it would be nice to have it @kescobo !