diff --git a/docs/examples/Gallery/plot_oil_well.py b/docs/examples/Gallery/plot_oil_well.py index e7827c6..c1f1dfe 100644 --- a/docs/examples/Gallery/plot_oil_well.py +++ b/docs/examples/Gallery/plot_oil_well.py @@ -98,7 +98,7 @@ "150-199 °C (Light saute)", "<150 °C (Dressings)", ] -cb.hsplit(labels=oils["cooking conditions"], order=order) +cb.group_rows(oils["cooking conditions"], order=order) cb.add_left(conditions, pad=0.1) cb.add_dendrogram( "left", add_meta=False, colors=colors, linewidth=1.5, size=0.5, pad=0.02 diff --git a/docs/examples/Gallery/plot_pbmc3k.py b/docs/examples/Gallery/plot_pbmc3k.py index 8fe4c27..b764f1f 100644 --- a/docs/examples/Gallery/plot_pbmc3k.py +++ b/docs/examples/Gallery/plot_pbmc3k.py @@ -76,7 +76,7 @@ h.add_left(cell_types) h.add_bottom(gene_names) -h.hsplit(labels=cell_cat, order=["Lymphoid", "Myeloid"]) +h.group_rows(cell_cat, order=["Lymphoid", "Myeloid"]) h.add_left(mp.Chunk(["Lymphoid", "Myeloid"], ["#33A6B8", "#B481BB"]), pad=0.05) h.add_dendrogram("left", colors=["#33A6B8", "#B481BB"]) h.add_dendrogram("bottom") diff --git a/docs/examples/Gallery/plot_sc_multiomics.py b/docs/examples/Gallery/plot_sc_multiomics.py index 4e3aa77..e6ba2b0 100644 --- a/docs/examples/Gallery/plot_sc_multiomics.py +++ b/docs/examples/Gallery/plot_sc_multiomics.py @@ -58,7 +58,7 @@ "title": "% expression in group", }, ) - gene_profile.hsplit(labels=lineage_cells, order=lineage) + gene_profile.group_rows(lineage_cells, order=lineage) gene_profile.add_left(ma.plotter.Chunk(lineage, lineage_colors, padding=10)) gene_profile.add_dendrogram( "left", @@ -103,7 +103,7 @@ "title": "% expression in group", }, ) - protein_profile.hsplit(labels=lineage_cells, order=lineage) + protein_profile.group_rows(lineage_cells, order=lineage) protein_profile.add_bottom( ma.plotter.Labels(marker_names, color="#E36414", align="bottom", padding=10) ) diff --git a/docs/examples/Gallery/plot_tiobe_index.py b/docs/examples/Gallery/plot_tiobe_index.py index 8550d33..65c899e 100644 --- a/docs/examples/Gallery/plot_tiobe_index.py +++ b/docs/examples/Gallery/plot_tiobe_index.py @@ -27,8 +27,18 @@ # --------- data = { - "Programming Language": ["Python", "C++", "C", "Java", "C#", "JavaScript", - "Go", "Visual Basic", "Fortran", "SQL"], + "Programming Language": [ + "Python", + "C++", + "C", + "Java", + "C#", + "JavaScript", + "Go", + "Visual Basic", + "Fortran", + "SQL", + ], "Ratings": [16.12, 10.34, 9.48, 8.59, 6.72, 3.79, 2.19, 2.08, 2.05, 2.04], } data = pd.DataFrame(data).set_index("Programming Language") @@ -50,8 +60,10 @@ # Plot c = ma.ZeroWidth(5) c.add_right(mp.Image([images[lang] for lang in data.index])) -c.add_left(mp.Labels(data.index, fontweight=600), pad=.1) -c.add_right(mp.Numbers(data['Ratings'], color="#009FBD", label="Rating"), pad=.1) -c.add_title("https://www.tiobe.com/tiobe-index/", align="left", fontsize=10, fontstyle="italic") +c.add_left(mp.Labels(data.index, fontweight=600), pad=0.1) +c.add_right(mp.Numbers(data["Ratings"], color="#009FBD", label="Rating"), pad=0.1) +c.add_title( + "https://www.tiobe.com/tiobe-index/", align="left", fontsize=10, fontstyle="italic" +) c.add_title("TIOBE Index July 2024", align="left", fontweight=600) c.render() diff --git a/docs/examples/Gallery/plot_tracks.py b/docs/examples/Gallery/plot_tracks.py index 3569087..dd9976e 100644 --- a/docs/examples/Gallery/plot_tracks.py +++ b/docs/examples/Gallery/plot_tracks.py @@ -2,6 +2,7 @@ Track Plot ========== """ + import marsilea as ma import marsilea.plotter as mp @@ -42,8 +43,14 @@ name = f"{cond}{enz}" color = colors[enz] canvas.add_bottom( - mp.Area(track, color=color, add_outline=False, alpha=1, - label=cond, label_loc="right"), + mp.Area( + track, + color=color, + add_outline=False, + alpha=1, + label=cond, + label_loc="right", + ), size=TRACK_HEIGHT, pad=TRACK_PAD, name=name, diff --git a/docs/examples/Plotters/plot_chunk.py b/docs/examples/Plotters/plot_chunk.py index 022b012..032200f 100644 --- a/docs/examples/Plotters/plot_chunk.py +++ b/docs/examples/Plotters/plot_chunk.py @@ -14,7 +14,7 @@ h = ma.Heatmap(matrix) chunk = ["C1", "C2", "C3", "C4"] labels = np.random.choice(chunk, size=20) -h.hsplit(labels=labels, order=chunk) +h.group_rows(labels, order=chunk) h.add_right(Chunk(chunk, bordercolor="gray"), pad=0.1) h.add_dendrogram("left") h.render() diff --git a/docs/examples/Plotters/plot_emoji.py b/docs/examples/Plotters/plot_emoji.py index 5c3b931..a2ad470 100644 --- a/docs/examples/Plotters/plot_emoji.py +++ b/docs/examples/Plotters/plot_emoji.py @@ -8,11 +8,10 @@ # %% -from marsilea.plotter import Emoji - # %% -import numpy as np import matplotlib.pyplot as plt +from marsilea.plotter import Emoji + _, ax = plt.subplots() Emoji("😆😆🤣😂😉😇🐍🦀🦄").render(ax) diff --git a/docs/examples/Plotters/plot_fixed_chunk.py b/docs/examples/Plotters/plot_fixed_chunk.py index 40641c2..dcf158a 100644 --- a/docs/examples/Plotters/plot_fixed_chunk.py +++ b/docs/examples/Plotters/plot_fixed_chunk.py @@ -15,7 +15,7 @@ h = ma.Heatmap(matrix) chunk = ["C1", "C2-1", "C2-2", "C4"] labels = np.random.choice(chunk, size=20) -h.hsplit(labels=labels, order=chunk) +h.group_rows(labels, order=chunk) h.add_right(FixedChunk(chunk, bordercolor="gray"), pad=0.1) h.add_right( FixedChunk( diff --git a/docs/examples/Plotters/plot_image.py b/docs/examples/Plotters/plot_image.py index f394692..ca1c6d1 100644 --- a/docs/examples/Plotters/plot_image.py +++ b/docs/examples/Plotters/plot_image.py @@ -8,15 +8,17 @@ # %% -from marsilea.plotter import Image - # %% -import numpy as np import matplotlib.pyplot as plt +from marsilea.plotter import Image + _, ax = plt.subplots() -Image([ - "https://www.iconfinder.com/icons/4375050/download/png/512", - "https://www.iconfinder.com/icons/8666426/download/png/512", - "https://www.iconfinder.com/icons/652581/download/png/512" -], align="right").render(ax) +Image( + [ + "https://www.iconfinder.com/icons/4375050/download/png/512", + "https://www.iconfinder.com/icons/8666426/download/png/512", + "https://www.iconfinder.com/icons/652581/download/png/512", + ], + align="right", +).render(ax) diff --git a/docs/examples/Plotters/plot_labels.py b/docs/examples/Plotters/plot_labels.py index 47828ad..824279b 100644 --- a/docs/examples/Plotters/plot_labels.py +++ b/docs/examples/Plotters/plot_labels.py @@ -15,6 +15,6 @@ _, ax = plt.subplots(figsize=(0.5, 6)) data = np.random.randint(0, 10, 30) -l = Labels(data) -l.set_side("right") -l.render(ax) +labels = Labels(data) +labels.set_side("right") +labels.render(ax) diff --git a/docs/how_to/legends/plot_custom_legend.py b/docs/how_to/legends/plot_custom_legend.py index ad9940d..b15b5fc 100644 --- a/docs/how_to/legends/plot_custom_legend.py +++ b/docs/how_to/legends/plot_custom_legend.py @@ -10,15 +10,21 @@ # %% import numpy as np + import marsilea as ma -from marsilea.plotter import ColorMesh, Colors data = np.random.randint(0, 10, (10, 10)) # %% from legendkit import cat_legend -def my_legend(): return cat_legend(labels=["my super legend"], colors=["lightblue"], title="My Legend") + + +def my_legend(): + return cat_legend( + labels=["my super legend"], colors=["lightblue"], title="My Legend" + ) + h = ma.Heatmap(data, width=3, height=3) h.custom_legend(my_legend) diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst index 505e5b1..cda4cb6 100644 --- a/docs/source/api/index.rst +++ b/docs/source/api/index.rst @@ -9,124 +9,147 @@ Declarative API Cheat Sheet .. list-table:: :header-rows: 1 + :widths: 10 50 50 * - Operator - - Description + - Showcase - Example - * - :meth:`~marsilea.base.WhiteBoard.add_layer` - - Add a plotter to main canvas. + + * - | :meth:`~marsilea.base.WhiteBoard.add_layer` + | Add a plotter to main canvas. + - .. image:: ../img/api_add_layer.png - .. code-block:: python wb.add_layer(ColorMesh(data)) - * - :meth:`~marsilea.base.WhiteBoard.add_left` - - Add to the **left-side** of main canvas. + * - | :meth:`~marsilea.base.WhiteBoard.add_left` + | Add to the **left-side** of main canvas. + - .. image:: ../img/api_add_left.png - .. code-block:: python wb.add_left(Numbers(data), size=1, pad=.1, name='left-plot') - * - :meth:`~marsilea.base.WhiteBoard.add_right` - - Add a plotter to the **right-side** of main canvas. + * - | :meth:`~marsilea.base.WhiteBoard.add_right` + | Add a plotter to the **right-side** of main canvas. + - .. image:: ../img/api_add_right.png - .. code-block:: python wb.add_right(Numbers(data)) - * - :meth:`~marsilea.base.WhiteBoard.add_top` - - Add a plotter to the **top-side** of main canvas. + * - | :meth:`~marsilea.base.WhiteBoard.add_top` + | Add a plotter to the **top-side** of main canvas. + - .. image:: ../img/api_add_top.png - .. code-block:: python wb.add_top(Numbers(data)) - * - :meth:`~marsilea.base.WhiteBoard.add_bottom` - - Add a plotter to the **bottom-side** of main canvas. + * - | :meth:`~marsilea.base.WhiteBoard.add_bottom` + | Add a plotter to the **bottom-side** of main canvas. + - .. image:: ../img/api_add_bottom.png - .. code-block:: python wb.add_bottom(Numbers(data)) - * - :meth:`~marsilea.base.WhiteBoard.add_title` - - Add titles to the plot. + * - | :meth:`~marsilea.base.WhiteBoard.add_title` + | Add titles to the plot. + - .. image:: ../img/api_add_title.png - .. code-block:: python - wb.add_title(top='Top Title', bottom='Bottom Title' - left='Left Title', right='Right Title') + wb.add_title(top='Top', bottom='Bottom' + left='Left', right='Right') - * - :meth:`~marsilea.base.ClusterBoard.add_dendrogram` - - Add a dendrogram to the plot, only available to ClusterBoard. + * - | :meth:`~marsilea.base.ClusterBoard.add_dendrogram` + | Add a dendrogram to the plot, only available to ClusterBoard. + - .. image:: ../img/api_add_dendrogram.png - .. code-block:: python - cb.add_dendrogram("left", data) + cb.add_dendrogram("right") - * - :meth:`~marsilea.base.ClusterBoard.group_cols` - - Split the main canvas horizontally, only available to ClusterBoard. + * - | :meth:`~marsilea.base.ClusterBoard.group_cols` + | Split the main canvas vertically by labeling columns, only available to ClusterBoard. + - .. image:: ../img/api_group_cols.png - .. code-block:: python - cb.group_cols(labels=[1, 1, 2, 2], order=[2, 1]) + cb.group_cols(list("11223")) - * - :meth:`~marsilea.base.ClusterBoard.group_rows` - - Split the main canvas vertically, only available to ClusterBoard. + * - | :meth:`~marsilea.base.ClusterBoard.group_rows` + | Split the main canvas horizontally by labeling rows, only available to ClusterBoard. + - .. image:: ../img/api_group_rows.png - .. code-block:: python - cb.group_rows(labels=[1, 1, 2, 2], order=[2, 1]) + cb.group_rows(list("11223")) - * - :meth:`~marsilea.base.ClusterBoard.cut_cols` - - Split the main canvas horizontally, only available to ClusterBoard. + * - | :meth:`~marsilea.base.ClusterBoard.cut_cols` + | Split the main canvas vertically by positions, only available to ClusterBoard. + - .. image:: ../img/api_cut_cols.png - .. code-block:: python - cb.cut_cols([5]) + cb.cut_cols([2, 4]) - * - :meth:`~marsilea.base.ClusterBoard.cut_rows` - - Split the main canvas vertically, only available to ClusterBoard. + * - | :meth:`~marsilea.base.ClusterBoard.cut_rows` + | Split the main canvas horizontally by positions, only available to ClusterBoard. + - .. image:: ../img/api_cut_rows.png - .. code-block:: python - cb.cut_rows([5]) + cb.cut_rows([2, 4]) - * - :meth:`~marsilea.base.LegendMaker.add_legends` - - Add legends to the plots. + * - | :meth:`~marsilea.base.LegendMaker.add_legends` + | Add legends to the plots. + - .. image:: ../img/api_add_legends.png - .. code-block:: python wb.add_legends() - * - :meth:`~marsilea.base.WhiteBoard.add_canvas` - - Add a plotter to a chosen side of main plot. + * - | :meth:`~marsilea.base.WhiteBoard.add_canvas` + | Add a empty canvas to a chosen side of main plot. + - .. image:: ../img/api_add_canvas.png - .. code-block:: python - wb.add_canvas("right", Numbers(data)) + wb.add_canvas("right") - * - :meth:`~marsilea.base.WhiteBoard.add_pad` - - Add white space between plot. + * - | :meth:`~marsilea.base.WhiteBoard.add_pad` + | Add white space between plot. + - --- - .. code-block:: python wb.add_pad("right", 1) - * - :meth:`~marsilea.base.WhiteBoard.set_margin` - - Add white space surrounding the figure. + * - | :meth:`~marsilea.base.WhiteBoard.set_margin` + | Add white space surrounding the figure. + - --- - .. code-block:: python wb.set_margin(1) - * - :meth:`~marsilea.base.WhiteBoard.render` - - Render the plot. + + * - | :meth:`~marsilea.base.WhiteBoard.render` + | Render the plot. + - --- - .. code-block:: python wb.render() - * - :meth:`~marsilea.base.WhiteBoard.save` - - Save the plot to a file. + + * - | :meth:`~marsilea.base.WhiteBoard.save` + | Save the plot to a file. + - --- - .. code-block:: python wb.save("output.png", dpi=300) - * - :code:`+` - - Two canvas side by side, number will be added as white space + * - | :code:`+` + | Two canvas side by side, number will be added as white space + - .. image:: ../img/api_concatenate_plus.png - .. code-block:: python (wb1 + 1 + wb2).render() - * - :code:`/` - - Two canvas top and bottom, number will be added as white space + * - | :code:`/` + | Two canvas top and bottom, number will be added as white space + - .. image:: ../img/api_concatenate_divide.png - .. code-block:: python (wb1 / 1 / wb2).render() diff --git a/docs/source/tutorial/axes-level.rst b/docs/source/tutorial/axes-level.rst index c4dbea7..2a26646 100644 --- a/docs/source/tutorial/axes-level.rst +++ b/docs/source/tutorial/axes-level.rst @@ -60,7 +60,7 @@ to retrieve the named axes. :context: close-figs >>> h = ma.Heatmap(data, linewidth=1) - >>> h.hsplit(cut=[5]) + >>> h.cut_rows(cut=[5]) >>> bar = ma.plotter.Numbers(np.arange(20)) >>> h.add_right(bar, name="My Bar") >>> h.render() diff --git a/docs/source/tutorial/heatmap.rst b/docs/source/tutorial/heatmap.rst index 4ec0cd2..eebf968 100644 --- a/docs/source/tutorial/heatmap.rst +++ b/docs/source/tutorial/heatmap.rst @@ -169,7 +169,7 @@ You can easily split the heatmap into multiple groups. .. plot:: :context: close-figs - >>> h.hsplit(labels=cat, order=["A", "B", "C"]) + >>> h.group_rows(cat, order=["A", "B", "C"]) >>> h.render() diff --git a/docs/source/tutorial/intro.rst b/docs/source/tutorial/intro.rst index f8f585b..8519f8e 100644 --- a/docs/source/tutorial/intro.rst +++ b/docs/source/tutorial/intro.rst @@ -3,28 +3,19 @@ Introduction: Basic Concepts .. py:currentmodule:: marsilea -Marsilea is a powerful Python package that allows you to effortlessly -create visually appealing X-layout visualization. X-layout visualization is -designed specifically for multi-feature dataset. +Marsilea is a powerful Python package that helps you to create +composable visualizations with ease. It's built on top of Matplotlib, but you don't need to +know the details of Matplotlib to use Marsilea. This tutorial will guide you through the basic operation -for creating a x-layout visualization. +on building a composable visualization. Prerequisites ------------- This tutorial assumes that you have basic knowledge of Python, -and you know how to use NumPy and Matplotlib. - -If you are not familiar with these packages, you can check out the following links: - -- `NumPy `_ -- `Matplotlib `_ - -It's recommended that you should be familiar with -the concept of :class:`Figure ` and -:class:`Axes ` in Matplotlib. +and you have basic knowledge of `numpy `_. Create main visualization ------------------------- @@ -32,20 +23,21 @@ Create main visualization .. plot:: :context: close-figs + >>> import numpy as np >>> import marsilea as ma >>> import marsilea.plotter as mp The shorthand convention for Marsilea is :code:`ma` and for plotter is :code:`mp`. >>> data = np.random.randn(10, 6) - >>> cb = ma.ClusterBoard(data, height=2, margin=.5) + >>> cb = ma.ClusterBoard(data, height=2, margin=0.5) >>> cb.add_layer(mp.Violin(data, color="#FF6D60")) >>> cb.render() Firstly, we create a :class:`ClusterBoard ` to draw the main visualization. It's an empty canvas that allows you to append plots to it. -The canvas is initialized with height of 2 and margin of .5. +The canvas is initialized with height of 2 and margin of 0.5. The margin can be used to reserve white space around the canvas to avoid clipping of visualization when you save the plot. In Marsilea, if not specified, the unit is **inches**. @@ -68,7 +60,7 @@ Grouping >>> cb.render() We use :meth:`group_cols() ` to split the canvas into three groups. -The :code:`labels` parameter specifies the gr oup for each column. +The :code:`group` parameter specifies the gr oup for each column. The :code:`order` parameter specifies the order of the groups that will present in the plot. Let's add side plots to the groups to make it more visually distinct. Here the spacing is the fraction of the width of the canvas. @@ -107,13 +99,13 @@ Hierarchical Clustering >>> cb.add_dendrogram("bottom", colors="g") >>> cb.render() -We use :meth:`add_dendrogram() ` to +We use :meth:`add_dendrogram() ` to add a dendrogram to the bottom of the canvas. The dendrogram is a tree-like diagram that records the hierarchical clustering process. In Marsilea, the clustering can be performed on different visualizations not limited to heatmap. -Here, you may notice that the order of the order of groups and +Here, you may notice that the order of groups and the order within groups are automatically changed according to the clustering result. diff --git a/docs/source/tutorial/intro2.rst b/docs/source/tutorial/intro2.rst index 9b4ab73..9000341 100644 --- a/docs/source/tutorial/intro2.rst +++ b/docs/source/tutorial/intro2.rst @@ -1,7 +1,7 @@ Introduction: Real World Example ================================== -Now that you get a general idea of how to create x-layout visualization +Now that you get a general idea of how to create composable visualization in Marsilea. Let's apply it on a real dataset. Load Dataset @@ -83,7 +83,7 @@ We split the data into groups based on the cooking conditions. >>> order=["Control", ">230 °C (Deep-frying)", "200-229 °C (Stir-frying)", ... "150-199 °C (Light saute)", "<150 °C (Dressings)"] >>> group_color = ["#e5e7eb", "#c2410c", "#fb923c", "#fca5a5", "#fecaca"] - >>> cb.hsplit(labels=data['cooking conditions'], order=order) + >>> cb.group_rows(data['cooking conditions'], order=order) Add text to annotate the groups. diff --git a/docs/source/tutorial/new_renderplan.rst b/docs/source/tutorial/new_renderplan.rst index bb7ff2d..b4998dd 100644 --- a/docs/source/tutorial/new_renderplan.rst +++ b/docs/source/tutorial/new_renderplan.rst @@ -126,7 +126,7 @@ Now we try add it to the left again. >>> h = ma.Heatmap(data) >>> h.add_left(Lollipop(lp_data)) - >>> h.hsplit(cut=[5, 10]) + >>> h.cut_rows(cut=[5, 10]) >>> h.render()