如何用Python绘制Circos图

Python014

如何用Python绘制Circos图,第1张

用Python实现Circos图的绘制在线绘制的Circos有一定局限性,如对数据的要求、个性化的局限和处理速度等的问题,但如果你是一个Pythoneer或者喜欢用更加Pythonic的方式来个性化地绘制Circos图,那么今天就跟随我一起用代码实现这一目标吧!

安装Circos包

首先,登录Python的包索引网站Python Package Index(PyPI,正确读音是:Pie Pee Ai),找到Circos包的下载页:

https://pypi.python.org/pypi/Circos/1.3.5

该包/模块的作者是我的好友Eric Ma。你可以选择下载wheeler文件,然后本地安装。也可以在shell下直接通过pip进行安装:

pipinstallcircos

注意,所支持的Python版本必须是3.x,对2不支持。

选择数据

当安装了circos包后,我们就可以直接应用这个包来写代码了。为了演示方便,我需要应用一些数据。作为内科医师,就让我来展示一下老本行:处理药物与肝酶细胞色素P450的相互关系的可视化。由于是为了抛砖引玉,所以绘制出的Circos图相对简单。

我们先从美国FDA官网下载不同细胞色素相关的各种口服药物表。共202种常用的口服药物,涵盖内科学、肿瘤学、神经科和心理学等学科。数据文件如下:

可以看到这个数据的结构:是按肝细胞色素酶进行分类,共分8个列。这8个细胞色素酶分别是:CYP1A2,CYP2B6, CYP2C8, CYP2C9, CYP2C19, CYP2D6, CYP2E1和CYP3A4。我们将要建立各个口服药与这些肝酶之间关系的Circos图,从而了解通过相同肝酶代谢或转化的药物之间是否存在相互作用。

导入各个模块和读入数据

导入各个模块:

fromcircosimportCircosPlot

importxlrd

importpandasaspd

importnumpyasnp

读入文件:

filename='.\\MedicationInteraction.xlsx'

book=xlrd.open_workbook(filename)

print('File loaded!')

提取数据:

nrows=book.sheet_by_name('Sheet1').nrows

header=book.sheet_by_name('Sheet1').row_values(0)

data=[book.sheet_by_name('Sheet1').row_values(i) fori inrange(1, nrows)]

df=pd.DataFrame(data, columns =header)

df[df==''] = np.nan

读取后,药物和酶的数据为pandas的DataFrame数据结构,细胞色素P450酶的名字为columns的名字。我们可以检查一下数据:

修数据,尤其是处理NA数据

df_dict={}

foriinrange(len(df.columns)):

df_dict[df.icol(i).name] =list(df.icol(i).dropna())

节点和连线

创建节点(nodes)数据,在我这个例子里就是各个药物和肝酶:

nodes=[]

forkeyindf_dict.keys():

nodes.extend(df_dict[key])

nodes=list(nodes)

headers=list(df.columns)

enzymes=['0'] * 5

forheaderinheaders:

enzymes.append(header)

enzymes.extend(['0']*5)

nodes.extend(enzymes)

创建连线(edges)数据,我们应用tuple(元组)这个数据结构来表示药物与特定肝酶之间的关系:

edges_origin=[]

forkeyindf_dict.keys():

forvalue indf_dict[key]:

edges_origin.append((key, value))

绘图

绘制Circos图:

c=CircosPlot(nodes, edges_origin, radius =10,

nodecolor="blue",

edgecolor="red",

)

c.draw()

得到了下面这张所有药物与肝酶之间的图:

左上方是8个肝脏细胞色素P450酶(CYP1A2、CYP2B6、CYP2C8、CYP2C9、CYP2C19、CYP2D6、CYP2E1和CYP3A4)。其它点即为202种口服药物。每种药物都与参与代谢和转化它的P450酶相连。与相同酶连接的不同药物,理论上应该都存在相互作用,但具体如何还要看与酶的作用机理。

个性化绘图

如果我们打算分别可视化出不同肝酶的关系图形,我们只需改变连线信息,即edges信息:

edges=[]

&#8205forvalueindf_dict['CYP2B6']:

edges.append(('CYP2B6', value))

c=CircosPlot(nodes, edges, radius =10,

nodecolor="orange",

edgecolor="orange",

)

c.draw()

从而我们得到了各种肝酶所代谢和转化药物的图形

用PS将它们合并:

相同肝酶所代谢和转化的药物用相同颜色的edges表示。

显示特定药物

最后,我们可以挑选其中一些感兴趣的药物来进行观察,例如,我从这202个药物中指定几个我感兴趣的药物:

propafenone(心律平), acetaminophen(对乙酰氨基酚), paclitaxel(紫杉醇), ibuprofen(布洛芬), losartan(洛沙坦), omeprazole(奥美拉唑), carvediolo(卡维地洛), codeine(可待因), theophylline(茶碱), quinidine(奎尼丁), verapamil(异搏定), lovastatin(洛伐他汀), nitrendipine(尼群地平)

然后重新建立edges:

medications=['propafenone', 'acetaminophen', 'paclitaxel', 'ibuprofen', 'losartan', 'omeprazole', 'carvedilol', 'codeine', 'theophylline', 'quinidine', 'verapamil', 'lovastatin', 'nitrendipine']

edges_candidate=set()

formedicationinmedications:

foredge inedges_origin:

if medication==edge[1]:

edges_candidate.add(edge)

edges_candidate=list(edges_candidate)

然后再绘图:

c=CircosPlot(nodes, edges_candidate, radius =10,

nodecolor="black",

edgecolor="black",

)

c.draw()

从而得到这张图。

1,xlable,ylable设置x,y轴的标题文字。

2,title设置标题。

3,xlim,ylim设置x,y轴显示范围。

plt.show()显示绘图窗口,通常情况下,show()会阻碍程序运行,带-wthread等参数的环境下,窗口不会关闭。

plt.saveFig()保存图像。

面向对象绘图

1,当前图表和子图可以用gcf(),gca()获得。

subplot()绘制包含多个图表的子图。

configure subplots,可调节子图与图表边框距离。

可以通过修改配置文件更改对象属性。

图标显示中文

1,在程序中直接指定字体。

2, 在程序开始修改配置字典reParams.

3,修改配置文件。

Artist对象

1,图标的绘制领域。

2,如何在FigureCanvas对象上绘图。

3,如何使用Renderer在FigureCanvas对象上绘图。

FigureCanvas和Render处理底层图像操作,Artist处理高层结构。

分为简单对象和容器对象,简单的Aritist是标准的绘图元件,例如Line 2D,Rectangle,Text,AxesImage等,而容器类型包含许多简单的的 Aritist对象,使他们构成一个整体,例如Axis,Axes,Figure等。

直接创建Artist对象进项绘图操作步奏:

1,创建Figure对象(通过figure()函数,会进行许多初始化操作,不建议直接创建。)

2,为Figure对象创建一个或多个Axes对象。

3,调用Axes对象的方法创建各类简单的Artist对象。

Figure容器

如何找到指定的Artist对象。

1,可调用add_subplot()和add_axes()方法向图表添加子图。

2,可使用for循环添加栅格。

3,可通过transform修改坐标原点。

Axes容器

1,patch修改背景。

2,包含坐标轴,坐标网格,刻度标签,坐标轴标题等内容。

3,get_ticklabels(),,get-ticklines获得刻度标签和刻度线。

1,可对曲线进行插值。

2,fill_between()绘制交点。

3,坐标变换。

4,绘制阴影。

5,添加注释。

1,绘制直方图的函数是

2,箱线图(Boxplot)也称箱须图(Box-whisker Plot),是利用数据中的五个统计量:最小值、第一四分位

数、中位数、第三四分位数与最大值来描述数据的一种方法,它可以粗略地看出数据是否具有对称性以及分

布的分散程度等信息,特别可以用于对几个样本的比较。

3,饼图就是把一个圆盘按所需表达变量的观察数划分为若干份,每一份的角度(即面积)等价于每个观察

值的大小。

4,散点图

5,QQ图

低层绘图函数

类似于barplot(),dotchart()和plot()这样的函数采用低层的绘图函数来画线和点,来表达它们在页面上放置的位置以及其他各种特征。

在这一节中,我们会描述一些低层的绘图函数,用户也可以调用这些函数用于绘图。首先我们先讲一下R怎么描述一个页面;然后我们讲怎么在页面上添加点,线和文字;最后讲一下怎么修改一些基本的图形。

绘图区域与边界

R在绘图时,将显示区域划分为几个部分。绘制区域显示了根据数据描绘出来的图像,在此区域内R根据数据选择一个坐标系,通过显示出来的坐标轴可以看到R使用的坐标系。在绘制区域之外是边沿区,从底部开始按顺时针方向分别用数字1到4表示。文字和标签通常显示在边沿区域内,按照从内到外的行数先后显示。

添加对象

在绘制的图像上还可以继续添加若干对象,下面是几个有用的函数,以及对其功能的说明。

•points(x, y, ...),添加点

•lines(x, y, ...),添加线段

•text(x, y, labels, ...),添加文字

•abline(a, b, ...),添加直线y=a+bx

•abline(h=y, ...),添加水平线

•abline(v=x, ...),添加垂直线

•polygon(x, y, ...),添加一个闭合的多边形

•segments(x0, y0, x1, y1, ...),画线段

•arrows(x0, y0, x1, y1, ...),画箭头

•symbols(x, y, ...),添加各种符号

•legend(x, y, legend, ...),添加图列说明

今天开始琢磨用Python画图,没使用之前是一脸懵的,我使用的开发环境是Pycharm,这个输出的是一行行命令,这个图画在哪里呢? 搜索之后发现,它会弹出一个对话框,然后就开始画了,比如下图第一个常用的库是Turtle,它是Python语言中一个很流行的绘制图像的函数库,这个词的意思就是乌龟,你可以想象下一个小乌龟在一个x和y轴的平面坐标系里,从原点开始根据指令控制,爬行出来就是绘制的图形了。   它最常用的指令就是旋转和移动,比如画个圆,就是绕着圆心移动;再比如上图这个怎么画呢,其实主要就两个命令: turtle.forward(200) turtle.left(170) 第一个命令是移动200个单位并画出来轨迹 第二个命令是画笔顺时针转170度,注意此时并没有移动,只是转角度 然后呢? 循环重复就画出来这个图了 好玩吧。 有需要仔细研究的可以看下这篇文章 https://blog.csdn.net/zengxiantao1994/article/details/76588580 ,这个牛人最后用这个库画个移动的钟表,太赞了。Turtle虽好玩,但是我想要的是我给定数据,然后让它画图,这里就找到另一个常用的画图的库了。 Matplotlib是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图。其中,matplotlib的pyplot模块一般是最常用的,可以方便用户快速绘制二维图表。 使用起来也挺简单, 首先import matplotlib.pyplot as plt 导入画图的图。 然后给定x和y,用这个命令plt.plot(x, y)就能画图了,接着用plt.show()就可以把图形展示出来。 接着就是各种完善,比如加标题,设定x轴和y轴标签,范围,颜色,网格等等,在 https://blog.csdn.net/guoziqing506/article/details/78975150 这篇文章里介绍的很详细。 现在互联网的好处就是你需要什么内容,基本上都能搜索出来,而且还是免费的。我为什么要研究这个呢?当然是为了用,比如我把比特币的曲线自己画出来可好? 假设现在有个数据csv文件,一列是日期,另一列是比特币的价格,那用这个命令画下: 这两列数据读到pandas中,日期为df['time']列,比特币价格为df['ini'],那我只要使用如下命令 plt.plot(df['time'], df['ini']) plt.show() 就能得到如下图:自己画的是不是很香,哈哈! 然后呢,我在上篇文章 https://www.jianshu.com/p/d4013d8a73de 中介绍过求Ahr999指数,那可不可以也放到这张图中呢?不就是加一条命令嘛 plt.plot(df['time'], df['Ahr999']) 图形如下:但是,Ahr999指数怎么就一条线不动啊, 原来两个Y轴不一致,显示出来太怪了,需要用多Y轴,问题来了。 继续谷歌一下,把第二个Y轴放右边就行了,不过呢得使用多图,重新绘制 fig = plt.figure() # 多图 ax1 = fig.add_subplot(111) ax1.plot(df['time'], df['ini'], label="BTC price")  # 绘制第一个图比特币价格 ax1.set_ylabel('BTC price') # 加上标签# 第二个直接对称就行了 ax2 = ax1.twinx()# 在右边增加一个Y轴 ax2.plot(df['time'], df['Ahr999'], 'r', label="ahr999")  # 绘制第二个图Ahr999指数,红色 ax2.set_ylim([0, 50])# 设定第二个Y轴范围 ax2.set_ylabel('ahr999')plt.grid(color="k", linestyle=":")# 网格 fig.legend(loc="center")#图例 plt.show() 跑起来看看效果,虽然丑了点,但终于跑通了。这样就可以把所有指数都绘制到一张图中,等等,三个甚至多个Y轴怎么加?这又是一个问题,留给爱思考爱学习的你。 有了自己的数据,建立自己的各个指数,然后再放到图形界面中,同时针对异常情况再自动进行提醒,比如要抄底了,要卖出了,用程序做出自己的晴雨表。