首页 > 编程语言 >Python——比 Seaborn 更好的相关性热力图:Biokit Corrplot

Python——比 Seaborn 更好的相关性热力图:Biokit Corrplot

时间:2024-06-30 17:42:43浏览次数:27  
标签:Corrplot Seaborn Python order 相关性 Biokit 绘制 method

目录

前言:我们需要更好的相关性热力图

在 Python 中我们日常分析数据的过程当中经常需要对数据进行相关性分析,相关性热力图(Correlation Heatmap)是我们经常使用的一种工具。通过相关性热力图,我们可以通过为相关性不同的数据使用不同深浅的不同颜色进行标记,从而直观地观察两两数据序列之间的相关性情况——这将有助于我们进一步的数据分析和处理,比如数据的回归分析等。

这其中最常见的工具就是由 Seaborn 工具包提供的 sns.heatmap(),处理方法的原理相当于先取得变量序列的相关性矩阵,然后直接对相关性矩阵绘制矩阵热图。

然而最近在学习了 R 语言之后,使用 corrplot 包可以绘制出更加华丽、全面、直观的相关性图,相比较之下就觉得 Seaborn 提供的热图并不令人满意。因此本文介绍一种新的更好的相关图的绘制方法,来自 Biokit 工具包中的 biokit.viz.Corrplot() 类,并介绍其使用。

废话不多说,先上图展示:

image

  • (咱就说我们平时写论文或者分析报告的时候,把这个图往上面一放是不是高端大气上档次?)

对比 Python Seaborn 与 R corrplot

传统的 Seaborn 相关性热力图

下面展示了一个简单的使用示例:

# 导入需要用到的库
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 读取数据,这里以著名的波士顿数据集举例
data = pd.read_csv('./data/boston.csv')

# 绘制热图
fig, ax = plt.subplots(figsize=(10, 8))
sns.heatmap(
    data.corr(), annot=True, cmap='coolwarm', ax=ax)

fig.savefig('../image/py_heatmap.png')

上述的代码绘制效果如下图所示:

image

从上图中可以看出传统的 Seaborn 的热图存在一些问题:

  1. 各个字段按顺序输出,不同相关性的单元格混排,难以一眼看出变量之间的显著相关关系
  2. 即使选择了对比度更高的,Colormap 仍然难以一眼找到具有较高相关性的变量
  3. 三角图的绘制需要设置和使用 mask 参数,代码书写复杂度瞬间翻倍

R 语言中的相关性热力图

相比较之下,如下是通过 R 语言绘制的相关性热图的示例:

### 导入工具包 ###

library('corrplot')

### 读取数据 ###
dat <- read.csv('./data/boston.csv')

### 计算取得相关性及相关性显著性 ###
corr <- cor(dat)
corrl <- cor.mtest(dat)

### 绘图 ###
corrplot.mixed(
  corr, order = 'AOE',
  lower = 'number', upper = 'ellipse',
  p.mat = corrl$p, insig = 'pch', pch = 4,
  tl.col = 'black', tl.pos = 'lt',
  number.cex = 0.7,  # 调整数字大小
)

关于 R 语言中 Corrplot 的使用方法,可以参考文章 An Introduction to corrplot Package,从原文中可以看见 R 的 Corrplot 包提供了大量自由度极高的参数选项对绘制的相关性热图进行调整。

绘制效果如下图所示:

image

从上图可以看出,与 Seaborn 相比,R 语言的相关性热力图具有以下几个显著的优势:

  1. 允许使用椭圆形、不同大小的圆或者方片乃至小饼图结合颜色标记来标记每个变量之间的相关性,更加直观、清晰。
  2. 允许数值和形状分开分别绘制在图的左下角和右上角,丰富图的内容。
  3. 对于未通过显著性检验的相关性矩阵元素,使用散点标记划去(图中的叉)。

显然我们希望在 Python 中也能像这样轻松第绘制更加美观和华丽的相关性热力图。

关于 Biokit

简介

BioKit 一套专门用于生物信息学、数据可视化(BioKit.viz)、在线生物数据访问(例如 UniProt,得益于生物服务的 NCBI)的工具。它还包含与数据分析相关的更高级的工具(例如 biokit.stats)。由于R在生物信息学中很常见,Biokit 还提供了一个方便的模块来在 Python 脚本或 shell 中运行 R(biokit.rtools 模块)。

文档手册在 biokit.readthedocs.io,详情请自行查看。

库的安装

Biokit 的安装在原生的 Python 和 Anaconda 中略有不同,按照官方给出的安装方式,在 Python 中:

pip install biokit

如果在使用 Conda,则官方手册和代码仓库的 README.md 文件中给出的安装方式互不相同。其原因……额,咱也不知道咱也不敢问:

conda install bioconda # 根据官方仓库 README.md
conda install biokit   # 根据手册

不过我会推荐大家从源码构建安装 Biokit,具体的原因我会在下文详述。

相关性热图的绘制

基本使用方法

Biokit 中的热图是以一个类的形式定义的,具体的定义形式:

biokit.viz.Corrplot(data, na=0)

这里初始化方法传入两个参数:na 是一个用于替换数据中的缺失值的默认值,也就是说如果数据里面有缺失值就会被自动替换为这个值。不言而喻;

这个 data 则很有意思,我翻译了官网上对于这个变量的介绍:

输入可以是 DataFrame(Pandas)、List(python)或 numpy 矩阵。但是,请注意,值必须介于 -1 和 1 之间。如果不是, 或者如果矩阵(或列表列表)不是方阵,则相关性为其自动计算的结果。数据或计算的相关性存储在 df 属性中。

也就是说,在 Biokit 中,传进的 data 参数可以是有待计算相关性的原始数据,也可以是相关性矩阵。如果传入前者,方法会为你计算相关性系数。

完成初始化之后,需要调用 .plot() 方法来绘图。其中,关于绘制图片的方法 biokit.viz.Corrplot.plot() 定义形式如下:

def plot(self, fig=None, grid=True, rotation=30, lower=None, upper=None, shrink=0.9, facecolor="white", colorbar=True, label_color="black", fontsize="small", edgecolor="black", method="ellipse", order_method="complete", order_metric="euclidean", cmap=None, ax=None, binarise_color=False):

详述一些绘图参数的问题及细节

对于每个参数的含义的说明,如下表所示:

名称 默认值 含义
fig None 一个 matplotlib 图对象,用于绘制热力图。默认情况下会自动创建,也可以在使用的时候具体指定。
grid True 添加网格(默认为灰色)。您可以将其设置为False或颜色。
rotation 30 在y轴上旋转标签的角度
lower None 设置左下角部分的热力图的绘制方法,可选的参数有 'ellipse''square''rectangle' 以及'color''text''circle''number''pie',绘制效果即字面意思所示,本文的读者可自行尝试每一种绘制效果。
upper None 设置右上上角部分的热力图的绘制方法,可选参数同 lower,此不复赘述。
shrink 0.9 符号使用每个小方格的最大空间(百分比)。如果提供负值,则取绝对值;如果大于 1,符号将与边框方格重叠。
facecolor "white" 图整体背景的颜色(默认为白色)。
colorbar True 添加颜色条(默认为True)。
label_color "black" 轴标签的颜色(默认为黑色)。
fontsize "small" 字体的大小,默认为“small”。可以直接用数字控制大小。
edgecolor "black" 代码文档中未曾提及但是确实存在的参数选项,目测其功能是指定绘制矩形、椭圆、圆等图形时图形边缘的颜色。。
method "ellipse" 在没有指定 lower 或者 upper 参数时生效,
order_method "complete" 使用方法对相关性矩阵的行和列重新排序,使得相似的变量被聚集在一起。这种排序可以帮助你更清晰地观察和理解数据的相关性模式。
order_metric "euclidean" 用于计算距离的度量标准。下文详述。
cmap None matplotlib 或 colormap 包中的有效的 Colormap(例如。'jet''copper')。默认为红色/白色/蓝色。
ax None 一个标准的 matplotlib 坐标轴对象。不指定则自动创建。
binarise_color False 又是一个代码文档中没说过的参数。目测其功能是将颜色值二值化(binarize)。具体来说,如果 binarise_color 被设置为 True,颜色值将被转换为二进制值。换句话说,简化颜色表示,仅使用两种颜色来表示正负相关性。

对于上表中的部分参数,我这里需要给出一些详细的说明:

我写不动了,这段内容我让 Chat 姐帮我写了。请读者们体谅一下。

关于 order_method 参数

order_method 参数决定了用于层次聚类的链接方法。这些方法定义了如何计算聚类之间的距离。常见的链接方法包括:

  • 'single': 最近邻法。两个聚类之间的距离由最近的一对点决定。
  • 'complete': 最远邻法。两个聚类之间的距离由最远的一对点决定。
  • 'average': 平均法。两个聚类之间的距离由所有点对之间的平均距离决定。
  • 'centroid': 质心法。两个聚类之间的距离由它们质心之间的距离决定。
  • 'median': 中位数法。计算两个聚类的中位数质心之间的距离。
  • 'ward': Ward法。最小化每个聚类的平方和误差。

这些方法是通过 scipy.cluster.hierarchy.linkage 函数实现的。选择不同的方法会影响聚类结果,从而影响相关性矩阵的排序。

关于 order_metric 参数

order_metric 参数决定了用于计算距离的度量标准。常见的度量标准包括:

  • 'euclidean': 欧几里得距离。
  • 'cityblock': 曼哈顿距离(城市街区距离)。
  • 'cosine': 余弦距离。
  • 'hamming': 汉明距离。
  • 'jaccard': 杰卡德距离。

这些度量标准是通过 scipy.spatial.distancescipy.cluster.hierarchy 提供的。选择不同的距离度量会影响聚类计算的结果。

在使用中,order_methodorder_metric 会对相关性矩阵的行和列重新排序,使得相似的变量被聚集在一起。这种排序可以帮助你更清晰地观察和理解数据的相关性模式。为了方便读者理解,我们这里给出一段示例代码——例如,如果你使用 'complete' 方法和 'euclidean' 距离,对应的代码如下:

Y = self.linkage(
    self.df, 
    method=order_method, 
    metric=order_metric)
ind1 = hierarchy.fcluster(
    Y, 0.7 * max(Y[:, 2]), "distance")
Z = hierarchy.dendrogram(Y, no_plot=True)
idx1 = Z["leaves"]
cor2 = self.df.iloc[idx1, idx1]

这段代码首先计算相关性矩阵的层次聚类,然后根据聚类结果对矩阵的行和列进行重新排序。self.linkage 函数调用了 scipy.cluster.hierarchy.linkagehierarchy.fclusterhierarchy.dendrogram 分别用于获取聚类结果和绘制树状图。

关于 cmap 参数

Biokit 源代码中应用 camp 参数的方法是:

self.cm = cmap_builder(cmap)

所以你可以使用如下的指定 colormap 的方法:

  • 指定 colormap 的名称:cmap='viridis'
  • 指定三种具体颜色的过渡:cmap=['#2F7FC1', '#FFFFFF', '#D8383A']

⚠ ⚠ ⚠ 不要使用 如下的方法指定 colormap,否则将会报错:

# 不要这样做!
import matplotlib.pyplot as plt
from

cmap = plt.cm.get_cmap('inferno') # 获取cmap对象
data = ...

... # 中间代码略

corrp = Corrplot(data)
corrp.plot(
  cmap=cmap
)

改进 BioKit 中 Corrplot 对 colormap 的支持

事情的起因

回到本文最开头的那张图片,绘制这张图片我使用了如下的代码:

import pandas as pd
import matplotlib.pyplot as plt

from biokit.viz import Corrplot

data = pd.read_csv('./data/boston.csv')

fig, ax = plt.subplots(figsize=(10, 8))
datacorr = Corrplot(data)
datacorr.plot(
    ax=ax,
    lower='ellipse', upper='text', 
    cmap='YlGnBu_r', edgecolor='grey', 
    fontsize=12, order_method='centroid')

如果读者们运行我给出的这段代码,就会发现图片绘制出来的效果和本文中所展示的有所不同——为什么右上半个三角中的数字只有红蓝两种颜色,而本文中展示的绘制效果则是叠加了 viridis Colormap 的效果呢?

实际上,原生的 Biokit 中 Corrplot 在使用 method='number' 的时候确实不支持任意 Colormap,只支持红蓝双色。参考 Biokit 在 Github 上的源代码仓库 biokit/biokit 中的 Jupyter Notebook biokit/viz/corrplot 中的说明:

c.plot(method='text', fontsize=8, colorbar=False)
# only red to blue colormap is implemented so far

image

但是仔细查看源代码之后,我发现想要修复这个问题使 .plot(method='text') 支持 Colormap 其实很简单。参考 stackoverflow 上的提问 Getting individual colors from a color map in matplotlib,我发现 matplotlib 中有个 Normalize 类能够将 colormap 对象映射到任何数值范围内:

matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)

我们知道相关性是一个从 -1 到 1 之间的数值,因此只需要将用户指定的 Colormap 映射到这个区间范围,再根据每个相关性矩阵元素的值从标准化之后的 Colormap 中选取颜色就好了。具体的实现方法:

Biokit 中原始的这段代码为:

...
                elif method in ['number', 'text']:
                    from easydev import precision
                    if d<0:
                        edgecolor = 'red'
                    elif d>=0:
                        edgecolor = 'blue'
                    ax.text(x,y, precision(d, 2), color=edgecolor,
                            fontsize=self.fontsize, horizontalalignment='center',
                            weight='bold', alpha=max(0.5, d_abs))
                            # withdash=False)
...

我给修改成了:

...
                elif method in ['number', 'text']:
                    from easydev import precision
                    # if d<0:
                    #     edgecolor = 'blue'
                    # elif d>=0:
                    #     edgecolor = 'red'
                    # Instantiate a 
                    # `matplotlib.colors.Normalize()` object
                    # as `color_norm`
                    color_norm = Normalize(
                        # the range of correlation coefficient
                        vmin=-1.0, 
                        vmax=1.0)
                    # select colors for each `d` 
                    # with normalized colormap
                    edgecolor = self.cm(
                        color_norm(d))
                    # plot the label with the color
                    ax.text(
                        x,
                        y, 
                        precision(d, 2), 
                        color=edgecolor,
                        fontsize=self.fontsize, 
                        horizontalalignment='center',
                        weight='bold', 
                        # alpha=max(0.5, d_abs) 
                        # withdash=False)
                        ) # alpha is no longer needed
...

我当时觉得这个改动还蛮好的,所以大概是在这篇博客写完之前的上个星期,我向原仓库提交了 Feature: A Method to Apply colormap to corrplot while Using method='number' #78,结果原作者一直不回复我。后来我干脆自己动手,又提交了 Pull Request for Issue #78: Apply Colormap to Corrplot #79后来我看了一下 Biokit 仓库现在的情况——好家伙,上次更新都已经是 3 年前了,不知道为什么这个仓库自那之后便一直没有再更新过。

所以读者们如果想要使用像本文开头所展示的那样带颜色的 text Corrplot,可以从 Github 上拉取 我 fork 并修改过源码的 repo,然后在本地通过源码构建安装。

拉取 Biokit 源码并在本地构建

如果您的计算机环境上已经配置过 Git 工具则可以使用下面的命令拉取项目到本地:

git clone https://github.com/GitHubonline1396529/biokit.git

进入本地项目文件夹并构建安装源码:

cd ./biokit
pip install .

注意!不要再使用 python -u ./setup.py 了! 这种安装方式已经严重过时,被弃用了。(居然到现在为止 CSDN 上还有那么多博文在建议这样构建源码,每天都有一大堆新手跑过来问我。我还能说什么?)

总结和补充

Biokit 是一个功能强大的库,尽管本文仅介绍其热力图的绘制,但是实际上这个工具包的功能非常的多,有待读者们发现。但是中文互联网上对于 Biokit 的介绍很少,我直接通过 Bing 搜索找到的也只有腾讯云社区上的 BioKit!让你用Python也可以轻松绘制矩阵热力图... 这一篇。

不知道原项目后面会不会更新,但是这么好的项目沉了也是蛮可惜的。但是凭我自学 Python 两年半的功夫肯定是更新不动这么大的一个项目的。

我也相当于是在这里问问有没有人愿意提供帮助吧。

标签:Corrplot,Seaborn,Python,order,相关性,Biokit,绘制,method
From: https://www.cnblogs.com/BOXonline1396529/p/18276702

相关文章

  • 【Python3.8.10打包exe】【Windows】
    Python3.8.10打包exe打包命令pyinstaller-Fxxx.py查看Package及版本号piplist查看Python版本号python-V打包需要用的Package及版本#python版本#3.8.10#wheel版本#0.43.0#pyinstaller版本#6.8.0常用链接chatgptPython标准库—Python3.8.19文档PyPI......
  • [oeasy]python021_赛博宝剑铭文大赏_宝剑上的铭文_特殊符号和宝物
    继续运行......
  • 《最新出炉》系列入门篇-Python+Playwright自动化测试-52- 字符串操作 - 下篇
    1.简介在日常的自动化测试工作中进行断言的时候,我们可能经常遇到的场景。从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言。这个时候就需要我们对字符串进行操作,宏哥这里介绍两种方法:正则和字符串切片函数split()。2.测试场景宏哥在这里......
  • 【Python爬虫实战项目】Python爬取Top100电影榜单数据并保存csv文件(附源码)
    前言今天给大家介绍的是Python爬取Top100电影榜单数据保存csv文件,在这里给需要的小伙伴们帮助,并且给出一点小心得。开发工具Python版本:3.6相关模块:requests模块time模块parsel模块csv模块环境搭建安装Python并添加到环境变量,pip安装需要的相关模块即可。文中......
  • Python教程:开箱即用的Python os模块知识
    1.简介注:文末有福利领取哦Python的os模块提供了许多接口用于与操作系统进行交互,包括文件操作、目录操作、路径操作、环境变量操作、系统信息获取等。以下是os模块中常用的接口及其解释:文件和目录操作:os.remove(path):删除指定路径的文件。os.rename(src,dst):......
  • SSM-学情分析系统-56772(免费领源码+开发文档)可做计算机毕业设计JAVA、PHP、爬虫、APP
    学情分析系统摘 要随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于学情分析系统当然也不能排除在外,随着网络技术的不断成熟,带动了学情分析系统,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵活性。这......
  • python创建websocket服务器,实现循环发送消息
    WebSocket协议是在2008年由Web应用程序设计师和开发人员创建的,目的是为了在Web浏览器和服务器之间提供更高效、更低延迟的双向通信。它允许客户端和服务器在任何时候发送消息,无需重新建立TCP连接。WebSocket可以在Web浏览器和服务器之间传输文本和二进制数据,使得构建实时Web......
  • 基于SpringBoot的高校大学生学科竞赛管理系统+53135(免费领源码)可做计算机毕业设计JAVA
    springboot高校大学生学科竞赛管理系统的设计与实现摘 要随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理。在现实运用中,应用软件的工作规则和开发步骤,采用Java技术建设高校大学生学科竞赛管理系统。......
  • Python-题库篇-基础
    文章目录Python-题库篇-基础题目001:在Python中如何实现单例模式。题目002:不使用中间变量,交换两个变量`a`和`b`的值。题目003:写一个删除列表中重复元素的函数,要求去重后元素相对位置保持不变。题目004:假设你使用的是官方的CPython,说出下面代码的运行结果。题目005:Lambda......
  • Python 字符串拼接方法
    字符串的拼接方式有多种:s='nice't='meetyou'r='!'1.利用字符串的格式化%s来拼接字符串。‘%s%s%s’%(s,t,r)结果:‘nicemeetyou!’2.利用join方法来拼接字符串。''.join([s,t,r])结果:‘nicemeetyou!’3.利用加号"+"来拼接字符串。s+t+r结果:‘......