关于程序员:ggplot2绘图如果做出来的图颜色区分度不明显如何对数据进行转换

32次阅读

共计 6290 个字符,预计需要花费 16 分钟才能阅读完成。

明天分享的学习笔记:异样绘图数据转换方法(对数法,评分法,踢值法,色彩法),用于对热图进行润饰。

ggplot2 中绘制热图时,有时候会遇到数据的组间差别太大,导致可视化后果不显著(色彩区分度较低),因而学习几种对非凡数据的解决办法,使热图出现的成果更好。

生成原始数据

创立一组数据,蕴含 4 个不同的样本(a 等 4 行),5 个不同的变量(Grp1 等 5 列),其中不同样本间的均值差别较大。

> data <- c(rnorm(5,mean=5),rnorm(5,mean=20),rnorm(5,mean=100),c(600,700,800,900,10000))
> data <- c(rnorm(5,mean=5),rnorm(5,mean=20),rnorm(5,mean=100),c(600,700,800,900,10000))
> #rnorm 函数可能随机生成一组正态分布的数据
> data <- matrix(data,ncol = 5,byrow=T)
> #将数据转化为矩阵格局
> data <- as.data.frame(data) #转化为数据框
> rownames(data) <- letters[1:4] #行名设置为小写字母 abcd
> colnames(data) <- paste("Grp",1:5,sep="_") #列名设置为 Grp+ 序号
> data #查看一下以后的数据
      Grp_1      Grp_2      Grp_3      Grp_4        Grp_5
a   4.31371   6.520402   5.049561   5.013933     6.716523
b  18.68553  19.702193  20.845860  21.102063    19.592703
c  99.00071  99.310800  99.422325 101.114502   100.693449
d 600.00000 700.000000 800.000000 900.000000 10000.000000

转换数据模式

刚刚创立的原始数据是 4 行 5 列的数据框,须要将其转化成相似 id~value 的长数据模式(行数变多,列数减小,理论数据表白内容雷同)

这种长数据用于后续的 ggplot2 作图应用,该转换过程的原理和办法我之前的笔记中有记录,欢送查阅。

> data$ID <- rownames(data) 
#增加新列,列的内容为以后数据框的行名
> data_1 <- melt(data,id.vars = c("ID")) 
#将矩阵交融变成长类型(用于绘图,列数少,看起来又窄又长)> head(data_1) #查看以后数据的前几行
  ID variable      value
1  a    Grp_1   4.313710
2  b    Grp_1  18.685532
3  c    Grp_1  99.000713
4  d    Grp_1 600.000000 #在此能够发现这一个的值和后面的相比很大很突出。5  a    Grp_2   6.520402
6  b    Grp_2  19.702193

绘图后果

利用 ggplot 函数绘制热图,能够发现下图中只有右上角的色彩比拟深,其余区域没有显著差异,这样的后果看不出差异性,须要对数据进一步转换。

p <- ggplot(data_1,aes(x=variable,y=ID)) +
  xlab("samples") + theme_bw() + 
  theme(panel.grid.major = element_blank()) + theme(legend.key = element_blank()) +
  theme(axis.text.x = element_text(angle=45,hjust = 1,vjust = 1)) +
  theme(legend.position = "top") + geom_tile(aes(fill=value)) +
  scale_fill_gradient(low="white",high="blue")
p 

数据的转换方法

依据材料提供的信息,这里介绍 对数法、评分法、踢值法、色彩法 四种计划。

对数法

对数函数可能将数据之间的绝对差异性进行转换,依据对数的图像能够看出,特大数值的差异性被压缩,绝对投影长度变小,以便于和较小数值处于同一基准规定进行差别比拟。

因而,首先将原始 data 数据通过对数转化,而后再对转化后的数据 增加 ID 列 转成长数据模式(简称为“两步走”)

> data_l <- log2(data+1) #对原始数据进行对数运算
> data_l #查看转换后的数据
     Grp_1    Grp_2    Grp_3    Grp_4     Grp_5
a 2.545781 2.076924 2.316681 2.473611  2.919831
b 4.302711 4.432475 4.355503 4.441871  4.439853
c 6.675369 6.675384 6.687525 6.650458  6.659354
d 9.231221 9.453271 9.645658 9.815383 13.287857
> data_l$ID <- rownames(data_l) 
#对转换后的数据增加新列,内容为数据的行名
> data_lm <- melt(data_l,id.vars = c("ID")) 
#对数据进行交融,转化成长数据用于绘图

须要留神的是,这两步骤不能调换程序,因为我测试时先增加了 ID 导致对数转化失败,应该先对数值进行解决。

从新绘图 之后,呈现了肉眼可见的差别哈哈哈哈哈!

p <- ggplot(data_lm,aes(x=variable,y=ID)) +
  xlab("samples") +ylab(NULL) +
  theme_bw() + theme(panel.grid.major = element_blank()) +
  theme(legend.key = element_blank()) + theme(legend.position = "top") +
  theme(axis.text.x = element_text(angle = 45,hjust = 1,vjust = 1)) +
  geom_tile(aes(fill=value)) + scale_fill_gradient(low="green",high = "blue")
p

对数法尽管有用,但也有局限性。

比方下面生成的图中绿色局部的区分度依然很低,接下来用新的测试数据来演示另外三种形式。

评分法

原名叫 Z -score 转化法,顾名思义:就是将成正态分布的数据中的原始分数转换为 z 分数,而 z 分数可能实在的反馈一个分数间隔平均数的绝对规范间隔,通过这种形式保留数据的实在差别。

首先,从新创立一个非凡的数据集,用于该办法的演示。能够看出不论是同一行(样品内)还是同一列(变量内),数值的差别幅度都很大。

> data
  Grp_1 Grp_2 Grp_3 Grp_4   Grp_5
a   6.6  20.9 100.1 600.0     5.2
b  20.8  99.8 700.0   3.7    19.2
c 100.0 800.0   6.2  21.4    98.6
d 900.0   3.3  20.3 101.1 10000.0

先去除数据中的烦扰项,而后标准化并设定列名,实现后输入查看这个时候的数据状态。

data <- data[apply(data,1,var)!=0,] 
#去除烦扰项,"!=" 示意不等于
> data_s <- as.data.frame(t(apply(data,1,scale))) 
#对数据进行标准化并转化成数据框
> colnames(data_s) <- colnames(data) #设置列名
> data_s #查看标准化解决后数据状态
       Grp_1      Grp_2      Grp_3      Grp_4      Grp_5
a -0.5456953 -0.4899405 -0.1811446  1.7679341 -0.5511538
b -0.4940465 -0.2301542  1.7747592 -0.5511674 -0.4993911
c -0.3139042  1.7740182 -0.5936858 -0.5483481 -0.3180801
d -0.2983707 -0.5033986 -0.4995116 -0.4810369  1.7823177

对解决后的数据进行“两步走”操作,而后将 value 的值转化成 z 分数格局。

> data_s$ID <- rownames(data_s) #增加新的一列,内容为数据的行名
> data_s_m <- melt(data_s,id.vars = c("ID")) #以新增加的行为规范交融数据
> data_s_m$value <- as.numeric(prettyNum(data_s_m$value,digits=2)) #将 value 的值转化为分数格局

进行绘图能够发现,此时数据之间的差异性可视化成果显著。

p <- ggplot(data_s_m,aes(x=variable,y=ID)) + xlab("samples") +
  ylab(NULL) +theme_bw() + theme(panel.grid.major = element_blank()) +
  theme(axis.text.x = element_text(angle=45,hjust = 1,vjust=1)) +
  geom_tile(aes(fill=value)) +scale_fill_gradient(low="pink",high="blue") +
  geom_text(aes(label=value))
p

踢值法

这个也叫抹去异样值法,就是将特地离谱的数据全副抹去(用正常值代替),在理论利用中须要酌情思考。
这里应用上一个办法中创立的数据做演示。

外围解决就一行,把大于 100 的值全变成 100 即可。

data_3[data_3>100] <- 100 #将大于 100 的值变成 100

而后进行规范“两步走”,生成的最终数据就没有特地离谱的值,能够释怀用于绘图。

> data_3$ID = rownames(data_3) #增加新列 ID
> data_3_m <- melt(data_3, id.vars=c("ID")) #以 ID 列为准交融数据
> head(data_3_m) #查看交融后数据的前几行
  ID variable value
1  a    Grp_1   6.6
2  b    Grp_1  20.8
3  c    Grp_1 100.0
4  d    Grp_1 100.0
5  a    Grp_2  20.9
6  b    Grp_2  99.8

绘制图像,发现数据之间的差异性比拟显著,然而这种办法的准确性比拟差,损失了一些数据的趋势信息。

p <- ggplot(data_3_m,aes(x=variable,y=ID)) +
  xlab("samples") +
  ylab(NULL) +
  theme_bw() + 
  theme(panel.grid.major= element_blank()) +
  theme(legend.key=element_blank()) +
  theme(axis.text.x=element_text(angle=45,hjust=1,vjust=1)) +
  geom_tile(aes(fill=value)) + 
  scale_fill_gradient(low = "red",high="green") +
  geom_text(aes(label=value))
p  

色彩法

也称为非线性色彩法,这种办法很妙,几乎妙的呱呱叫! 体现出了一种“山不过去,我就过来”的思维。

色彩在最小值到最大值之间是均匀分布的。如果最小值到最大值之间用 100 个色彩辨别,其中每一个值都会赋予一个色彩。非线性色彩则是对数据比拟小但密集的中央赋予更多色彩,数据大但散布散的中央赋予更少色彩,这样既能加大区分度,又不影响原始数值。

图里色彩看不出显著差别,先不论数据有啥问题,间接把色彩改成差别的就完事儿,使可视化后果趋于显著。

首先,创立用于示例的数据:

先进行“两步走”,而后再利用 summary 函数获取 value 变量的数据信息(最小值,一分位值,中位值,三分位值,最大值)

> data_4$ID=rownames(data_4) #增加新 ID 列
> data_4_m <- melt(data_4,id.vars = c("ID")) #交融数据,生成用于绘图的数据格式
> summary_v <- summary(data_4_m$value) #计算数据的最小值,一分位值,中位值,三分位值,最大值
> summary_v #查看上一行计算的后果
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
    3.30    16.05    60.00   681.36   225.82 10000.00 

在最小值和第一四分位数之间划出 6 个区间,第一四分位数和中位数之间划出 6 个区间,中位数和第三四分位数之间划出 5 个区间,最初的数划出 5 个区间,并查看划分后果。

> break_v <- unique(c(seq(summary_v[1]*0.95,summary_v[2],length=6),
+                     seq(summary_v[2],summary_v[3],length=6),
+                     seq(summary_v[3],summary_v[5],length=5),
+                     seq(summary_v[5],summary_v[6]*1.05,length=5)))
> break_v #查看划分的后果
 [1]     3.1350     5.7180     8.3010    10.8840    13.4670    16.0500    24.8400    33.6300
 [9]    42.4200    51.2100    60.0000   101.4562   142.9125   184.3687   225.8250  2794.3687
[17]  5362.9125  7931.4562 10500.0000

用新划分的区间数值替换原来的数值,并查看以后的数值状态。

> data_4_m$value <- cut(data_4_m$value,breaks = break_v,
+                       labels = break_v[2:length(break_v)]) #利用刚刚生成的划分区间设置切割标签
> break_v=unique(data_4_m$value) 
> head(data_4_m,3)#查看以后的数据状态
   ID variable      value
1   a    Grp_1      8.301
2   b    Grp_1      24.84
3   c    Grp_1  101.45625

判断一下生成的数据 value 列是否为因子格局,而后设置色彩并生成一系列色彩值。

> is.factor(data_4_m$value) # 判断一下以后数据的 value 列是否为因子格局
[1] TRUE
> gradient_1=c("yellow","blue","green") #设置色彩
> col <- colorRampPalette(gradient_1)(length(break_v)) #利用划分的区间后果生成一组色彩值
> col #查看所生成的色彩数据
[1] "#FFFF00" "#999966" "#3232CC" "#0033CB" "#009965" "#00FF00"

用新生成的色彩值进行填充绘图,能够看出数据间色彩差异性比拟显著。

p <- ggplot(data_4_m,aes(x=variable,y=ID)) +
  xlab("sam") +
  ylab(NULL) +
  theme_bw() +
  theme(panel.grid.major = element_blank()) +
  theme(legend.key = element_blank()) + 
  theme(axis.text.x=element_text(angle=35,hjust = 0.9,vjust = 0.9)) +
  geom_tile(aes(fill=value))
#利用色彩填充信息
p <- p + scale_fill_manual(values = col)
p

本笔记参考学习材料:http://www.ehbio.com/Bioinfo_…

本文由 mdnice 多平台公布

正文完
 0