如何在Seaborn jointplot下方添加共享x轴的原生Matplotlib子图
实现方案
可以实现,核心思路是提前用Matplotlib的GridSpec定义整幅图的全局布局,再将Seaborn JointGrid的坐标轴绑定到预定义的网格位置上,即可实现高度比例自定义、x轴自动共享、所有元素自动对齐的效果。
完整可运行代码如下:
import matplotlib.pyplot as plt import seaborn as sns from matplotlib.gridspec import GridSpec # 加载数据集 diamonds = sns.load_dataset('diamonds') # 定义总画布与全局网格,3行高度比例对应3:1:1 fig = plt.figure(figsize=(7, 10)) global_gs = GridSpec(3, 1, figure=fig, height_ratios=[3, 1, 1], hspace=0.1) # 第一行网格拆分出JointGrid需要的主图+右侧边际y图布局 joint_gs = global_gs[0].subgridspec(1, 2, width_ratios=[5, 1], wspace=0.05) ax_main = fig.add_subplot(joint_gs[0, 0]) ax_marg_y = fig.add_subplot(joint_gs[0, 1], sharey=ax_main) # 初始化JointGrid并绑定预创建的坐标轴 g = sns.JointGrid( data=diamonds, x="carat", y="price", hue="cut", xlim=(1, 2), ax=ax_main ) g.ax_marg_y = ax_marg_y # 移除不需要的顶部x边际图 g.ax_marg_x.remove() # 绘制jointplot内容 g.plot_joint(sns.scatterplot) g.plot_marginals(sns.kdeplot, fill=True) # 创建下方两个共享x轴的子图 ax_depth = fig.add_subplot(global_gs[1], sharex=ax_main) ax_table = fig.add_subplot(global_gs[2], sharex=ax_main) # 绘制下方散点图 ax_depth.scatter(x=diamonds["carat"], y=diamonds["depth"], color="gray", edgecolor="black") ax_depth.set_ylabel("depth") # 隐藏上方子图的x轴刻度避免重复 plt.setp(ax_depth.get_xticklabels(), visible=False) ax_table.scatter(x=diamonds["carat"], y=diamonds["table"], color="gray", edgecolor="black") ax_table.set_xlabel("carat") ax_table.set_ylabel("table") plt.show()
调整说明
- 可修改
GridSpec的height_ratios参数自定义三个区域的高度比例 - 可调整
hspace、wspace参数修改子图之间的间距 - 所有子图x轴自动共享对齐,不会受边际KDE曲线的尺寸变化影响
内容的提问来源于stack exchange,提问作者a11
相关产品推荐
相关产品推荐

