ponnhide / patchworklib

Patchwork for matplotlib: A subplot manager for intuitive layouts in matplotlib, seaborn, and plotnine.
GNU General Public License v3.0
382 stars 25 forks source link

Iteratively generate plots and combine #19

Closed kyaki closed 2 years ago

kyaki commented 2 years ago

Hello!

I am currently working on some code whereby I iteratively generate a list of plots using plotnine and I want to also be able to combine them all into one figure. Depending on when I run this code there may be a variable number of plots, and so I can not use the basic syntax of patchworklib.

So my question is if there is a way with patchworklib to combine a list of plots together, instead of having to specify individual plot objects (ie "plot1 | plot2"). There doesn't seem to be a lot of options to do this using plotnine, but prefer it over the murky waters of matplotlib.

Thanks for any help! Kurt

ponnhide commented 2 years ago

Thank you for using Patchworklib ! The simplest way to accomplish your request is to use the patchworklib.stack method. (I'm really sorry that I do not have the articulated API document of patchworklib yet, I will make it as soon as possible) Please refer to the following example code.

import patchworklib as pw
ax_list1 = []
for i in range(5):
    ax_list1.append(pw.Brick(figsize=(2,2), label="ax{}".format(i)))
ax_list2 = []
for i in range(5,10):
    ax_list2.append(pw.Brick(figsize=(2,2), label="ax{}".format(i)))

row1 = pw.stack(ax_list1, operator="|", margin=0.2)
row2 = pw.stack(ax_list2, operator="|", margin=0.2)
stacked_axes = row1/row2 
stacked_axes.savefig()

As a result, you will be able to get the figure below. download

If you face any problems, please let me know.

kyaki commented 2 years ago

Thankyou @ponnhide ! I have been a fan of patchwork in R, and was so happy to see a version of it in python to go along with plotnine! Thanks for the help.

kyaki commented 2 years ago

Hi @ponnhide !

I thought I knew what to do, but now that I am back at it I am getting an error when running your code example:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1004-5a9605d31752> in <module>
      2 ax_list1 = []
      3 for i in range(5):
----> 4     ax_list1.append(pw.Brick(figsize=(2,2), label="ax{}".format(i)))
      5 ax_list2 = []
      6 for i in range(5,10):

~/virt_envs/bioinf/lib/python3.8/site-packages/patchworklib/patchworklib.py in __init__(self, label, figsize, ax)
   2105 
   2106             if label in Brick._labelset:
-> 2107                 raise ValueError("'label' value should be unique in 'Brick._labelset'")
   2108             Brick._labelset.add(label)
   2109             self.set_label(label)

ValueError: 'label' value should be unique in 'Brick._labelset'
ponnhide commented 2 years ago

This error is caused by creating multiple Bricks objects with the same name. Could you try to remove the label argument when creating a Brick object? In that case, a unique label value is automatically specified.