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

如何为Seaborn factorplot添加散点并自定义颜色?

解决Seaborn分组柱状图叠加被试散点并自定义颜色的问题

问题背景

现有如下结构的pandas DataFrame:

feat  roi       sbj         alpha test_type       acc
0     cnn2  LOC  Subject1  normal_space   imagery  0.260961
1     cnn2  LOC  Subject1           0.4   imagery  0.755594
...

当前使用以下代码绘制分组柱状图:

ax = sns.factorplot(x="feat", y="acc", col="roi", hue="alpha", alpha = 0.9, data=df_s_pt, kind="bar").set(title = "perception, scene wise correlation")

需要实现:

  • 在柱状图上叠加每个被试(Subject1、Subject2等)的散点
  • 自定义散点和柱状图的颜色

解决方案

sns.factorplot已被官方弃用,建议改用功能一致且维护更活跃的sns.catplot。以下是完整实现步骤:

1. 定义自定义颜色映射

用字典指定不同分组对应的颜色,灵活控制柱状图和散点的配色:

# 自定义alpha分组的柱状图颜色
alpha_colors = {
    "normal_space": "#1f77b4",
    "0.4": "#ff7f0e",
    # 可添加更多alpha值对应的颜色
}

# 自定义被试散点的颜色
sbj_colors = {
    "Subject1": "#2ca02c",
    "Subject2": "#d62728",
    "Subject3": "#9467bd",
    # 可添加更多被试对应的颜色
}

2. 绘制基础柱状图

使用catplot绘制柱状图,传入自定义颜色映射,并获取子图坐标轴对象:

import seaborn as sns
import matplotlib.pyplot as plt

# 绘制柱状图
g = sns.catplot(
    x="feat", y="acc", col="roi", hue="alpha", 
    alpha=0.9, data=df_s_pt, kind="bar",
    palette=alpha_colors
)
g.set(title="perception, scene wise correlation")

# 获取每个子图的坐标轴
axes = g.axes.flatten()

3. 遍历子图叠加被试散点

对每个子图筛选对应roi的数据,调整散点位置避免与柱状图重叠,同时应用自定义颜色:

# 遍历每个roi对应的子图
for ax, roi in zip(axes, df_s_pt["roi"].unique()):
    # 筛选当前roi的数据
    roi_data = df_s_pt[df_s_pt["roi"] == roi]
    # 获取x轴类别对应的数值索引
    x_cats = roi_data["feat"].unique()
    x_positions = [i for i, cat in enumerate(x_cats)]
    
    # 遍历每个alpha分组,给散点添加偏移避免重叠
    alpha_list = roi_data["alpha"].unique()
    for alpha_idx, alpha_val in enumerate(alpha_list):
        alpha_data = roi_data[roi_data["alpha"] == alpha_val]
        # 计算偏移量,让同一feat下不同alpha的散点分散开
        offset = (alpha_idx - len(alpha_list)/2) / 5
        # 遍历每个被试绘制散点
        for sbj in alpha_data["sbj"].unique():
            sbj_data = alpha_data[alpha_data["sbj"] == sbj]
            # 匹配feat对应的x位置并加上偏移
            x_vals = [x_positions[list(x_cats).index(f)] + offset for f in sbj_data["feat"]]
            # 绘制散点,设置层级确保在柱状图上方
            ax.scatter(
                x_vals, sbj_data["acc"], 
                color=sbj_colors[sbj], 
                marker="o", s=50,
                edgecolor="white",  # 白边增强散点辨识度
                zorder=5  # 让散点显示在柱状图上层
            )

# 可选:添加被试散点的单独图例
from matplotlib.patches import Patch
sbj_legend_elements = [Patch(facecolor=sbj_colors[sbj], label=sbj) for sbj in sbj_colors]
plt.legend(handles=sbj_legend_elements, bbox_to_anchor=(1.05, 1), loc="upper left")

plt.tight_layout()
plt.show()

关键细节说明

  • zorder=5确保散点在柱状图上方显示,不会被遮挡
  • 偏移量offset的调整可以根据分组数量灵活修改,避免散点重叠
  • 自定义颜色字典支持任意数量的分组,扩展性强
  • 若不需要单独的散点图例,可省略图例添加部分

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:50:31