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

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_5a   4.31371   6.520402   5.049561   5.013933     6.716523b  18.68553  19.702193  20.845860  21.102063    19.592703c  99.00071  99.310800  99.422325 101.114502   100.693449d 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      value1  a    Grp_1   4.3137102  b    Grp_1  18.6855323  c    Grp_1  99.0007134  d    Grp_1 600.000000 #在此可以发现这一个的值和前面的相比很大很突出。5  a    Grp_2   6.5204026  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_5a 2.545781 2.076924 2.316681 2.473611  2.919831b 4.302711 4.432475 4.355503 4.441871  4.439853c 6.675369 6.675384 6.687525 6.650458  6.659354d 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_5a   6.6  20.9 100.1 600.0     5.2b  20.8  99.8 700.0   3.7    19.2c 100.0 800.0   6.2  21.4    98.6d 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_5a -0.5456953 -0.4899405 -0.1811446  1.7679341 -0.5511538b -0.4940465 -0.2301542  1.7747592 -0.5511674 -0.4993911c -0.3139042  1.7740182 -0.5936858 -0.5483481 -0.3180801d -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 value1  a    Grp_1   6.62  b    Grp_1  20.83  c    Grp_1 100.04  d    Grp_1 100.05  a    Grp_2  20.96  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      value1   a    Grp_1      8.3012   b    Grp_1      24.843   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_R_course/Rplots.html#ggplot2_heatmapnonlinear

本文由 mdnice 多平台发布

ggplot2绘图:如果做出来的图颜色区分度不明显,如何对数据进行转换?相关推荐

  1. 数据可视化——R语言ggplot2包绘制相关矩阵为热图

    数据可视化--R语言ggplot2包绘制相关矩阵为热图 概述:R语言软件和数据可视化--ggplot2快速绘制相关矩阵为热图.本文翻译了一篇英文博客,博客原文链接:http://www.sthda.c ...

  2. ggplot2绘图:qPCR数据箱式图叠加散点图1

    小白新手,加速记忆,先整理个帖子 正题: install.packages('gg.gap')library(ggplot2)#首次用需要先安装install.packages('ggplot2') ...

  3. R语言(ggplot2绘图)

    原文链接:https://wklchris.github.io/R-ggplot2.html ggplot2 的语法与 R 原生的语法并不统一,但是熟悉起来也并不复杂.它主要通过"+&quo ...

  4. 20180507-A · Global Coffee Chains · ggplot2 usmap geom_map geom_point 地图 热图 美国地图 · R 语言数据可视化 案例 源码

    所有作品合集传送门: Tidy Tuesday 2018 年合集传送门: 2018 Global Coffee Chains 欢迎来到ggplot2的世界! ggplot2是一个用来绘制统计图形的 R ...

  5. 数据可视化——R语言ggplot2包绘制精美的小提琴图(并箱线图或误差条图组合)

    数据可视化--R语言ggplot2包绘制精美的小提琴图(并箱线图或误差条图组合) 概述:R语言使用ggplot2工具包绘制小提琴图.为了使数据表达更加丰富,同时将小提琴图与箱线图和误差条图相结合.另外 ...

  6. R统计绘图 | 物种组成堆叠面积图(绝对/相对丰度,ggalluvial)

    一.数据准备 数据使用的不同处理土壤样品的微生物组成数据,包含物种丰度,分类单元和样本分组数据.此数据为虚构,可用于练习,请不要作他用. # 1.1 设置工作路径 #knitr::opts_knit$ ...

  7. 不需要懂得编程,但却可以使用ggplot2画出论文级别的图?

    你有没有遇到过这样的烦恼,你需要画一些论文级别的图,并且你知道R中的ggplot2是一个很好的选择,可以画出符合你要求的图.但是由于你不熟悉ggplot2的使用,你需要上网倒弄一番,了解与你图相关的代 ...

  8. owc_绘图区(PlotArea)背景显示多种颜色

    owc_绘图区(PlotArea)背景显示多种颜色 阅读(62) 评论(0) 发表时间:2008年07月21日 10:28 本文地址:http://www.cnblogs.com/no7dw/admi ...

  9. 用php怎么输出饼状图,php绘图之生成饼状图的方法_PHP

    本文实例讲述了php绘图之生成饼状图的方法.分享给大家供大家参考.具体如下: 这里要实现的功能是人口分布比例图,由扇形组成一个圆,每个扇形颜色不一样. 代码如下: $array = array(&qu ...

最新文章

  1. PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.15. JSON 函数和操作符...
  2. NR 5G 用户平面协议
  3. 结构体重定义冲突_有意减脂、调整饮食,体重却增加了?
  4. 获取设备IMEI ,手机名称,系统SDK版本号,系统版本号
  5. 【笔记篇】C#笔记2
  6. angular 构建可以动态挂载的配置服务
  7. ArcGIS实验教程——实验七:矢量数据空间校正(Spatial Adjustment)
  8. 飞畅科技-交换机的三种交换方式详解
  9. think in java - 第一章 学习笔记
  10. 问题 D: 最小生成树II
  11. discuz仿文明争霸游戏官网模版
  12. 微软操作系统 Windows Server 2012 R2 官方原版镜像-转载
  13. flyme android 7 root,魅族PRO7怎么Root?魅族PRO7一键ROOT权限获取图文教程(系统自带Root功能)...
  14. 网络爬虫排除协议robots.txt介绍及写法详解.
  15. 逻辑右移、算术右移与循环逻辑右移
  16. linux 切换java_Linux中切换java的版本
  17. 自动给多个视频进行画面裁切,裁剪成一样的尺寸
  18. 最精密的尺子,平面激光干涉仪的原理与应用
  19. json c语言开发,JSON c语言开发指南
  20. Python爬虫(学习笔记)

热门文章

  1. 笔试|蓝鸽|C++岗
  2. JAVA加密狗(JAVA程序加密保护,防拷贝和防止反编译)
  3. Dictionary介绍
  4. APM32F103CBT6调试接口复用为GPIO配置问题
  5. 苹果计算机次方怎么按,详细的mac计算器操作技巧+快捷键分享~
  6. VMware 虚拟机硬盘扩容
  7. 服务器无法重命名 请确定磁盘未满或未被写保护而且文件夹未被使,请确定磁盘未满或未被写保护而且文件未被使用 解决办法...
  8. PyTorch学习笔记(13)——强力的可视化工具visdom
  9. npm 查看源地址以及更换源地址的方法
  10. 惠科股份周末听曹总监培训的感言