SCI图表复现:整合数据分布与相关系数的高级可视化策略

picture.image

背景

有效的可视化不仅能够揭示数据的分布,还可以帮助识别不同变量之间的关系,一种流行的多变量数据可视化方法是将散点图、直方图和相关系数组合成一个综合图表,这种可视化方法,通常被称为成对图或相关网格,在探索性数据分析中尤为有用,能帮助研究者了解数据的潜在结构和关系,写这篇文章的灵感来源于以下SCI可视化

picture.image

优点

  • 数据关系的可视化表现: 散点图能够直观地展示两个连续变量之间的关系, 在分析多变量数据时,这些图能够帮助识别线性或非线性趋势、聚类或异常值
  • 通过直方图和核密度估计理解分布: 对角线部分的直方图显示每个变量的分布, 加入核密度估计(KDE)提供了直方图的平滑版本,能够更好地了解变量的概率密度函数
  • 通过相关系数量化关系: 皮尔逊相关系数是一种统计量,衡量两个变量之间的线性关系, 通过在上三角矩阵中注释这些系数,我们可以快速评估关系的强度和方向(正或负)

接下来作者将展示如何用python代码复现这个可视化,以及怎么样改进使其更美观

代码实现

数据生成


          
import seaborn as sns
          
import matplotlib.pyplot as plt
          
import numpy as np
          
import pandas as pd
          
import warnings
          
warnings.filterwarnings("ignore")
          

          
# 示例数据集
          
df = pd.DataFrame(np.random.randn(100, 10), columns=["M", "V", "D", "t", "w", "n", "fy", "fc", "L", "d"])
          
df.head()
      

picture.image

生成一个具有10列随机数(遵循标准正态分布)的示例数据集,并将其列名设置为["M", "V", "D", "t", "w", "n", "fy", "fc", "L", "d"]

基础复现


          
# 计算皮尔逊相关系数矩阵
          
corr = df.corr()
          

          
# 创建 PairGrid
          
g = sns.PairGrid(df)
          

          
# 左下角绘制散点图
          
g.map_lower(sns.scatterplot)
          

          
# 对角线绘制直方图
          
g.map_diag(sns.histplot, kde=True)
          

          
# 右上角显示相关系数
          
for i, j in zip(*np.triu_indices_from(corr, 1)):
          
    g.axes[i, j].annotate(f'corr:{corr.iloc[i, j]:.2f}', (0.5, 0.5), 
          
                          textcoords='axes fraction', ha='center', va='center', fontsize=20)
          
    
          
plt.savefig("第一种.pdf", format='pdf', bbox_inches='tight')
          
plt.show()
      

picture.image

创建一个综合图表,用于展示数据集中多个变量之间的分布和线性关系,左下角部分是散点图,对角线部分是直方图与核密度估计,而右上角则显示每对变量的皮尔逊相关系数

改进——修改相关系数部分为热图


          
corr = df.corr()
          
g = sns.PairGrid(df)
          
g.map_lower(sns.scatterplot)
          
g.map_diag(sns.histplot, kde=True)
          
fig = g.fig
          

          
# 右上角替换为热力图(每个子图显示一个相关系数)
          
for i, j in zip(*np.triu_indices_from(corr, 1)):
          
    ax = g.axes[i, j]
          
    sns.heatmap(pd.DataFrame([[corr.iloc[i, j]]]), cmap=sns.diverging_palette(240, 10, as_cmap=True), 
          
                cbar=False, annot=True, fmt=".2f", square=True, ax=ax, vmin=-1, vmax=1,
          
                annot_kws={"size": 20})  # 设置相关系数数字字体大小为12
          

          
# 在图形旁边添加全局色条
          
fig.subplots_adjust(right=0.85)  # 调整图形右侧空间以显示色条
          
cbar_ax = fig.add_axes([0.87, 0.15, 0.03, 0.7])  # 定义色条位置和大小
          
norm = plt.Normalize(vmin=-1, vmax=1)
          
sm = plt.cm.ScalarMappable(cmap=sns.diverging_palette(240, 10, as_cmap=True), norm=norm)
          
sm.set_array([])  # 为空数组设置色条
          
fig.colorbar(sm, cax=cbar_ax)  # 添加全局色条
          
plt.savefig("第二种.pdf", format='pdf', bbox_inches='tight')
          
plt.show()
      

picture.image

通过使用热力图替代右上角的空白数字显示、添加全局色条以及调整图形布局,确实使相关系数矩阵的展示更加直观和信息丰富。然而,细心的读者会发现,这种方法会导致除第一列以外的其他列的散点图和直方图显示不完整,因此,需要进一步优化,而不是简单地通过函数批量绘制散点图和直方图


          
corr = df.corr()
          
n = len(df.columns)
          
fig, axes = plt.subplots(n, n, figsize=(2.5 * n, 2.5 * n))
          

          
# 绘制每个位置的散点图和直方图
          
for i in range(n):
          
    for j in range(n):
          
        ax = axes[i, j]
          
        if i == j:
          
            # 对角线:绘制直方图
          
            sns.histplot(df.iloc[:, i], kde=True, ax=ax)
          
        elif i > j:
          
            # 下三角:绘制散点图
          
            sns.scatterplot(x=df.iloc[:, j], y=df.iloc[:, i], ax=ax)
          
        else:
          
            # 上三角:绘制热图显示相关系数
          
            sns.heatmap(pd.DataFrame([[corr.iloc[i, j]]]), cmap=sns.diverging_palette(240, 10, as_cmap=True),
          
                        cbar=False, annot=True, fmt=".2f", square=True, ax=ax, vmin=-1, vmax=1,
          
                        annot_kws={"size": 20})  # 设置相关系数数字字体大小
          

          
        # 隐藏不需要的轴标签
          
        if i < n - 1:
          
            ax.set_xticklabels([])
          
        if j > 0:
          
            ax.set_yticklabels([])
          

          
# 调整子图之间的间距
          
plt.subplots_adjust(hspace=0.3, wspace=0.3)
          

          
# 在图形旁边添加全局色条
          
fig.subplots_adjust(right=0.85)  # 调整图形右侧空间以显示色条
          
cbar_ax = fig.add_axes([0.87, 0.15, 0.03, 0.7])  # 定义色条位置和大小
          
norm = plt.Normalize(vmin=-1, vmax=1)
          
sm = plt.cm.ScalarMappable(cmap=sns.diverging_palette(240, 10, as_cmap=True), norm=norm)
          
sm.set_array([])  # 为空数组设置色条
          
fig.colorbar(sm, cax=cbar_ax)  # 添加全局色条
          

          
plt.savefig("改进后的可视化.pdf", format='pdf', bbox_inches='tight')
          
plt.show()
      

picture.image

通过手动控制每个子图的类型和位置,解决原方法中图像显示不完整的问题,最后隐藏不必要的轴标签,减少视觉冗余,使图表更加简洁和清晰

当然读者可以通过进一步优化图表元素,如调整核密度曲线的颜色、样式以及图例显示等,来探索更丰富的可视化效果和数据洞察

往期推荐

复现 Nature 图表可视化——基于模型残差分析与显著性检验的模型解释

模型过拟合与欠拟合的核心原理及其与数据集分割的关系

复现顶刊Streamlit部署预测模型APP

从基础到进阶:优化SHAP力图,让样本解读更直观

不止 SHAP 力图:LIME 实现任意黑盒模型的单样本解释

特征选择:Lasso和Boruta算法的结合应用

从基础到进阶:优化SHAP力图,让样本解读更直观

用图表说话:如何有效呈现回归预测模型结果

特征选择:基于随机森林的Boruta算法应用

picture.image

picture.image

picture.image

微信号|deep_ML

欢迎添加作者微信进入Python、ChatGPT群

进群请备注Python或AI进入相关群
无需科学上网、同步官网所有功能、使用无限制

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

个人观点,仅供参考

0
0
0
0
评论
未登录
暂无评论