如何用Seaborn绘制带梯度连线的分组散点图?
用Seaborn绘制配对样本带梯度连线的分组散点图
完全可以用Seaborn实现这类配对实验的可视化,核心是结合散点图函数展示分组分布,再手动绘制每个样本的配对连线(还能让连线随变化量呈现梯度色彩),以下是具体实现方法:
1. 准备配对格式的数据
配对实验的数据需要整理为长格式DataFrame,包含三列:
- 样本ID:标记每个配对的样本
- 分组:区分对照组(Control)和处理组(Treated)
- 测量值:对应分组的实验数据
2. 基础版:带灰色连线的散点图
用swarmplot避免散点重叠,再循环绘制每个样本的配对连线:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np # 模拟配对实验数据 np.random.seed(42) sample_ids = [f"Sample_{i}" for i in range(1, 21)] control_vals = np.random.normal(loc=10, scale=1.5, size=20) treated_vals = control_vals + np.random.normal(loc=2, scale=0.8, size=20) # 整理成长格式DataFrame df = pd.DataFrame({ "Sample": sample_ids * 2, "Group": ["Control"]*20 + ["Treated"]*20, "Value": np.concatenate([control_vals, treated_vals]) }) # 创建画布 plt.figure(figsize=(8, 6)) # 绘制无重叠的散点图 sns.swarmplot(data=df, x="Group", y="Value", hue="Group", size=8, palette="Set2") # 绘制每个样本的配对连线 for sample in sample_ids: control_val = df[(df["Sample"] == sample) & (df["Group"] == "Control")]["Value"].values[0] treated_val = df[(df["Sample"] == sample) & (df["Group"] == "Treated")]["Value"].values[0] # x坐标对应分组位置:0=Control,1=Treated plt.plot([0, 1], [control_val, treated_val], color="gray", alpha=0.5, linestyle="-") # 优化图表样式 plt.title("配对样本:对照组vs处理组", fontsize=14) plt.ylabel("测量值", fontsize=12) plt.xlabel("分组", fontsize=12) plt.legend([],[], frameon=False) # 隐藏重复图例 plt.tight_layout() plt.show()
3. 进阶版:带梯度色彩的连线
如果要让连线颜色随处理前后的差值呈现梯度变化(更直观展示样本变化幅度和方向),可以结合颜色映射实现:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np from matplotlib import cm # 复用之前的模拟数据 np.random.seed(42) sample_ids = [f"Sample_{i}" for i in range(1, 21)] control_vals = np.random.normal(loc=10, scale=1.5, size=20) treated_vals = control_vals + np.random.normal(loc=2, scale=0.8, size=20) df = pd.DataFrame({ "Sample": sample_ids * 2, "Group": ["Control"]*20 + ["Treated"]*20, "Value": np.concatenate([control_vals, treated_vals]) }) # 计算每个样本的处理差值 diff_df = df.pivot(index="Sample", columns="Group", values="Value") diff_df["Diff"] = diff_df["Treated"] - diff_df["Control"] # 创建画布 plt.figure(figsize=(9, 6)) # 绘制散点图 sns.swarmplot(data=df, x="Group", y="Value", hue="Group", size=8, palette="Set2") # 设置颜色映射规则 norm = plt.Normalize(diff_df["Diff"].min(), diff_df["Diff"].max()) cmap = cm.get_cmap("coolwarm") # 冷色对应负差值,暖色对应正差值 # 绘制带梯度色彩的配对连线 for sample in sample_ids: control_val = df[(df["Sample"] == sample) & (df["Group"] == "Control")]["Value"].values[0] treated_val = df[(df["Sample"] == sample) & (df["Group"] == "Treated")]["Value"].values[0] diff = diff_df.loc[sample, "Diff"] # 根据差值匹配颜色 plt.plot([0, 1], [control_val, treated_val], color=cmap(norm(diff)), alpha=0.7) # 添加差值颜色条 sm = cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) plt.colorbar(sm, label="处理组 - 对照组 差值") # 优化样式 plt.title("配对样本:对照组vs处理组(差值梯度连线)", fontsize=14) plt.ylabel("测量值", fontsize=12) plt.xlabel("分组", fontsize=12) plt.legend([],[], frameon=False) plt.tight_layout() plt.show()
补充说明
- 如果样本量很大,
swarmplot可能会有显示问题,可以换成stripplot(data=df, x="Group", y="Value", hue="Group", jitter=True, size=6)实现带抖动的散点图。 - 连线的颜色、透明度、线型都可以根据需求调整,比如用
linestyle="--"改成虚线。
内容的提问来源于stack exchange,提问作者arash
相关产品推荐
相关产品推荐

