DingWB / PyComplexHeatmap

PyComplexHeatmap: A Python package to plot complex heatmap (clustermap)
https://dingwb.github.io/PyComplexHeatmap/
MIT License
249 stars 28 forks source link

composite Clustermap enforces same dimensions for both clustermaps #41

Closed demian1 closed 12 months ago

demian1 commented 1 year ago

When trying to plot two clustermaps that share one axis, PyComplexHeatmap.clustermap.composite() enforces both column and indexes to be the same as the main cluster map.

This is enforced in the following code:

for i, cm in enumerate(cmlist):
        if i == main:
            continue
        gs1 = gs[i, 0] if axis == 0 else gs[0, i]
        cm.plot(ax=axes[i], subplot_spec=gs1, row_order=cm_1.row_order, col_order=cm_1.col_order)
        for L in cm.legend_list:
            if L[1] not in legend_names:
                legend_names.append(L[1])
                legend_list.append(L)
        w = ax.figure.get_window_extent().width * cm.label_max_width / cm.ax.figure.get_window_extent().width
        if w > label_max_width:
            label_max_width = w

The parameters row_order and col_order in cm.plot should be given dynamically depending on whether axis = 0 or axis = 1

DingWB commented 1 year ago

Yeah, you are right. Sorry for the mistake. I have already fixed it in the latest GitHub push. Please install it using pip install git+https://github.com/DingWB/PyComplexHeatmap Please kindly test it and give me feedback if there are any bugs.

demian1 commented 12 months ago

Thanks for the quick fix!

I would also recommend the option to pass height_ratios and width_ratios to the function. Something like:

if axis == 1:  # horizontally
        wspace = col_gap * mm2inch * ax.figure.dpi / (ax.get_window_extent().width / n)
        nrows = 1
        ncols = n
        width_ratios = [cm.data2d.shape[1] for cm in cmlist] if width_ratios is None else width_ratios
        height_ratios = None
else:  # vertically
        hspace = row_gap * mm2inch * ax.figure.dpi / (ax.get_window_extent().height / n)
        nrows = n
        ncols = 1
        width_ratios = None
        height_ratios = [cm.data2d.shape[0] for cm in cmlist] if height_ratios is None else height_ratios
demian1 commented 12 months ago

I've been playing around with the function on my own data, and it works great so far!

Of course the clustermaps do not align anymore if one provides different number of row or column annotations

DingWB commented 12 months ago

That's a good idea. Could you please make a pull request?

demian1 commented 12 months ago

Just did