python 科研统计_Python科研统计作图Plotnine+Seaborn+matplotlib替代R ggplot2系列!(二)...

系列文章的第二讲主要关注更加plotnine作图更加细节的地方。首先作为科研工作者,我们很大一部分工作,无论是某个算法相比于之前的算法更加节省时间,稳定性更高,还是生命科学里面一个基因敲除之后蛋白表达水平降低,这些数据结果的呈现方式都需要按照不同的类别分组,然后再进一步呈现,如果用生命科学中的术语来说,我们需要和control进行比较,从而得出我们的结论。这就免不了需要分组做图,这样更加直观,说服力更强。The gramma of graphics这门书,也就是ggplot2的灵感来源,实际上就是告诉我们通过什么样的数据格式去展现不同情况下的数据。

首先,传统的参数统计以及方差分析等作图的方式相对简单,数据量较小,而且使用柱状图和折线图即可,简单的分组和事后比较。然而,非参数统计,或者多元统计方面,则需要一些复杂的方法,比如降维,排序等。下图以python非度量多维尺度为例,详细展示了如何使用sklearn中的MDS函数进行nmds分析并且将数据转化为dataframe,用于plotnine作图。在这个案例中,不同的样品点之间,或者不同的处理之间,可以通通过不同的形状和颜色区别开来,对于嵌套的实验设计同样可以这样做。而且同一个处理之间通过置信椭圆区别开来。这是典型的多元统计的作图展现方法。同样的可以使用PCA等降维方法展现不同处理之间的差异。

# -*- coding: utf-8 -*-

"""@author: Jianshu Zhao, zhaojs16@mails.tsinghua.edu.cnDepartment of Environmental Metagenomics, School of Environment, Tsinghua University"""

import matplotlib

import matplotlib.pylab as pylab

import matplotlib.pyplot as plt

import pandas as pd

import numpy as np

from biom import load_table

from biom import example_table

from biom import parse_table

import skbio

from sklearn import manifold

from sklearn.decomposition import PCA

from scipy.spatial import distance

from plotnine import *

# Say, "the default sans-serif font is Helvetica"

matplotlib.rcParams['font.sans-serif'] = "Helvetica"

# Then, "ALWAYS use sans-serif fonts"

matplotlib.rcParams['font.family'] = "sans-serif"

params={

'axes.labelsize': '14',

'xtick.labelsize':'14',

'ytick.labelsize':'14',

'lines.linewidth':1,

'legend.fontsize': '14',

'figure.figsize' : '6, 4.5'

}

pylab.rcParams.update(params)

### using path to open data Users/jaysonchao/Documents/python/MacQiime_hawaii_bacteria/usearch61_open_ref_no_chimera/

# with open('16S_otu_table_mc2_w_tax_no_singletons_nolowcoverage_sorted_rarefied_40000.biom') as f:

# table = parse_table(f)

## a function to extrac otu table from biom file without taxonomy

def exploding_panda(_bt):

"""BIOM->Pandas dataframe converterParameters----------_bt : biom.TableBIOM tableReturns-------pandas.DataFrameThe BIOM table converted into a DataFrameobject.References----------Based on this answer on SO:http://stackoverflow.com/a/17819427/379593"""

m = _bt.matrix_data

data = [pd.SparseSeries(m[i].toarray().ravel()) for i in np.arange(m.shape[0])]

out = pd.SparseDataFrame(data, index=_bt.ids('observation'),

columns=_bt.ids('sample'))

return out

### using path to open data Users/jaysonchao/Documents/python/MacQiime_hawaii_bacteria/usearch61_open_ref_no_chimera/

# with open('16S_otu_table_mc2_w_tax_no_singletons_nolowcoverage_sorted_rarefied_40000.biom') as f:

# table = parse_table(f)

# direct load data from biom file

table_all = load_table('16S_otu_table_mc2_w_tax_no_singletons_nolowcoverage_sorted_rarefied_40000.biom')

# table_all = load_table('otu_table.biom')

otu_table = exploding_panda(table_all)

otu_table_T = otu_table.T

# print(otu_table_T.index)

index = otu_table_T.index

# center the data

# otu_table_T -= otu_table_T.mean()

## calculating bray-curtis distance matrix

DM_dist = distance.squareform(distance.pdist(otu_table_T, metric="braycurtis")) # (n x n) distance measure

DM_dist_DF = pd.DataFrame(DM_dist,index=index, columns=index)

# print(DM_dist_DF)

## transform to distance matrix for pcoa in skbio

# DM_dist = skbio.stats.distance.DistanceMatrix(Ar_dist, ids=otu_table_T.index)

# mds

seed = np.random.RandomState(seed=3)

mds = manifold.MDS(n_components=2, max_iter=3000, eps=1e-9, random_state=seed,

dissimilarity="precomputed", n_jobs=1)

pos = mds.fit(DM_dist).embedding_

# nmds

nmds = manifold.MDS(n_components=2, metric=False, max_iter=3000, eps=1e-12,

dissimilarity="precomputed", random_state=seed, n_jobs=1,

n_init=1)

npos = nmds.fit_transform(DM_dist, init=pos)

## rotate data

# npos *= np.sqrt((otu_table_T ** 2).sum()) / np.sqrt((npos ** 2).sum())

clf = PCA(n_components=2)

npos = clf.fit_transform(npos)

# print(npos)

column = ['NMDS1','NMDS2']

npos_DF = pd.DataFrame(npos,index=index, columns=column)

print(npos_DF)

## read group data and join two dataframe

group = pd.read_csv('group.csv',header=0,index_col=0)

nmds_data = pd.concat([npos_DF, group], axis=1)

print(nmds_data.index)

print(nmds_data.columns)

print(nmds_data.head)

print(nmds_data)

p1 = (ggplot(nmds_data, aes(x='NMDS1', y='NMDS2'))+

geom_point(aes(color='precipitation',shape='depth'),size=3)+ theme_classic()+scale_shape_manual(['s','^','o','<'])+

theme(axis_text=element_text(size=14,color='black',family='sans-serif'),axis_title=element_text(size=14,color='black',family='sans-serif'),legend_text= element_text(size=12,color='black',family='sans-serif'))+

theme(legend_background=element_rect(alpha=0))+

stat_ellipse(aes(group='precipitation',color='precipitation'),level = 0.75,size=0.8,geom='path',type='t')+

scale_color_manual(values=['#56B4E9', '#E69F00', '#D55E00', '#009E73', '#F0E442', '#0072B2', '#000000', '#CC79A7','#BE5C2E','#3F725D','#2CE1C9','#944F4A','#666666','#999999'])+

labs(color='',shape='')

)

p1.save(filename = 'nmds_bacteria.pdf', height=5.35, width=5, units = 'in')非度量多维尺度,一种降维排序的方法

不同于R语言中的mds函数,python机器学习包sklearn需要几步才能完成nmds的计算,plotnine对figure参数的调整和改变几乎和ggplot2相同。值得一提的是stat_ellipse()函数在一个月前刚刚更行,之前的plotnine版本中是无法使用的。plotnine包仍然在大幅度的更新,很多ggplot2具有的其他功能也正在完善,有需要的同学可以时刻关注plotnine的作者个人网页A Grammar of Graphics for Python​plotnine.readthedocs.iov2-5ecdc6d23d4bfb399fbd001304c650da_ipico.jpg

或者githubhas2k1/plotnine​github.com

另外一种方法就是可以先在R中计算出nmds的记过再导入到python中可视化,同样的在R中完成可视化也同样很方便。

在完成堆积柱状图的时候,在R中非常方便,只要将对应的数据格式转换,导入读取画图即可,plotnine同样如此,注意将所有的element.text()改成element_text()。

MyColors <- ["#E6478A","#56B4E9", "#E33D36","#7570B0", "#E69F00", "#B3DB70", "#0072B2","#DBDBD9","#944F4A","#5CB5E8","#E39E26","#BFBAD9","#8FD4C7","#DBBA29","#47A133","#945457","#F07D3D","#F5E369","#999999","#ED8CC2"]

#bar

a=(ggplot(data=ups.melt, aes(x=variable, y=value, fill=phylum)) +

geom_bar(stat="identity",width=0.94)+theme_classic()+theme(legend.title = element_blank())+theme(legend_position="right")+scale_fill_manual(values=MyColors)+theme(axis_ticks_x = element_blank(),panel_grid_major=element_blank(),panel_grid_minor=element_blank(),panel_background = element_blank())+theme(legend_text = element_text(size = 12))+theme(legend_key_size = unit(0.5, "cm"))+scale_y_continuous(expand=[0, 0, .1, 0])+labs(y="Relative Abundance",x=""+theme(axis_text_x = element_blank())相对丰度堆积柱状图

和在ggplot2中相同,bar距离x轴和y轴的距离可以通过scale_y_continuous(expand=[0,0,0.1,0])调整而不需要保留空白一看就能看出来是ggplot2画的图。当然我们也可以通过添加分面的方式,把不同的组别分开只需要加上facidwrap(~group,scale="free_x"),按照什么类型分面,可以根据自己的需求修改画图导入的metadata。相对丰度分面图

当说到分组的时候,我们通常对应不同的处理或者样地而言,有些情况下,我们不仅需要各个处理的情况,还需要知道整体,尤其是做相关性分析的时候。分组的同时也能观察并且可视化总体的情况,这是用plotnine也是很快就可以完成的。

"""

@author: Jianshu Zhao (zhaojs16@mails.tsinghua.edu.cn)

"""

import matplotlib

# Say, "the default sans-serif font is Helvetica"

matplotlib.rcParams['font.sans-serif'] = "Helvetica"

# Then, "ALWAYS use sans-serif fonts"

matplotlib.rcParams['font.family'] = "sans-serif"

import numpy as np

import matplotlib.pylab as pylab

import matplotlib.pyplot as plt

params={

'axes.labelsize': '14',

'xtick.labelsize':'14',

'ytick.labelsize':'14',

'lines.linewidth':1,

'legend.fontsize': '14',

'figure.figsize' : '6, 5.5'

pylab.rcParams.update(params)

import math

import pandas as pd

import numpy as np

from plotnine import *

from plotnine.data import *

# read dataframe and check

bacteria_ddr_group = pd.read_csv('bacteria_abundant_rare_ddr_group.csv',header=0,index_col=0)

print(bacteria_ddr_group.head())

plot_abundant=(ggplot(bacteria_ddr_group,aes(x='geodis_log',y='bray_abundant_log'))+geom_point(aes(color='category'),size=0.5)+theme_classic()+

stat_smooth(aes(color='category'),method='lm',se=False)+

scale_color_manual(values=['#1AA68C', '#D55E00','#56B4E9'])+

stat_smooth(method='lm',color='grey',se=False)+

theme(legend_position=(0.3,0.3))+theme(legend_background=element_rect(alpha=0))+theme(axis_text=element_text(size=12,color='black',family='sans-serif'),axis_title=element_text(size=13,color='black',family='sans-serif'),

legend_text= element_text(size=12,color='black',family='sans-serif'),legend_title= element_text(size=12,color='black',family='sans-serif')))

plot_abundant.save('bacter_ddr11.pdf',width=6, height=5.5)做相关性分析分组和整体

我们可以同时按照分组和不分组的方式对x和y做相关性分析,这个和其他可视化软件比如sigmaplot相比就显得非常人性化,可以同时叠加多个图层,而在sigmaplot则可能需要添加新的数据分组。

以上主要介绍简单的分组方式。最近太忙了,乘着坐飞机的空隙写的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值