Project Icon

patchworklib

用于组合和对齐matplotlib生态图表的Python库

patchworklib是一个Python库,用于组合和对齐matplotlib、Seaborn和plotnine等生态系统中的图表。它通过简单的'/'和'|'运算符实现不同类型图表的灵活排列。该库能将各种seaborn和plotnine图表作为matplotlib子图处理,解决了图表排版耗时的问题。patchworklib为创建复杂图表布局提供了直观的方法,提高了数据可视化效率。

patchworklib

Patchworklib是一个通用的matplotlib相关绘图组合器(包括简单的matplotlib绘图、Seaborn绘图(轴级和图形级)以及plotnine绘图)。这个库的灵感来自ggplot2的patchwork。因此,与原始的patchwork一样,用户可以仅使用"/"和"|"运算符轻松对齐matplotlib绘图。虽然matplotlib正式提供了一个不错的子图组合器"subplot_mosaic",但我认为patchworklib的方式更直观、更灵活。

此外,许多基于matplotlib的第三方库,如plotnine和seaborn,提供了使用简单Python代码生成漂亮图表的功能,但这些图表中的许多不能作为matplotlib子图处理。因此,它们的位置必须手动调整。现在,科学家们花费宝贵的时间来排列图表。

Patchworklib为这个问题提供了解决方案。通过使用patchworklib,任何类型的seaborn和plotnine绘图都可以作为matplotlib子图处理。

加入我们的团队:诚聘生物信息学研究员

我们目前正在寻找一位有生物信息学专业知识的熟练研究员加入我们的实验室。 有关更多详情和申请,请访问以下网址

安装

对于普通用户,我们建议您按以下方式安装官方发布版: pip install patchworklib

如果您想使用开发版本,可以使用以下单个命令安装: pip install git+https://github.com/ponnhide/patchworklib.git

新闻

2023年10月23日:版本0.6.3发布。

  • 现在支持Seaborn v0.13.0。
  • 我已确认patchworklib仍适用于plotnine v0.12.3。

2023年5月16日:版本0.6.1发布。

  • 我无法完全支持plotnine版本0.12.1(它可以工作,但patchworklib的排列结果不如预期)。也许,我将来不会支持plotnine。
  • Bricks对象获得了新方法align_xlabelsalign_ylabels,这有助于用户对齐给定Brick对象的x/y标签。
  • 在stack函数中添加了新参数equal_spacing。如果此值为True,轴边界框应以相等的间距放置。否则,根据x/y刻度标签和x/y标签的文本值,它们可能并不总是等距排列。
  • 关闭并可能解决了问题"当子图轴对齐时对齐Bricks的标签。 #40"
  • 关闭并可能解决了问题"不适用于Plotnine Seaborn主题。 #37"
  • 关闭并可能解决了问题"在plotnine中无法设置标题位置。 #36"

更新日志

2022年12月8日:版本0.5.0发布。

  • 添加了新的运算符"+"和"-"。
  • 现在支持plotnine > v0.10.x。
  • 现在patchworklib可以处理由面向对象的seaborn接口生成的图表。
  • 在此存储库中添加了patchworklib提供的每个函数和类的描述。如果您想详细了解如何使用patchworklib,请参阅API.md
  • 更新了patchworklib-examples

2022年8月15日:版本0.4.7发布。

  • 修复了一些错误。
  • 添加了inset函数。请参见以下示例。
  • hstackvstack函数中添加了keep_aspect参数。
  • 示例代码已移至patchworklib-examples
创建嵌入元素
import patchworklib as pw
from plotnine import *
from plotnine.data import *

g1  = pw.load_ggplot(ggplot(mtcars) + geom_point(aes("mpg", "disp")),figsize=(4, 2))
g2  = pw.load_ggplot(ggplot(mtcars) + geom_boxplot(aes("gear", "disp", group = "gear")) + theme_classic())
g12 = pw.inset(g1,g2)
g12.savefig()
g12 = pw.inset(g1,g2, loc="lower left", hratio=0.4, wratio=0.2)
g12.savefig("inset_plotnine2.png")

2022年8月9日:版本0.4.6发布。

  • 修复了一些错误(请参见问题#18)。
  • 提高了绘图速度。

2022年7月20日:版本0.4.5发布。

  • 修复了一些错误。
  • 修改了与ggplot主题继承相关的函数。如果您使用patchworklib处理plotnine图表,请务必更新。
  • 在Bricks对象中指定绘图(Brick对象)时,您现在可以直接指定Brick对象,而不是Brick对象的标签名称。请参见以下示例。
通过在Bricks对象中指定Brick对象来对齐plotnine图表。
import patchworklib as pw
from plotnine import *
from plotnine.data import *

g1 = pw.load_ggplot(ggplot(mpg, aes(x='cty', color='drv', fill='drv')) +
                    geom_density(aes(y=after_stat('count')), alpha=0.1) +
                    scale_color_discrete(guide=False) +
                    theme(axis_ticks_major_x=element_blank(),
                          axis_text_x =element_blank(),
                          axis_title_x=element_blank(),
                          axis_text_y =element_text(size=12),
                          axis_title_y=element_text(size=14),
                          legend_position="none"),
                    figsize=(4,1))

g2 = pw.load_ggplot(ggplot(mpg, aes(x='hwy', color='drv', fill='drv')) +
                    geom_density(aes(y=after_stat('count')), alpha=0.1) +
                    coord_flip() +
                    theme(axis_ticks_major_y=element_blank(),
                          axis_text_y =element_blank(),
                          axis_title_y=element_blank(),
                          axis_text_x =element_text(size=12),
                          axis_title_x=element_text(size=14)
                         ),
                    figsize=(1,4))

g3 = pw.load_ggplot(ggplot(mpg) +
                    geom_point(aes(x="cty", y="hwy", color="drv")) +
                    scale_color_discrete(guide=False) +
                    theme(axis_text =element_text(size=12),
                          axis_title=element_text(size=14)
                         ),
                    figsize=(4,4))

pw.param["margin"] = 0.2
(g1/(g3|g2)[g3]).savefig() #通过在(g3|g2)中指定g3,g1正好定位在g3上。

2022年7月19日:版本0.4.3发布。

  • 修复了一些错误。
  • 添加了basefigure参数。您可以通过patchworklib.basefigure访问patchworklib的基本图形。
  • 现在支持plotnine v0.9.0。可能仍存在一些错误。如果您发现错误,请在问题中告诉我。

2022年4月22日:版本0.4.2发布。

  • 修复了一些错误。

2022年4月18日:版本0.4.1发布。

  • load_seaborngrid 现可接受 seaborn.clustermap 图表。详情请参见 Google Colab 上的示例代码。
  • 修复了一些bug。

2022年3月27日:版本0.4.0发布。

  • 为每个方法和类添加了文档字符串。
  • patchworklib.Bricks 类添加了几个新方法,用于为 Bricks 对象中的 Brick 对象设置通用标签、标题、轴线和颜色条。 使用方法请参考文档字符串或 Google Colab 上的示例代码。

2022年2月4日:版本0.3.6发布。

  • 修复了与排列多个极坐标图对象相关的一些bug。

2022年2月4日:版本0.3.5发布。

  • 修复了 move_legend 中的一些bug。(seaborn网格图的 move_legend 功能无法正常工作。)
  • 提高了 savefig 操作的速度。

2022年1月24日:版本0.3.3发布。

  • 修复了一些bug。

2022年1月22日:版本0.3.0发布。

Patchworklib 现在支持排列 matplotlib.projections.polar.PolarAxes 对象的功能。

当您将 matplotlib.projections.polar.PolarAxes 对象加载为 Brick 类对象时,请使用 'cBrick' 而不是 'Brick'。 现在,您可以使用 pycircos 和 patchworklib 排列多个圆形图。请参阅以下示例代码。 https://colab.research.google.com/drive/1tkn7pxRqh9By5rTFqRbVNDVws-o-ySz9?usp=sharing

2022年1月21日:版本0.2.1发布。

  • 修复了 'load_seaborngrid' 的一些bug。

2022年1月20日:版本0.2.0发布。

Patchworklib 现在可以排列 Seaborn 网格图。添加了 "stack" 功能。修复了一些bug。

排列 Seaborn 网格图

Patchworklib 支持排列基于 axisgrid(FacetGrid、PairGrid 和 JointGrid)生成的多个 Seaborn 图表。 让我们看看以下示例。

import os
import seaborn as sns
import patchworklib as pw
from functools import reduce
pw.overwrite_axisgrid() #使用 pw.load_seagorngrid 时,应执行 'overwrite_axisgrid'。

df = sns.load_dataset("penguins")
g1  = sns.pairplot(df, hue="species")
g1  = pw.load_seaborngrid(g1)
g1.move_legend("upper left", bbox_to_anchor=(0.08,1.01))

planets = sns.load_dataset("planets")
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
g2 = sns.relplot(
    data=planets,
    x="distance", y="orbital_period",
    hue="year", size="mass",
    palette=cmap, sizes=(10, 200),
)
g2.set(xscale="log", yscale="log")
g2.ax.xaxis.grid(True, "minor", linewidth=.25)
g2.ax.yaxis.grid(True, "minor", linewidth=.25)
g2.despine(left=True, bottom=True)
g2 = pw.load_seaborngrid(g2)

penguins = sns.load_dataset("penguins")
g3 = sns.jointplot(
    data=penguins,
    x="bill_length_mm", y="bill_depth_mm", hue="species",
    kind="kde",
)
g3 = pw.load_seaborngrid(g3, labels=["joint","marg_x","marg_y"])
((g2/g3["marg_x"])|g1).savefig()

此外,一些示例代码可在 Google Colaboratory 上执行。

"stack" 功能

我实现了 stack 功能。此功能允许用户沿指定方向排列多个(两个以上)Brick 或 Bricks 对象,如下所示。

import patchworklib as pw
ax_list = []
for i in range(10):
    ax_list.append(pw.Brick(figsize=(2,2), label="ax{}".format(i)))
stacked_axes = pw.stack(ax_list, operator="|", margin=0.2)
stacked_axes.savefig()

2022年1月14日:版本0.1.0发布。

  • Patchworklib 现可通过 pip 安装。
2022年1月13日:实现了 "spacer" 类,并为 Bricks 类添加了 "case" 参数。

在图表周围添加空白空间

#准备图表数据
import numpy as np 
import matplotlib as mpl
import patchworklib as pw

data1 = 20 * np.random.rand(100,100) - 10
data2 = 20 * np.random.rand(100,100) - 10
cmap = mpl.cm.Reds
norm = mpl.colors.Normalize(vmin=-10, vmax=10)
ax1 = pw.Brick("axx", figsize=(3,3))
ax2 = pw.Brick("axy", figsize=(3,3))
ax1.imshow(data1, interpolation='nearest', cmap=cmap, aspect="auto")
ax2.imshow(data2, interpolation='nearest', cmap=cmap, aspect="auto")

不使用 spacer

ax_cb    = pw.Brick("ax_cb", figsize=(0.1,3))
cb       = mpl.colorbar.ColorbarBase(ax_cb, cmap=cmap, norm=norm)
ax12     = ax1|ax2
heatmap2 = ax12 | ax_cb
heatmap2.savefig()

使用 spacer

ax_cb2   = pw.Brick("ax_cb2", figsize=(0.1,1.5))
cb2      = mpl.colorbar.ColorbarBase(ax_cb2, cmap=cmap, norm=norm)
heatmap2 = ax12 | (pw.spacer(ax_cb2,0.5)/ax_cb2/pw.spacer(ax_cb2,0.5))
heatmap2.savefig()

多个图表的总标题 有时,只需为多个图表设置通用标签和标题。 通过指定 Bricks 类对象的 case 参数,可以处理多个图表的通用 matplotlib 艺术家对象。

ax12.case.set_title("多个图表的总标题", pad=10)
heatmap2 = ax12|(pw.spacer(ax_cb,0.5)/ax_cb/pw.spacer(ax_cb,0.5))
heatmap2.savefig("")
01072022: Patchworklib 已更新,以支持排列多个由 plotnine 生成的图表。
import patchworklib as pw
from plotnine import *
from plotnine.data import *
g1 = pw.load_ggplot(ggplot(mtcars) + geom_point(aes("mpg", "disp")) + theme(figure_size=(2, 3)))
g2 = pw.load_ggplot(ggplot(mtcars) + geom_boxplot(aes("gear", "disp", group = "gear")) + theme(figure_size=(2, 3)))
g12 = g1 | g2
g12.savefig()
g3 = pw.load_ggplot(ggplot(mpg, aes(x='displ', y='hwy')) + geom_point() + geom_smooth(span=.3) + theme(figure_size=(2, 3)))
g4 = pw.load_ggplot(ggplot(mtcars) + geom_bar(aes("carb")) + theme(figure_size=(7, 2)))
g1234 = (g1|g2|g3)/g4
g1234.savefig()

使用方法

如果您想详细了解如何使用 patchworklib,请参阅 API.md

使用 patchworklib,您可以仅使用 |/ 运算符快速自由地排列 matplotlib 图表,如下所示。

import patchworklib as pw
import seaborn as sns 

fmri = sns.load_dataset("fmri")
ax1 = pw.Brick(figsize=(3,2))
sns.lineplot(x="timepoint", y="signal", hue="region", style="event", data=fmri, ax=ax1)
ax1.legend(bbox_to_anchor=(1.05, 1.0), loc='upper left')
ax1.set_title("ax1")
 
titanic = sns.load_dataset("titanic")
ax2 = pw.Brick(figsize=(1,2))
sns.barplot(x="sex", y="survived", hue="class", data=titanic, ax=ax2)
ax2.move_legend(new_loc='upper left', bbox_to_anchor=(1.05, 1.0))
ax2.set_title("ax2")

ax12 = ax1|ax2
ax12.savefig("ax12.png")

所有示例代码的 Jupyter Notebook 文件都可以在 patchworklib-examples 中找到,并且可以在 Google Colaboratory 中执行。

图库

多个轴级 seaborn 图表的排列

多个 Plotnine 图表的排列

多个图级 seaborn 图表的排列

入门

示例代码

教程 ~组合多个 seaborn 图表~ 以下教程代码可在 tutorial1 中执行

1. 导入 patchworklib 库

import patchworklib as pw 
fmri = sns.load_dataset("fmri")
ax1 = pw.Brick("ax1", figsize=(4,2))
sns.lineplot(x="timepoint", y="signal", hue="region", style="event", data=fmri, ax=ax1)
ax1.move_legend(new_loc='upper right')
ax1.set_title("ax1")

2. 创建示例图表

使用 seaborn 模块创建一些示例图表。patchworklib 模块提供的 Brick 类是 matplotlib.axes.Axes 的子类。因此,Brick 类对象可以传递给具有 ax 参数的 seaborn 绘图函数。

在创建 Brick 类对象时,应指定 label 值,并且它在 Python 脚本中生成的 Brick 类对象中应是唯一的(如果未指定 label 值,则会自动给出唯一的标签名称。可以使用 get_label() 方法确认该值)。还可以指定 figsize 参数。但是,该值并不是很重要,因为在排列图表时,Brick 类对象的图形大小可以自动调整。savefig(filename=str) 方法返回 matplotlib.figure.Figure 类对象。如果给定 filename,则可以将图形对象输出到文件。

import seaborn as sns
#示例图表 1(参考:https://seaborn.pydata.org/examples/errorband_lineplots.html)
fmri = sns.load_dataset("fmri")
ax1 = pw.Brick("ax1", figsize=(4,2))
sns.lineplot(x="timepoint", y="signal", hue="region", style="event", data=fmri, ax=ax1)
ax1.move_legend(new_loc='upper right')
ax1.set_title("ax1")
ax1.savefig()

Brick 类提供了 movelegend(loc=str, bbox_to_anchor=(float,float)) 方法。使用此方法,可以快速修改图例位置。

#示例图表 2(参考:https://seaborn.pydata.org/tutorial/categorical.html)
titanic = sns.load_dataset("titanic")
ax2 = pw.Brick("ax2", figsize=(1,2))
sns.barplot(x="sex", y="survived", hue="class", data=titanic, ax=ax2)
ax2.move_legend(new_loc='upper left', bbox_to_anchor=(1.05, 1.0)) #Brick 类的原始方法
ax2.set_title("ax2")
ax2.savefig()
#示例图3(参考:https://seaborn.pydata.org/examples/histogram_stacked.html)
diamonds = sns.load_dataset("diamonds")
ax3 = pw.Brick("ax3", (5,2))
sns.histplot(diamonds, x="price", hue="cut", multiple="stack",
    palette="light:m_r", edgecolor=".3", linewidth=.5, log_scale=True,
    ax = ax3)
ax3.set_title("ax3")
ax3.savefig()
#示例图4(参考:https://seaborn.pydata.org/examples/grouped_violinplots.html)
tips = sns.load_dataset("tips")
ax4 = pw.Brick("ax4", (6,2))
sns.violinplot(data=tips, x="day", y="total_bill", hue="smoker",
    split=True, inner="quart", linewidth=1,
    palette={"Yes": "b", "No": ".85"},
    ax=ax4)
ax4.set_title("ax4")
ax4.savefig("../img/ax4.png")
#示例图5(参考:https://seaborn.pydata.org/examples/wide_data_lineplot.html)
rs = np.random.RandomState(365)
values = rs.randn(365, 4).cumsum(axis=0)
dates = pd.date_range("1 1 2016", periods=365, freq="D")
data = pd.DataFrame(values, dates, columns=["A", "B", "C", "D"])
data = data.rolling(7).mean()
ax5 = pw.Brick("ax5", (5,2))
sns.lineplot(data=data, palette="tab10", linewidth=2.5, ax=ax5)
ax5.set_xlabel("date")
ax5.set_ylabel("value")
ax5.set_title("ax5")
ax5.savefig()

3. 排列和堆叠图表

patchworklib模块提供了两个操作符"|"和"/",可以通过简单的操作为多个图表设计整洁的布局。"|"操作符将图表并排放置,而"/"操作符将它们堆叠。

#水平排列"ax1"、"ax2"和"ax4"
ax124 = ax1|ax2|ax4
ax124.savefig("../img/ax124.png")

由多个Brick对象(Bricks类对象)排列生成的对象也可以与其他Brick对象进行排列和堆叠。此外,还可以通过嵌套操作创建更复杂的布局。

ax12435 = ax124/(ax3|ax5)
ax12435.savefig("../img/ax12435.png")

你可以通过重新排列它们来快速测试另一种布局。

ax35214 = (ax3/(ax2|ax1))|(ax5/ax4)
ax35214.savefig()

如果你想调整对象之间的边距,请更改.param["margin"]的值。

pw.param["margin"]=0.2 #默认值为0.5
ax35214 = (ax3/(ax2|ax1))|(ax5/ax4)
ax35214.savefig("../img/ax35214_v1.1.png")

此外,每个图表的宽高比可以自由修改。

pw.param["margin"]=0.5
ax1.change_aspectratio((4,2))
ax3.change_aspectratio((4,1))
ax4.change_aspectratio((5,2))
ax35214_v2 = (ax3/(ax2|ax1))|(ax5/ax4)
ax35214_v2.savefig()

4. 使用标签索引打包图表(高级方法)

通过在Bricks对象中用标签名称指定Brick对象,你可以调整要打包的另一个Brick对象的位置。

ax321 = ax3/(ax2|ax1)
ax321.savefig("../img/ax321.png")
ax3214 = ax321["ax1"]|ax4
ax3214.savefig("../img/ax3214.png")
ax35214_v3 = ax3214["ax3"]|ax5
ax35214_v3.savefig("../img/ax35214_v3.png")

上述打包过程允许对象的坐标轴精确对齐。实际上,在"ax35214"和"ax35214_v2"中,ax3和ax5的底部坐标轴线并不完全对齐,而在"ax35214_v3"中,它们的底部坐标轴线完全对齐。但请注意,这种使用标签索引的打包方法会改变要打包的Brick对象的宽高比,以使其坐标轴线与其他对象对齐。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

稿定AI

稿定设计 是一个多功能的在线设计和创意平台,提供广泛的设计工具和资源,以满足不同用户的需求。从专业的图形设计师到普通用户,无论是进行图片处理、智能抠图、H5页面制作还是视频剪辑,稿定设计都能提供简单、高效的解决方案。该平台以其用户友好的界面和强大的功能集合,帮助用户轻松实现创意设计。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号