image image image
问答社区:http://www.omicsclass.com/ 组学大讲堂公众号 生信课堂

image image image
课程推荐1:R语言入门与基础绘图 课程推荐2:R语言绘图(ggplot) 所有生信课程:点击

1 ggplot绘图基本思想

一张统计图形是从数据几何对象图形属性的一个映射。此外,图形中还可能包含数据的统计变换,最后绘制在某个特定的坐标系中,而分面则可以用来生成数据不同子集的图形。

  • 映射(mapping):是把你想要可视化的数据(data)中的一系列变量对应到图形中不同的属性;

  • 几何对象(geom):在图中实际看到的图形元素,如点、线、多边形等;

  • 统计变换(stats):对数据进行的某种汇总,如分组计数、线性回归等。可选,但很有用。

  • 标度(scale):将数据的取值映射到图形空间,如用颜色、大小或形状来表示不同的取值,使读者可以从图形中读取原始数据一些信息。展现方式为绘制图例和坐标轴。

  • 坐标系(coord):描述数据是如何映射到图形所在的平面,同时提供看图所需的坐标轴和网络线。通常使用笛卡尔坐标系,但也可以变换为其他类型,如极坐标和地图投影。

  • 分面(facet):描述如何将数据分解为各个子集,以及如何对子集作图并联合进行展示。分面也称为条件作图或网格作图。

ggplot2官方帮助文档:https://ggplot2.tidyverse.org/reference/index.html

2 示例代码

2.1 加载包和示例数据

library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
dim(diamonds) #示例数据
## [1] 53940    10
#随机选取1000行数据,减少数据量加快绘图时间
mydiamonds<-sample_n(diamonds,1000)

2.2 数据图形geom和映射aes

ggplot中“+” 运算符,可以多次使用,添加不同的图层。

#点图
ggplot(data=mydiamonds,mapping=aes(x=carat,y=price))+geom_point()

# 增加点的颜色映射
ggplot(data=mydiamonds,aes(x=carat,y=price,color=color))+geom_point()

ggplot(data=mydiamonds,aes(x=carat,y=price,color=color,shape=cut))+geom_point()
## Warning: Using shapes for an ordinal variable is not advised

#box图
ggplot(data=mydiamonds,aes(x=color,y=price))+geom_boxplot()

#柱状图
ggplot(data=mydiamonds,aes(x=color))+geom_bar()

#增加颜色映射
ggplot(data=mydiamonds,aes(x=color,fill=clarity))+geom_bar()

#频率直方图
ggplot(data=mydiamonds,aes(x=price))+geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.

ggplot(data=mydiamonds,aes(x=price))+geom_histogram(binwidth = 1000)

ggplot(data=mydiamonds,aes(x=price,fill=color))+geom_histogram(binwidth = 1000)

#密度分布图
ggplot(data=mydiamonds,aes(x=price))+geom_density()

ggplot(data=mydiamonds,aes(x=price,color=color))+geom_density()

2.3 图层叠加

ggplot中“+” 运算符,可以多次使用,添加不同的图层。

p<-ggplot(data=mydiamonds,aes(x=carat,y=price))+geom_point()
print(p)

p<-ggplot(data=mydiamonds,aes(x=carat,y=price))+geom_point()+geom_smooth()
print(p)
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

p<-ggplot(data=mydiamonds,aes(x=carat,y=price))+geom_point()+geom_line()
print(p)

3 图形调整美化

3.1 标题 label修改

  • xlab()
  • ylab()
  • labs()
  • ggtitle()
p<-ggplot(data=mydiamonds,aes(x=carat,y=price,color=cut))+geom_point()
print(p)

p1<-p+  xlab("Carat")+ylab("Price")+ggtitle("mydiamonds")
print(p1)

#或者
p2<-p+  labs(x="Carat",y="Price",title="mydiamonds",color="my cut")
print(p2)

3.2 scale 标度修改

颜色标度修改,color代表点线的设置,fill填充颜色设置

以下为修改颜色的方法

scale_color_hue()

scale_fill_hue()

scale_color_brewer()

scale_fill_brewer()

scale_color_manual() 手动设置颜色

scale_fill_manual() 手动设置颜色

#修改配色方案
#柱状图用fill设置颜色映射
ggplot(data=mydiamonds,aes(x=price,fill=color))+geom_histogram(binwidth = 1000)

#修改一下配色
ggplot(data=mydiamonds,aes(x=price,fill=color))+geom_histogram(binwidth = 1000)+
  scale_fill_hue()

#借用一下第三方配色方案 RColorbrewer
ggplot(data=mydiamonds,aes(x=price,fill=color))+geom_histogram(binwidth = 1000)+
  scale_fill_brewer(palette = "Set1")

#DIY 设置自己喜欢的颜色,并且指定分组各自的颜色
mycolor<-c(F="#E41A1C", D="#377EB8",E= "#4DAF4A" ,I="#984EA3" ,H="#FF7F00" ,J="#FFFF33" ,G="#A65628")
ggplot(data=mydiamonds,aes(x=price,fill=color))+geom_histogram(binwidth = 1000)+
  scale_fill_manual(values=mycolor)

####同样的道理对于点的颜色设置,使用color:

ggplot(data=mydiamonds, aes(carat, price)) + geom_point(aes(colour = clarity))

#修改一下配色,注意 用的scale_color_hue(),大家也可以用用一下scale_fill_hue() 看看有什么效果?
ggplot(data=mydiamonds, aes(carat, price)) + geom_point(aes(colour = clarity))+scale_color_hue()

#借用一下第三方配色方案 RColorbrewer
ggplot(data=mydiamonds, aes(carat, price)) + geom_point(aes(colour = clarity))+scale_color_brewer(palette = "Set1")

#自己设置喜欢的颜色
ggplot(data=mydiamonds,aes(carat, price,color=color))+geom_point()+
        scale_color_manual(values=c("#66C2A5", "#FC8D62", "#8DA0CB", "#E78AC3" ,"#A6D854", "#FFD92F","#E5C494" ,"#B3B3B3"))

3.3 shape 修改

注意:有些shape 只能设置边框颜色,不能设置填充色,有些都可以设置

R语言常用shape 编号对应形状 输出:

# 创建数据
df <- data.frame(
  x = rep(5:1, 5),
  y = rep(1:5, each = 5),
  shape = 24:0
)

# 绘图
ggplot(df, aes(x = x, y = y)) +
  geom_point(aes(shape = factor(shape)), 
             size = 4, 
             colour = "red", 
             fill = "blue") +
  geom_text(aes(y = y - 0.3, label = shape), size = 3) +
  scale_shape_manual(values = 0:24) +
  theme_void() +
  labs(title = "Shape 样式 (红色边框,蓝色填充)") +
  theme(plot.title = element_text(hjust = 0.5))

aes中映射shape

ggplot(data=mydiamonds,aes(x=carat,y=price,shape=cut,color=cut))+geom_point()+
  xlab("Carat")+ylab("Price")+ggtitle("mydiamonds")
## Warning: Using shapes for an ordinal variable is not advised

#修改shape
ggplot(data=mydiamonds,aes(x=carat,y=price,shape=cut,color=cut))+geom_point()+
  xlab("Carat")+ylab("Price")+ggtitle("mydiamonds")+
  scale_shape_manual(values = c(1,2,6,0,23))

3.4 坐标轴修改

#坐标轴label修改,非连续型坐标轴:scale_x_discrete(),scale_y_discrete()

p<-ggplot(mydiamonds, aes(cut)) + geom_bar()
print(p)

p+scale_x_discrete("Cut", labels = c("Fair" = "F","Good" = "G","Very Good" = "VG","Perfect" = "P","Ideal" = "I"))

#坐标轴label修改,连续型坐标:scale_x_continuous(),scale_y_continuous()
p<-ggplot(data=mydiamonds,aes(x=carat,y=price))+geom_point()
print(p)

p+scale_x_continuous("Carat") +scale_y_continuous("Price")  #修改坐标轴标题

p + scale_x_continuous(limits = c(0, 2))
## Warning: Removed 43 rows containing missing values or values outside the scale range
## (`geom_point()`).

p+scale_x_continuous(breaks = c(1,3),label = c( "one","three"))

4 主题theme()修改

  • 修改绘图显示样式,美化我们的图片
  • 找到图形中对应的主题元素名称,然后使用对应的方法在theme()中进行修改:

例如:图片的title主题元素名称为plot.title,类型是文字,用element_text()方法修改显示样式,如字号调大一下:

p1<-ggplot(mtcars, aes(wt, mpg)) +geom_point() +labs(title="Fuel economy declines as weight increases")
p1

p1 + theme(plot.title=element_text(size=rel(2)))

  • 主题元素名称总结
  • 对应修改方法
类型 修改方法
line,segment element_line()
rect element_rect()
text element_text()

另外:还有一个方法 element_blank() 表示什么都不画,清除。

更多主题修改:https://ggplot2.tidyverse.org/reference/theme.html

4.1 以下为修改主图的 示例代码

4.1.1 text 修改 element_text()

方法中的选项意义:

  • family:Font family
  • face : Font face (“plain”, “italic”, “bold”, “bold.italic”)
  • hjust : Horizontal justification (in [0, 1])
  • vjust : Vertical justification (in [0, 1])
  • angle : Angle (in [0, 360])
  • lineheight : Line height
ggplot(data=mydiamonds,aes(x=price))+geom_histogram(binwidth = 1000)+
  theme(axis.text.x=element_text(color="red",angle=45),
        axis.text.y=element_text(color="red"),
        axis.title.x =element_text(color="blue",face="bold"),
        axis.title.y=element_text(color="blue",face="bold",angle = 90)
        
        )

4.1.2 矩形框的修改:element_rect()

方法中的一些选项意义:

  • fill: Fill colour.
  • colour: colorLine/border colour. Color is an alias for colour.
  • size: Line/border size in mm; text size in pts.
  • linetype: Line type. An integer (0:8), a name (blank, solid, dashed, dotted, dotdash, longdash, twodash), or a string with an even number (up to eight) of hexadecimal digits which give the lengths in consecutive positions in the string.
ggplot(data=mydiamonds,aes(x=price))+geom_histogram(binwidth = 1000)

p<-ggplot(data=mydiamonds,aes(x=price))+geom_histogram(binwidth = 1000)
print(p)

p+theme(plot.background = element_rect(fill="red"),
        panel.background = element_rect(fill="blue"))

线修改:element_line()

  • colour 或者 color :Line/border colour. Color is an alias for colour.
  • size: Line/border size in mm; text size in pts.
  • linetype: Line type. An integer (0:8), a name (blank, solid, dashed, dotted, dotdash, longdash, twodash), or a string with an even number (up to eight) of hexadecimal digits which give the lengths in consecutive positions in the string.
p<-ggplot(data=mydiamonds,aes(x=price))+geom_histogram(binwidth = 1000)

p+theme(panel.grid.major = element_line(color="red"),
        panel.grid.minor = element_line(color="blue",linetype = "dashed"),
        panel.background = element_blank()
)

p+theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank()
)

p+theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.line = element_line(color="red",linewidth=1)
)

#利用:panel.background 设置绘图边框
p+theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_rect(fill=NA,color = "red",linewidth=2),
        axis.line = element_line(color="red",size=1)
)
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

4.1.3 图例部分修改

p<-ggplot(data=mydiamonds,aes(x=carat,y=price,shape=cut,color=cut))+geom_point()+
  xlab("Carat")+ylab("Price")+ggtitle("mydiamonds")+
  scale_shape_manual(values = c(1,2,6,0,23))
print(p)

#修改legend

#可以直接删除
p+theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_rect(fill=NA,color = "red",linewidth=2),
        legend.position='none'
)

p+theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_rect(fill=NA,color = "red",linewidth=2),

        legend.key = element_blank(),
        legend.title = element_blank()
)

4.2 使用内置主题,减少设置

p<-ggplot(data=mydiamonds,aes(x=carat,y=price,color=cut))+geom_point()+
  xlab("Carat")+ylab("Price")+ggtitle("mydiamonds")+scale_color_brewer(palette = "Set1")
p+theme_bw()

p+theme_linedraw()

p+theme_light()

p+theme_dark()

p+theme_classic()

5 存储输出图片:

存储图片尺寸与分辨率要符合杂志要求,参考:https://www.omicsclass.com/article/330

#使用绘图设备输出
pdf(file="out.pdf",width = 4,height = 4)
print(p)
dev.off()

png(filename =  "out.png",width = 4,height = 4,units = "in",res=300)
print(p)
dev.off()

#也可以用ggplot自带的方法输出图片
ggsave(filename = "out1.png",width =4,height = 4,units = "in",dpi=300)
ggsave(filename = "out1.pdf",width = 4,height = 4)

6 本文档使用R包版本信息

sessionInfo()
## R version 4.4.2 (2024-10-31)
## Platform: x86_64-pc-linux-gnu
## Running under: Rocky Linux 9.4 (Blue Onyx)
## 
## Matrix products: default
## BLAS:   /share/biosoft/R/R-v4.4.2/lib64/R/lib/libRblas.so 
## LAPACK: /share/biosoft/R/R-v4.4.2/lib64/R/lib/libRlapack.so;  LAPACK version 3.12.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: Asia/Shanghai
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] dplyr_1.2.1   ggplot2_4.0.2
## 
## loaded via a namespace (and not attached):
##  [1] Matrix_1.7-5       gtable_0.3.6       jsonlite_2.0.0     compiler_4.4.2    
##  [5] tidyselect_1.2.1   dichromat_2.0-0.1  jquerylib_0.1.4    splines_4.4.2     
##  [9] scales_1.4.0       yaml_2.3.12        fastmap_1.2.0      lattice_0.22-9    
## [13] R6_2.6.1           labeling_0.4.3     generics_0.1.4     knitr_1.51        
## [17] tibble_3.3.1       bslib_0.10.0       pillar_1.11.1      RColorBrewer_1.1-3
## [21] rlang_1.2.0        cachem_1.1.0       xfun_0.57          sass_0.4.10       
## [25] S7_0.2.1           otel_0.2.0         viridisLite_0.4.3  cli_3.6.6         
## [29] withr_3.0.2        magrittr_2.0.5     mgcv_1.9-4         digest_0.6.39     
## [33] grid_4.4.2         rstudioapi_0.18.0  lifecycle_1.0.5    nlme_3.1-169      
## [37] vctrs_0.7.2        evaluate_1.0.5     glue_1.8.0         farver_2.1.2      
## [41] rmarkdown_2.31     tools_4.4.2        pkgconfig_2.0.3    htmltools_0.5.9