You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Seaborn使用plt.subplots绘制jointplot子图空白、排列错误如何解决

seaborn jointplot水平排列解决方案

问题原因

  • sns.jointplot 属于Figure级别的绘图接口,本身会自动生成独立的画布和轴系,不支持传入plt.subplots()创建的普通轴对象。你提前创建的fig, axes = plt.subplots(1, 2)生成的两个轴没有被使用,就变成了顶部的空白图。
  • 每次调用sns.jointplot都会生成独立的新画布,默认按顺序垂直堆叠展示,不会自动适配你提前创建的水平子图网格,所以出现垂直排列的问题。

可直接运行的修改后代码

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

sns.set(style="darkgrid")
iris = sns.load_dataset("iris")

# 创建总画布,用gridspec划分适配jointplot结构的网格,总宽度按两个jointplot等分
fig = plt.figure(figsize=(12, 6))
gs = fig.add_gridspec(2, 6, width_ratios=[3, 1, 0.2, 3, 1, 0.2], height_ratios=[1, 3])

# 分配左侧第一个jointplot的三个轴位置:主绘图区、上侧边际分布区、右侧边际分布区
ax1_joint = fig.add_subplot(gs[1, 0:2])
ax1_marg_x = fig.add_subplot(gs[0, 0:2], sharex=ax1_joint)
ax1_marg_y = fig.add_subplot(gs[1, 2], sharey=ax1_joint)

# 分配右侧第二个jointplot的三个轴位置
ax2_joint = fig.add_subplot(gs[1, 3:5])
ax2_marg_x = fig.add_subplot(gs[0, 3:5], sharex=ax2_joint)
ax2_marg_y = fig.add_subplot(gs[1, 5], sharey=ax2_joint)

# 隐藏边际图的冗余刻度,避免重复显示
plt.setp(ax1_marg_x.get_xticklabels(), visible=False)
plt.setp(ax1_marg_y.get_yticklabels(), visible=False)
plt.setp(ax2_marg_x.get_xticklabels(), visible=False)
plt.setp(ax2_marg_y.get_yticklabels(), visible=False)

# 绘制第一个jointplot,手动指定三个轴,避免自动生成新画布
g1 = sns.JointGrid(x="sepal_width", y="sepal_length", data=iris, 
                   ax_joint=ax1_joint, ax_marg_x=ax1_marg_x, ax_marg_y=ax1_marg_y)
g1.plot_joint(sns.regplot, color='k')
g1.plot_marginals(sns.histplot, kde=True, color='k')
# 替换主绘图区为带尺寸映射的散点图
g1.ax_joint.cla()
sns.scatterplot(data=iris, x='sepal_width', y='sepal_length', 
                size='petal_length', sizes=(10, 200), ax=g1.ax_joint)

# 绘制第二个jointplot
g2 = sns.JointGrid(x="sepal_width", y="sepal_length", data=iris,
                   ax_joint=ax2_joint, ax_marg_x=ax2_marg_x, ax_marg_y=ax2_marg_y)
g2.plot_joint(sns.regplot, color='k')
g2.plot_marginals(sns.histplot, kde=True, color='k')
# 替换主绘图区为带尺寸映射的散点图
g2.ax_joint.cla()
sns.scatterplot(data=iris, x='sepal_width', y='sepal_length', 
                size='petal_width', sizes=(10, 200), ax=g2.ax_joint)

# 调整子图间距避免重叠
plt.tight_layout()
plt.show()

修改核心要点

  • 改用matplotlib.gridspec划分适配jointplot三部分(主绘图区、上下边际分布区)的网格结构,分别给两个jointplot分配左右对应的位置,实现水平排列
  • 调用底层的sns.JointGrid接口手动指定轴位置,避免接口自动生成多余画布,消除顶部空白图
  • 保留原有需求的回归拟合线、边际分布、散点尺寸映射逻辑,无需修改业务绘图逻辑

内容的提问来源于stack exchange,提问作者H42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 21:24:04