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

如何将Matplotlib箱线图+直方图子图从2列改为4列?

解决Matplotlib/Seaborn 4列子图布局空白问题

问题根源

你遇到的右侧子图空白,核心是两个问题:

  1. 子图创建时的行列数计算错误,导致实际生成的子图结构和预期不匹配
  2. 循环中特征与子图索引的对应逻辑出错,只往左侧子图写入了数据,右侧的没被用到

修正后的完整代码示例

假设你用pandas处理数据,特征列表为features,每个特征对应一组箱线图+直方图,以下是4列布局的正确实现:

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

# 示例数据(替换成你的实际数据)
df = pd.DataFrame({
    'col1': np.random.normal(0, 1, 100),
    'col2': np.random.normal(5, 2, 100),
    'col3': np.random.uniform(0, 10, 100),
    'col4': np.random.exponential(1, 100),
    'col5': np.random.normal(-2, 3, 100),
    'col6': np.random.uniform(-5, 5, 100)
})
features = list(df.columns)

# 设置4列布局
ncols = 4
n_features = len(features)
# 计算所需行数:每个特征占2个子图,总子图数是n_features*2,行数=总子图数//列数,有余数则加1
total_subplots = n_features * 2
nrows = (total_subplots + ncols - 1) // ncols

# 创建子图网格,转成一维数组方便索引
fig, axs = plt.subplots(nrows, ncols, figsize=(18, 5*nrows))
axs = axs.flatten()

# 循环绘制:每行放2组(箱线+直方),共4个子图
for row_idx in range(nrows):
    # 当前行处理的特征:每行2个特征
    feature_start = row_idx * 2
    current_features = features[feature_start : feature_start + 2]
    
    # 第一个特征的子图位置
    if len(current_features) >= 1:
        box_ax = axs[row_idx * ncols]
        hist_ax = axs[row_idx * ncols + 1]
        
        sns.boxplot(data=df, x=current_features[0], ax=box_ax)
        box_ax.set_title(f'箱线图:{current_features[0]}')
        hist_ax.hist(df[current_features[0]].dropna(), bins=20)
        hist_ax.set_title(f'直方图:{current_features[0]}')
    
    # 第二个特征的子图位置
    if len(current_features) >= 2:
        box_ax2 = axs[row_idx * ncols + 2]
        hist_ax2 = axs[row_idx * ncols + 3]
        
        sns.boxplot(data=df, x=current_features[1], ax=box_ax2)
        box_ax2.set_title(f'箱线图:{current_features[1]}')
        hist_ax2.hist(df[current_features[1]].dropna(), bins=20)
        hist_ax2.set_title(f'直方图:{current_features[1]}')

plt.tight_layout()
plt.show()

关键注意事项

  • 子图数组扁平化:一定要用axs.flatten()把二维的子图数组转成一维,不然直接用axs[row_idx * ncols]会索引错误(二维数组需要用axs[row, col]格式)
  • 行列数计算准确:总子图数是特征数×2,行数要根据总子图数和4列来计算,避免生成多余或不足的子图
  • 指定绘图的ax对象:所有绘图函数(sns.boxplot、plt.hist)必须通过ax参数指定子图,否则会默认画到最后一个子图里

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:05:30