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

如何基于各分类hue数量调整Seaborn小提琴图尺寸消除空白

问题描述

我需要基于两个分类变量绘制小提琴图,但部分分类组合在数据中不存在,导致绘图时出现空白区域。之前在R中我通过geom_violin(position=position_dodge(0.9))调整小提琴的位置和尺寸消除了这类空白,现在想用Python的Seaborn实现同样效果,但当前代码生成的图仍有空白(见附图)。

以下是可复现代码:

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

# Define categories for Depth and Hydraulic Conductivity
depth_categories = ["<0.64", "0.64-0.82", "0.82-0.90", ">0.9"]
hydraulic_conductivity_categories = ["<0.2", "0.2-2.2", "2.2-15.5", ">15.5"]

# Generate random HSI values
np.random.seed(42)  # For reproducibility
hsi_values = np.random.uniform(low=0, high=35, size=30)

# Generate random categories for Depth and Hydraulic Conductivity
depth_values = np.random.choice(depth_categories, size=30)
hydraulic_conductivity_values = np.random.choice(hydraulic_conductivity_categories, size=30)

# Ensure not all combinations are available by removing some combinations
for i in range(5):
    depth_values[i] = depth_categories[i % len(depth_categories)]
    hydraulic_conductivity_values[i] = hydraulic_conductivity_categories[(i + 1) % len(hydraulic_conductivity_categories)]

# Create the DataFrame
dummy_data = pd.DataFrame({
    'HSI': hsi_values,
    'Depth': depth_values,
    'Hydraulic_Conductivity': hydraulic_conductivity_values
})
# Violin plot for Soil Depth and Hydraulic Conductivity
plt.figure(figsize=(12, 6))
sns.violinplot(x='Depth', y='HSI', hue='Hydraulic_Conductivity', data=dummy_data, palette=color_palette,
                density_norm="count",
                cut = 0,
                gap = 0.1,
                linewidth=0.5,
                common_norm=False,
                 dodge=True)
plt.xlabel("DDDD")
plt.ylabel("XXX")
plt.title("Violin plot of XXX by YYYY and DDDD")
plt.ylim(-5, 35)
plt.legend(title='DDDD', loc='upper right')
# sns.despine()# Remove the horizontal lines
plt.show()
解决方案

Seaborn默认的dodge=True只会为有数据的hue类别分配位置,缺失组合会留下空白。要复刻R中position_dodge的效果,需手动调整dodge宽度和小提琴总宽度,让存在的小提琴填满每个x分类的空间。

修改后的代码

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

# Define categories for Depth and Hydraulic Conductivity
depth_categories = ["<0.64", "0.64-0.82", "0.82-0.90", ">0.9"]
hydraulic_conductivity_categories = ["<0.2", "0.2-2.2", "2.2-15.5", ">15.5"]

# Generate random HSI values
np.random.seed(42)  # For reproducibility
hsi_values = np.random.uniform(low=0, high=35, size=30)

# Generate random categories for Depth and Hydraulic Conductivity
depth_values = np.random.choice(depth_categories, size=30)
hydraulic_conductivity_values = np.random.choice(hydraulic_conductivity_categories, size=30)

# Ensure not all combinations are available by removing some combinations
for i in range(5):
    depth_values[i] = depth_categories[i % len(depth_categories)]
    hydraulic_conductivity_values[i] = hydraulic_conductivity_categories[(i + 1) % len(hydraulic_conductivity_categories)]

# Create the DataFrame and set categorical order (optional but recommended)
dummy_data = pd.DataFrame({
    'HSI': hsi_values,
    'Depth': pd.Categorical(depth_values, categories=depth_categories, ordered=True),
    'Hydraulic_Conductivity': pd.Categorical(hydraulic_conductivity_values, categories=hydraulic_conductivity_categories, ordered=True)
})

# Violin plot with adjusted positioning
plt.figure(figsize=(12, 6))
# 计算每个hue类别的 dodge 宽度,确保填满x分类空间
hue_total = len(hydraulic_conductivity_categories)
dodge_width = 0.8 / hue_total

sns.violinplot(x='Depth', y='HSI', hue='Hydraulic_Conductivity', data=dummy_data, 
                palette=color_palette,
                density_norm="count",
                cut=0,
                gap=0.1,
                linewidth=0.5,
                common_norm=False,
                dodge=dodge_width,  # 手动设置dodge宽度
                width=0.8)  # 控制每个x分类的总宽度

plt.xlabel("Depth")
plt.ylabel("HSI")
plt.title("Violin plot of HSI by Depth and Hydraulic Conductivity")
plt.ylim(-5, 35)
plt.legend(title='Hydraulic Conductivity', loc='upper right')
plt.show()

核心调整说明

  1. 手动设置dodge数值:将dodge从布尔值改为0.8 / hue类别数,让每个存在的小提琴占据均等的空间,填满当前x分类的宽度。
  2. 固定分类顺序:把分类列转为pd.Categorical并指定顺序,避免绘图时分类乱序导致的布局问题。
  3. 调整width参数:保持width=0.8(Seaborn默认值),配合dodge数值确保小提琴之间没有多余空白。

这样修改后,每个x分类下的小提琴会紧密排列,不会因缺失组合留下空白,效果和R中position_dodge(0.9)一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:19:55