如何合并两个Seaborn FacetGrid绘图?
如何合并两个Seaborn FacetGrid绘图到单个PDF
当然可以合并!直接用fig.axes.append导致重叠的原因是:每个FacetGrid自带独立的Figure和Axes布局,直接追加Axes不会自动调整它们的位置。下面给你两种可行的Python实现方案,完全不需要外部工具。
方案一:提前规划布局,在同一个Figure中生成两个FacetGrid
这种方法更简洁,从一开始就统一管理整个绘图的布局,避免后续迁移Axes的麻烦:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import seaborn as sns # 加载数据集 iris = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv') melted_iris = pd.melt(iris.loc[:,['sepal_length','sepal_width','species']], id_vars='species') # 创建一个大的Figure,并通过GridSpec规划布局 fig = plt.figure(figsize=(12, 8)) # 第一行:2个子图(对应第一个FacetGrid的两个特征变量) gs_top = gridspec.GridSpec(1, 2, figure=fig) # 第二行:3个子图(对应第二个FacetGrid的三个鸢尾花品种) gs_bottom = gridspec.GridSpec(1, 3, figure=fig) # 调整第二行的上下位置,避免和第一行重叠 gs_bottom.update(top=0.45, bottom=0.05) # 生成第一个FacetGrid,指定使用顶部的GridSpec布局 g1 = sns.FacetGrid(melted_iris, col='variable', ax=gs_top) # 注意:你之前拼写的virginia是错误的,正确品种名是virginica g1.map(sns.boxplot, 'species','value', order=['setosa','versicolor','virginica']) # 生成第二个FacetGrid,指定使用底部的GridSpec布局 g2 = sns.FacetGrid(iris, col="species", ax=gs_bottom) g2.map(plt.scatter, "sepal_length", "sepal_width") # 自动调整子图间距 plt.tight_layout() # 保存为PDF文件 fig.savefig('combined_iris_plots.pdf') plt.show()
方案二:迁移已生成的FacetGrid到新Figure
如果你已经生成了两个独立的FacetGrid(g1和g2),可以通过迁移Axes的方式合并到同一个Figure中:
import pandas as pd import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import seaborn as sns # 加载数据并生成两个独立的FacetGrid iris = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv') melted_iris = pd.melt(iris.loc[:,['sepal_length','sepal_width','species']], id_vars='species') g1 = sns.FacetGrid(melted_iris, col='variable') g1.map(sns.boxplot, 'species','value', order=['setosa','versicolor','virginica']) g2 = sns.FacetGrid(iris, col="species") g2.map(plt.scatter, "sepal_length", "sepal_width") # 创建新的统一Figure fig = plt.figure(figsize=(12, 8)) # 规划2行3列的布局:第一行用前2个位置,第二行用全部3个位置 gs = gridspec.GridSpec(2, 3, figure=fig) # 迁移g1的Axes到新Figure for idx, ax in enumerate(g1.axes.flatten()): ax.remove() # 从原Figure移除Axes ax.figure = fig # 绑定到新Figure fig.add_axes(ax) # 添加到新Figure ax.set_position(gs[0, idx].get_position(fig)) # 设置新位置 # 迁移g2的Axes到新Figure for idx, ax in enumerate(g2.axes.flatten()): ax.remove() ax.figure = fig fig.add_axes(ax) ax.set_position(gs[1, idx].get_position(fig)) # 调整布局并保存 plt.tight_layout() fig.savefig('combined_iris_plots.pdf') plt.show()
关键说明
- 两种方案都通过
matplotlib.gridspec.GridSpec来精确控制每个子图的位置,避免重叠。 - 注意你代码中的拼写错误:鸢尾花品种
virginica被写成了virginia,修正后才能正常运行。
内容的提问来源于stack exchange,提问作者user3521099
相关产品推荐
相关产品推荐

