如何使用matplotlib或seaborn绘制右上角带边缘分布的联合散点/线图
斜向排布边缘分布的实现方案
seaborn 原生的 jointplot 采用固定布局(主图在左下,x变量分布在顶部、y变量分布在右侧),不支持沿主对角线方向放置边缘分布的配置。这类斜向组合图本质是自定义网格坐标系下的多轴拼接,不需要依赖 seaborn 的高层封装,结合 matplotlib 的轴定位能力、seaborn 的绘图函数即可实现,以下是两种可落地的实现路径:
手工自定义matplotlib轴布局
这是灵活度最高的实现方式,核心逻辑是独立创建三个独立坐标轴,手动调整位置实现斜向排布:
- 初始化主图坐标轴,绘制核心散点/线图,务必设置
set_aspect('equal')保证主图x、y轴比例1:1,避免斜向元素变形 - 在主图右上角的对角区域,分别插入两个小型坐标轴,承载x变量、y变量的分布密度/直方图内容
- 调整小轴的位置参数,让两个分布的延展方向对齐主图的1-3象限对角线
- 隐藏所有小轴的冗余刻度、边框,仅保留分布图形的可见元素
可运行的简化示例代码:
import matplotlib.pyplot as plt import seaborn as sns import numpy as np # 生成模拟关联数据 np.random.seed(42) x = np.random.normal(0, 1, 500) y = 0.8 * x + np.random.normal(0, 0.5, 500) # 初始化画布与主图 fig = plt.figure(figsize=(6, 6)) ax_main = fig.add_axes([0.1, 0.1, 0.8, 0.8]) ax_main.scatter(x, y, alpha=0.6, s=20) ax_main.set_xlim(-3, 3) ax_main.set_ylim(-3, 3) ax_main.set_aspect('equal') # 插入x变量的斜向分布轴 ax_xdist = fig.add_axes([0.62, 0.62, 0.25, 0.25]) sns.kdeplot(x=x, ax=ax_xdist, fill=True, alpha=0.7) ax_xdist.set_axis_off() # 插入y变量的斜向分布轴,错层避免图形重叠 ax_ydist = fig.add_axes([0.72, 0.55, 0.2, 0.2]) sns.kdeplot(y=y, ax=ax_ydist, fill=True, color="#ff7f0e", alpha=0.7) ax_ydist.set_axis_off() plt.show()
基于seaborn JointGrid的二次改造
如果习惯使用seaborn生态,不需要从零搭建布局,可以直接修改JointGrid生成的默认轴位置,大幅减少重复代码:
JointGrid初始化时会自动生成三个固定轴:主图轴ax_joint、x变量分布轴ax_marg_x、y变量分布轴ax_marg_y- 沿用
JointGrid自带的主图、边缘分布绘图逻辑,完成基础图形绘制 - 通过
set_position()方法直接调整两个边缘分布轴的坐标,从默认的顶部、右侧位置移动到主图的对角区域,调整大小到适配比例 - 隐藏边缘轴的冗余元素即可完成斜向排布
改造示例代码:
from seaborn import JointGrid import seaborn as sns import numpy as np # 生成模拟关联数据 np.random.seed(42) x = np.random.normal(0, 1, 500) y = 0.8 * x + np.random.normal(0, 0.5, 500) # 初始化JointGrid,移除默认轴之间的间距 g = JointGrid(x=x, y=y, space=0) # 绘制主图散点 g.plot_joint(sns.scatterplot, alpha=0.6) # 绘制默认的边缘密度分布 g.plot_marginals(sns.kdeplot, fill=True, alpha=0.7) # 移动x变量分布轴到对角区域 orig_pos_x = g.ax_marg_x.get_position() g.ax_marg_x.set_position([0.62, 0.62, orig_pos_x.width*0.3, orig_pos_x.height*0.3]) # 移动y变量分布轴到对角区域错层位置 orig_pos_y = g.ax_marg_y.get_position() g.ax_marg_y.set_position([0.72, 0.55, orig_pos_y.width*0.3, orig_pos_y.height*0.3]) # 隐藏边缘轴的冗余刻度与边框 g.ax_marg_x.set_axis_off() g.ax_marg_y.set_axis_off() g.fig.show()
实现注意事项
- 主图必须设置1:1的等比例坐标轴,否则沿对角线排布的分布会出现拉伸变形,无法和斜向方向对齐
- 如果需要实现沿2-4象限(y=-x方向)的分布排布,只需要将边缘轴的位置调整到对应斜向区域即可
- 如需实现带标注、分层着色的复杂斜向分布图,可以在上述基础上,结合matplotlib的旋转变换模块,对边缘分布的图形角度做精确调整,让密度曲线的延展方向完全和对角线重合
内容的提问来源于stack exchange,提问作者My Work
相关产品推荐
相关产品推荐

