背景
在数据分析的可视化过程中,“云雨图”是非常直观的展示工具,它结合了箱线图、散点图以及山脊图,以清晰传达不同组别的数据分布和显著性差异。然而,在某些情况下,为简化图形或强调数据的核心分布特征,可以省略山脊图部分,仅保留箱线图与散点图的组合,本文展示一种简化的“云雨图”方法,即不包含山脊图部分的箱线图和散点图组合,这种设计既保留了“云雨图”直观的分布信息,又更加简洁、聚焦于组间显著性差异,简化方法非常适合展示数据分布的中心趋势、离散情况和组间差异,使得读者能够快速获得数据之间的对比关系
代码实现
数据读取
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
df = pd.read_csv('2024-11-7-公众号Python机器学习AI.csv')
导入必要的库并设置图形参数,然后从名为2024-11-7-公众号Python机器学习AI.csv的文件中读取数据到df数据框
基础可视化
# 设置颜色映射,分别为紫色、蓝色和橙色
colors = ['#7D2E8E', '#00AEE9', '#F8766D']
# 设置图形大小
plt.figure(figsize=(8, 6), dpi=1200)
# 创建箱型图和带颜色的散点图
# 使用 'boxprops' 设置箱型图为白色填充,隐藏离群值
sns.boxplot(
x='division', y='CC', data=df, width=0.4, palette=colors,
boxprops=dict(facecolor='white', edgecolor='black', linewidth=1.2), # 白色填充
medianprops=dict(color='black', linewidth=1.5), # 设置中位数线样式
showfliers=False # 隐藏离群值
)
# 绘制带有分组颜色的散点图
sns.stripplot(x='division', y='CC', data=df, jitter=True, palette=colors, size=4, alpha=0.8)
# 计算每个 division 的样本量
sample_counts = df['division'].value_counts().sort_index()
for i, (label, count) in enumerate(sample_counts.items()):
plt.text(i, -1, f'n = {count}', ha='center', va='center', fontsize=10, style='italic')
plt.xlabel('')
plt.ylabel('Cooling capacity (°C)')
plt.title('CC by Division with Sample Size')
plt.savefig('1.pdf', format='pdf', bbox_inches='tight')
plt.show()
设置三种颜色映射(紫色、蓝色和橙色)用于区分各个分组,然后生成一个包含箱线图和散点图的组合图,箱线图展示每个分组(division)的冷却能力(CC)的分布情况,箱线填充为白色并隐藏离群值,且中位数用黑色线条标出,同时,散点图在每组数据上添加带有轻微抖动的彩色数据点,以展示个体数据的分布,最后,在图中每个分组下方标注样本数量, 图表各部分的解读:
箱线图:
- 每个分组中间的矩形框代表该组冷却能力的四分位范围(即25%至75%之间的数据分布)
- 矩形框内部的黑色线条表示该组数据的中位数(即数据的中心趋势)
- 矩形框的上下延伸的“须”表示数据的范围,一般延伸到1.5倍的四分位距(IQR),展示数据的整体分布
- 这个箱线图部分帮助理解每个分组中冷却能力的集中趋势和分布范围,从而便于比较各分组的典型值和数据范围
散点图:
- 每个分组中的散点代表一个具体的数据点,带有轻微的水平“抖动”效果,使得重叠的数据点彼此分开
- 散点图的颜色与分组对应,紫色、蓝色和橙色分别代表GS、GN和GL组的数
据
- 叠加散点图的作用是展示数据的具体分布情况和数据的离散性,让我们看到每个分组内数据的个体分布,而不仅仅是箱线图给出的汇总信息
最终通过这个图表组成可视化直观比较分组间的差异:通过箱线图和中位数线的对比,可以快速识别出哪个分组的数据集中较高或较低(如GN较高), 展示数据的离散情况:散点图展示了各分组内数据的离散程度,让我们能看到数据的分布是否集中或分散,结合样本数量的信息:样本量的标注说明了每个分组的代表性,可以帮助判断分组间的差异是否可能受样本量的影响
进阶可视化
from scipy.stats import mannwhitneyu
from matplotlib.patches import ConnectionPatch
colors = ['#7D2E8E', '#00AEE9', '#F8766D']
plt.figure(figsize=(8, 6), dpi=1200)
sns.boxplot(
x='division', y='CC', data=df, width=0.4, palette=colors,
boxprops=dict(facecolor='white', edgecolor='black', linewidth=1.2),
medianprops=dict(color='black', linewidth=1.5),
showfliers=False
)
sns.stripplot(x='division', y='CC', data=df, jitter=True, palette=colors, size=4, alpha=0.8)
# 计算每个 division 的样本量
sample_counts = df['division'].value_counts().sort_index()
for i, (label, count) in enumerate(sample_counts.items()):
plt.text(i, -1, f'n = {count}', ha='center', va='center', fontsize=10, style='italic')
# 进行 Mann-Whitney U 检验
groups = [('GL', 'GN'), ('GN', 'GS'), ('GL', 'GS')]
p_values = {}
for group1, group2 in groups:
data1 = df[df['division'] == group1]['CC']
data2 = df[df['division'] == group2]['CC']
# 检查每组是否有数据并计算 p 值
if len(data1) > 0 and len(data2) > 0:
stat, p_value = mannwhitneyu(data1, data2)
p_values[f'{group1}_vs_{group2}'] = p_value
else:
p_values[f'{group1}_vs_{group2}'] = "Insufficient data"
# 添加显著性横线和 p 值标记
annotations = {
('GL', 'GN'): (0, 1, 10), # 在 GL 和 GN 之间的 p 值高度
('GN', 'GS'): (1, 2, 9.5), # 在 GN 和 GS 之间的 p 值高度
('GL', 'GS'): (0, 2, 8.5) # 在 GL 和 GS 之间的 p 值高度
}
for (group1, group2), (x1, x2, y) in annotations.items():
p_value = p_values[f'{group1}_vs_{group2}']
if isinstance(p_value, float):
# 画出显著性横线
con = ConnectionPatch(xyA=(x1, y), xyB=(x2, y), coordsA="data", coordsB="data",
axesA=plt.gca(), axesB=plt.gca(),
arrowstyle="-", linewidth=1.5, color="black")
plt.gca().add_artist(con)
# 添加竖线
plt.plot([x1, x1], [y - 0.1, y], color='black', linewidth=1.5)
plt.plot([x2, x2], [y - 0.1, y], color='black', linewidth=1.5)
# 在横线上方添加 p 值
plt.text((x1 + x2) / 2, y + 0.1, f'p = {p_value:.2e}', ha='center', va='bottom')
plt.xlabel('')
plt.ylabel('Cooling capacity (°C)')
plt.title('CC by Division with Sample Size and Significance Annotations')
plt.savefig('2.pdf', format='pdf', bbox_inches='tight')
plt.show()
进阶代码在基础可视化的基础上,增加分组间显著性差异的统计分析和标注,具体来说,使用Mann-Whitney U检验来比较各组冷却能力(CC)的显著性差异,并在图中添加了显著性横线和p值标记,以直观展示哪些分组之间的差异具有统计学意义,这种改进使得图表不仅展示了数据的分布,还提供了分组间差异的统计信息,帮助读者理解这些差异是否具有统计显著性,从而更具解释力和科学性
同样的思路可以应用到其他数据集和检验方法上,只需更换为适合的变量名称和数据,就可以使用这段代码结构来进行显著性分析,展示不同分组的数据分布情况,如果数据的分布符合正态分布,可以考虑使用t检验或ANOVA等方法,而对于不满足正态分布的数据,除了Mann-Whitney U检验,还可以选择Kruskal-Wallis检验等非参数方法,无论使用何种检验方法,关键在于通过统计显著性标记来展示不同分组间是否存在统计学差异,从而使图表更具解释性和严谨性
🎁 赠书活动来啦! 🎁
支持知识分享,畅享学习乐趣!特别感谢清华出版社 对本次赠书活动的鼎力支持!即日起,只需
点赞、在看、转发 此文章,作者将从后台随机抽取一位幸运儿,免费包邮赠送清华出版社提供的《Python数据可视化:科技图表绘制》这本精彩书籍📚!
💡 赶快参与,一键三连,说不定你就是那位幸运读者哦!
往期推荐
复现SCI文章 SHAP 依赖图可视化以增强机器学习模型的可解释性
复现 Nature 图表——基于PCA的高维数据降维与可视化实践及其扩展
复现Nature图表——基于PCA降维与模型预测概率的分类效果可视化
SCI图表复现:如何直观展示机器学习模型预测结果的准确性和一致性
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考