背景
数据可视化是数据分析中的重要环节,尤其是在面对多维数据时,如何有效地展示各类特征及其之间的关系是一项挑战,接下来将介绍一种独特且高效的可视化工具——Circos,它以环形布局为基础,能够清晰、直观地展示不同类别、维度的复杂数据结构
通过本文,读者将了解 Circos 的基本原理和使用方法,配合 Python 实现环形图的构建,并展示 Circos 如何在不同场景下应用于模拟数据和实际数据分析中
Circos 可视化的基本原理
Circos 是一种环状图表,最初用于基因组学中的基因关系可视化,后来逐渐发展为广泛应用于各类多维数据展示的工具,它以圆形扇区为核心,不同的类别或维度可以分配到各个扇区中,每个扇区内可以绘制多个图形轨道,从而能够在同一图表中显示多种图形类型
Circos 的优势在于它可以将复杂的数据结构可视化,并且能在不同类别、维度之间绘制关联线,使数据间的关系一目了然
代码实现
模拟数据的 Circos 可视化
import numpy as np
from pycirclize import Circos
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
np.random.seed(0)
# 定义一个字典,表示每个扇区的名称和大小
sectors = {"A": 10, "B": 15, "C": 12, "D": 20, "E": 15}
# 创建 Circos 图表对象,设置扇区之间的间距为 5
circos = Circos(sectors, space=5)
# 遍历 Circos 图表中的每个扇区
for sector in circos.sectors:
# 在扇区内部显示文本,文本内容为 "Sector: 扇区名称",文本半径设置为 110,字体大小设置为 15
sector.text(f"Sector:{sector.name}", r=110, size=15)
# 定义 x 坐标的数组,范围为扇区的起始位置到结束位置 + 0.5
x = np.arange(sector.start, sector.end) + 0.5
# 生成一个随机的 y 值数组,长度与 x 数组相同,值在 0 到 100 之间
y = np.random.randint(0, 100, len(x))
# 第一个轨道:绘制线条
# 添加一个轨道,半径范围在 (80, 100) 之间,r_pad_ratio 用于设置轨道之间的间距比例
track1 = sector.add_track((80, 100), r_pad_ratio=0.1)
# 在第一个轨道上根据固定间隔绘制 x 轴刻度
track1.xticks_by_interval(interval=1)
# 绘制轴线
track1.axis()
# 使用 x 和 y 数据绘制线条图
track1.line(x, y)
# 第二个轨道:绘制散点图
# 添加第二个轨道,半径范围在 (55, 75) 之间
track2 = sector.add_track((55, 75), r_pad_ratio=0.1)
# 绘制轴线
track2.axis()
# 使用 x 和 y 数据绘制散点图
track2.scatter(x, y)
# 第三个轨道:绘制条形图
# 添加第三个轨道,半径范围在 (30, 50) 之间
track3 = sector.add_track((30, 50), r_pad_ratio=0.1)
# 绘制轴线
track3.axis()
# 使用 x 和 y 数据绘制条形图
track3.bar(x, y)
# 绘制不同扇区之间的连接线(link)
# 在扇区 A 的位置 0 到 3 之间绘制连接线,连接到扇区 B 的位置 15 到 12 之间
circos.link(("A", 0, 3), ("B", 15, 12))
# 在扇区 B 的位置 0 到 3 之间绘制连接线,连接到扇区 C 的位置 7 到 11 之间,颜色为天蓝色
circos.link(("B", 0, 3), ("C", 7, 11), color="skyblue")
# 在扇区 C 的位置 3 到 5 之间绘制连接线,连接到扇区 E 的位置 15 到 12 之间
# 连接线颜色为亮绿色,边框颜色为黑色,线宽为 0.5,使用斜线样式,连接方向设置为 2
circos.link(("C", 3, 5), ("E", 15, 12), color="lime", ec="black", lw=0.5, hatch="//", direction=2)
# 在扇区 D 的位置 8 到 10 之间绘制连接线,连接到扇区 E 的位置 2 到 8 之间
# 连接线颜色为紫罗兰色,边框颜色为红色,线宽为 1.0,线型设置为虚线
circos.link(("D", 8, 10), ("E", 2, 8), color="violet", ec="red", lw=1.0, ls="dashed")
circos.savefig("example01.pdf", dpi=1200)
fig = circos.plotfig()
利用 Circos 图表库生成了一个包含多个扇区和数据轨道的环形可视化图。 每个扇区(A、B、C、D、E)代表不同的类别或数据区域,在每个扇区内绘制了三种不同类型的图表: 线条图、散点图和条形图,用来展示数据的不同维度。 此外,代码还绘制了多个扇区之间的连接线,展示它们之间的关联关系。 通过这些图形和连接线,能够直观地展示不同类别的数据及其相互关系
Circos 可视化的实际应用:从模拟数据到真实数据
from sklearn.datasets import load_iris
from matplotlib.lines import Line2D
# 加载鸢尾花数据集
iris = load_iris()
data = iris.data
labels = iris.target
feature_names = iris.feature_names
species = iris.target_names
# 将数据按类别分组
setosa = data[labels == 0]
versicolor = data[labels == 1]
virginica = data[labels == 2]
# 定义扇区的大小,例如每个类别分配相等的大小
sectors = {"Setosa": len(setosa), "Versicolor": len(versicolor), "Virginica": len(virginica)}
circos = Circos(sectors, space=5)
# 绘制每个扇区
for sector in circos.sectors:
# 在扇区中显示类别名称
sector.text(f"Species: {sector.name}", r=110, size=15)
# 根据鸢尾花类别绘制不同的图形
if sector.name == "Setosa":
data_subset = setosa
elif sector.name == "Versicolor":
data_subset = versicolor
elif sector.name == "Virginica":
data_subset = virginica
# 定义 x 坐标
x = np.arange(0, len(data_subset)) + 0.5
# 特征的 y 坐标
y_sepal_length = data_subset[:, 0] # 花萼长度
y_sepal_width = data_subset[:, 1] # 花萼宽度
y_petal_length = data_subset[:, 2] # 花瓣长度
y_petal_width = data_subset[:, 3] # 花瓣宽度
# 绘制不同轨道的特征数据
# 轨道1:花萼长度的散点图
track1 = sector.add_track((80, 100), r_pad_ratio=0.1)
track1.axis()
track1.scatter(x, y_sepal_length)
# 轨道2:花萼宽度的条形图
track2 = sector.add_track((55, 75), r_pad_ratio=0.1)
track2.axis()
track2.bar(x, y_sepal_width)
# 轨道3:花瓣长度的线图
track3 = sector.add_track((30, 50), r_pad_ratio=0.1)
track3.axis()
track3.line(x, y_petal_length)
# 轨道4:花瓣宽度的散点图
track4 = sector.add_track((5, 25), r_pad_ratio=0.1)
track4.axis()
track4.scatter(x, y_petal_width)
# 保存 Circos 图为 PDF
circos.savefig("iris_circos.pdf", dpi=1200)
fig = circos.plotfig()
# 创建图例的文本说明
legend_text = """Track Information:
Track 1: Sepal Length
Track 2: Sepal Width
Track 3: Petal Length
Track 4: Petal Width
"""
# 使用 plt.text 在图的外部添加文本说明
plt.text(1.05, 0.5, legend_text, transform=plt.gca().transAxes, fontsize=12,
verticalalignment='center', bbox=dict(facecolor='white', alpha=0.5))
# 保存图形并包含文本说明
plt.savefig("iris_circos_with_legend_text.pdf", dpi=1200, bbox_inches="tight")
plt.show()
为进一步展示 Circos 的强大功能,使用 Circos 图表可视化了经典的鸢尾花(Iris)数据集,展示了每个物种(Setosa、Versicolor、Virginica)的四个特征:花萼长度、花萼宽度、花瓣长度和花瓣宽,每个物种对应一个环形扇区,内部按顺序展示四个轨道:第一轨道为花萼长度的散点图,第二轨道为花萼宽度的条形图,第三轨道为花瓣长度的线图,第四轨道为花瓣宽度的散点图。最后,代码添加了图例,说明了每个轨道代表的特征。通过这种方式,图形清晰地展示了不同鸢尾花物种之间在各个特征上的差异,由于 Circos 图中的数据展示相对复杂,尤其是当图形较为密集时,单独添加图例显得尤为重要,确保读者不会因为信息过载而感到困惑
往期推荐
从零开始:手把手教你部署顶刊机器学习在线预测APP并解读模型结果
微信号|deep_ML
欢迎添加作者微信进入Python、ChatGPT群
进群请备注Python或AI进入相关群
无需科学上网、同步官网所有功能、使用无限制
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考