Concatenate Multiple Cross-layouts#

For situations where a single cross-layout is insufficient to demonstrate your data, you may want to concatenate multiple cross-layouts together.

Suppose you have a blue heatmap and a green heatmap, as shown below:

>>> import marsilea as ma
>>> data1 = np.random.rand(20, 20)
>>> h1 = ma.Heatmap(data1, cmap="Blues", width=4, height=4, name="h1")
>>> h1.add_title(top="Blue", align="left")
>>> h1.add_legends()
>>> h1.render()
../_images/concatenation-1.png
>>> data2 = np.random.rand(10,10)
>>> h2 = ma.Heatmap(data2, cmap="Greens", width=2, height=2, name="h2")
>>> h2.add_title(top="Green", align="left")
>>> h2.add_legends()
>>> h2.render()
../_images/concatenation-2.png

To concatenate heatmaps horizontally, simply use the add operator +.

>>> (h1 + h2).render()
../_images/concatenation-3.png

But if the heatmaps appear too close together, you can add space between them by including a number:

>>> (h1 + .2 + h2).render()
../_images/concatenation-4.png

For vertical concatenation, use the divide operator /:

>>> (h1 / .2 / h2).render()
../_images/concatenation-5.png

Take note that when concatenating, the width of the secondary heatmap(s) will be adjusted to match the main heatmap’s layout. For example, the width of h2 becomes 5 to match h1

Legends#

Marsilea can effectively rearrange legends from all your heatmaps.

Here, the concatenated result has legends added to the left side using the add_legends() method.

>>> c = (h1 + .2 + h2)
>>> c.add_legends()
>>> c.render()
../_images/concatenation-6.png

The example also demonstrates how to arrange multiple legends.

>>> from marsilea.plotter import MarkerMesh
>>> h1.add_dendrogram("left")
>>> h2.add_dendrogram("right")
>>> layer1 = MarkerMesh(data1 > 0.8, color='red', marker='o', label="> 0.8")
>>> layer2 = MarkerMesh(data2 > 0.5, color='orange', label="> 0.5")
>>> h1.add_layer(layer1, name='marker1')
>>> h2.add_layer(layer2, name='marker2')
>>> c = h1 + .2 + h2
>>> c.add_legends(side="right", order=["h1", "marker1", "h2", "marker2"],
...               stack_by='row', stack_size=2, align_legends='center')
>>> c.render()
../_images/concatenation-7.png

Advanced#

To get finer control over your concatenation, you can use marsilea.base.CompositeBoard, which is a cross-layout for cross-layouts instead of plots. The result of + or / operations is a marsilea.base.CompositeBoard object.

>>> c = ma.CompositeBoard(h1)
>>> c.append("bottom", h2, pad=.2)
>>> c.render()
../_images/concatenation-8.png

By default, the size of the appended heatmap will be forced to aligned with the main heatmap. You can change this behavior by setting align=False:

>>> c = ma.CompositeBoard(h1, align_main=False)
>>> c.append("bottom", h2, pad=.2)
>>> c.render()
../_images/concatenation-9.png

If you want to keep the legends within each heatmap, you can set keep_legends=True:

>>> c = ma.CompositeBoard(h1, keep_legends=True)
>>> c.append("bottom", h2, pad=.2)
>>> c.render()
../_images/concatenation-10.png