专栏名称: 生信宝典
生物信息分析入门、晋级和经验分享。Linux、R、Python学习教程;高通量测序数据分析学习教程;生信软件安装教程。所有内容均为原创分享,致力于从基础学习到提高整个过程。
目录
相关文章推荐
BioArt  ·  两天5篇《Nature》!Incucyte杀 ... ·  3 天前  
生物学霸  ·  19 ... ·  3 天前  
BioArt  ·  Nat Commun | ... ·  4 天前  
生物学霸  ·  Nature:建立一个实验室网站为什么很重要 ·  5 天前  
BioArt  ·  剑桥大学Science/Cell双发:新型特 ... ·  1 周前  
51好读  ›  专栏  ›  生信宝典

ggplot2画图:如何将散点图的坐标轴居中?

生信宝典  · 公众号  · 生物  · 2024-11-21 21:00

正文

今天来教大家怎么在用使用ggplot2画散点图的时候将坐标轴居中,即将两个坐标轴交叉位置设置为原点(0,0)。


1、需求描述

默认情况下,在使用ggplot2画散点图时,x 坐标轴位于图片最底部,y 坐标轴位于图片最左边,比如我们生成一个示例数据来画散点图,代码如下:

library(ggplot2)
set.seed(6)# 设置随机种子,当随机种子固定后,生成的随机数将不会发生变化dfdata.frame(x=rnorm(50),y=rnorm(50))
## 绘制 x 和 y 的散点图ggplot(df, aes(x=x,y=y))+ geom_point()+ theme_classic()# 一种 ggplot2 主题,会仅显示坐标轴,并且不显示网格

上述代码所绘制的散点图如下所示:

从图中可以发现,x 和 y 坐标轴分别位于图片的最底部和最左边。

但是有时候我们想要将 x 和 y 坐标轴的交叉点放到(0, 0)的位置,这样可以更加清晰地分辨出四个象限,也会容易观察出数据的 pattern。

然而ggplot2中并没有合适的函数可以实现这个需求,因此我们需要自定义函数来实现该功能。


2、需求实现

由于ggplot2中的坐标轴本质上就是两条线,并且ggplot2提供了函数(geom_line)来绘制直线,也提供了函数(annotate)在图中添加注释,因此我们可以借助这些函数来绘制坐标轴直线、坐标轴刻度和标签。

下面定义一个函数(theme_with_xy_centered)来将 x 和 y 坐标轴居中(代码有些长,并添加了较为详细的注释):

theme_with_xy_centered     xlimit, ylimit,     xgeo = 0, 
ygeo =
0, color = "black",
xlab =
"x", ylab = "y",
num_ticks =
10, lab_textsize = 4,
tick_textsize =
3, linewidth = 1,
epsilon = max(xlimit,ylimit)/
50) {
# modified from https://stackoverflow.com/questions/17753101/center-x-and-y-axis-with-ggplot2
# 参数说明: # xlimit: x坐标轴的范围
# ylimit: y坐标轴的范围 # xgeo : y轴向x轴偏移的距离,为0时表示不偏移,即y轴位于 x=0 直线上
# ygeo : x轴向y轴偏移的距离,为0时表示不偏移,即x轴位于 y=0 直线上 # color: 坐标轴的颜色,默认是黑色
# xlab : x 坐标轴的标签 # ylab : y 坐标轴的标签
# num_ticks: 在每个坐标轴上添加的刻度数目,默认是10个刻度 # lab_textsize: x和y轴标签的大小
# tick_textsize: x和y轴刻度上的标签的大小 # linewidth: 坐标轴和刻度的宽度
# epsilon: 该参数通常设置为很小的值,表示坐标轴刻度的长度
# 新的坐标轴的位置 xaxis 2))
yaxis 2), y_ax = c(-ylimit, ylimit))
# 添加新的坐标轴 theme.list theme_void(), # 将当前图片的主题设置为空,避免影响后续主题设置 geom_line(aes(x = x_ax, y = y_ax), color = color, data = xaxis, linewidth=linewidth),
geom_line(aes(
x = x_ax, y = y_ax), color = color, data = yaxis, linewidth=linewidth), # 添加x轴标签
annotate(
"text", x = xlimit + 2*epsilon, y = ygeo, label = xlab, size = lab_textsize, vjust=-0.5, hjust=1), # 添加y轴标签
annotate(
"text", x = xgeo, y = ylimit + 4*epsilon, label = ylab, size = lab_textsize, vjust=-0.3), xlim(-xlimit - 7*epsilon, xlimit + 7*epsilon), # 在坐标轴添加范围限制
ylim(-ylimit -
7*epsilon, ylimit + 7*epsilon) # 在坐标轴添加范围限制 )
# 设置坐标轴刻度的位置
ticks_x q(-xlimit, xlimit, length.out = num_ticks), 2) ticks_y q(-ylimit, ylimit, length.out = num_ticks), 2)
# 接下来循环添加x和y轴的刻度
nlist length(theme.list)
for (k in 1:num_ticks){ # 生成x坐标轴刻度的数据
xtick 2), yt = c(xgeo + epsilon, xgeo))
# 生成y坐标轴刻度的数据 ytick yt = rep(ticks_y[k], 2))
# 添加x坐标轴的刻度 theme.list[[nlist + 4*k-3]] x = xt, y = yt),
data = xtick, color = color,
linewidth=linewidth)
# 添加x坐标轴刻度的标签 theme.list[[nlist + 4*k-2]] "text",
x = ticks_x[k], y = ygeo - epsilon,
size = tick_textsize, vjust =
1,
label = paste(ticks_x[k]))
# 添加y坐标轴的刻度 theme.list[[nlist + 4*k-1]] x = xt, y = yt),
data = ytick, color = color,
linewidth=linewidth)
# 添加y坐标轴刻度的标签 theme.list[[nlist + 4*k]] "text",
x = xgeo - epsilon, y = ticks_y[k],
size = tick_textsize, hjust =
1,
label = paste(ticks_y[k])) }
# 返回该主题list,该list可以直接用在ggplot创建的图层中,通过加号 (+) 连接
return(theme.list)}

下面主要讲一下该函数的思路和功能,具体参数的含义请参考函数内部的注释。

该函数的主要思路是创建一个新的ggplot主题(theme),该主题实质上是R语言中的列表(list),而list可以直接添加在ggplot创建的图层中。

在创建该主题的list时,首先使用了geom_lineannotate函数来创建 x 和 y 坐标轴及标签,然后计算需要在坐标轴上绘制的刻度的坐标,再采用循环的方式给坐标轴添加刻度及标签,在循环中仍然使用了geom_lineannotate这两个函数。

下面看一下使用了该函数以后的散点图,运行如下代码:

set.seed(6)# 设置随机种子,当随机种子固定后,生成的随机数将不会发生变化dfdata.frame(x=rnorm(50),y=rnorm(50))
## 将 xy 轴居中,放到原点 (0,0) 上xlimitmax(abs(df$x),abs(df$y))ylimitxlimitggplot(df)+ geom_point(aes(x=x,y=y))+ theme_with_xy_centered( xlimit=xlimit,ylimit=ylimit, linewidth=0.4 )

绘制的散点图如下:


可以发现,此时 x 坐标轴与 y=0 直线重合了,而 y 坐标轴与 x=0 直线重合了,并且可以清晰地分辨出四个象限。

此外,theme_with_xy_centered函数有很多参数可以设置,这里列举几个常用的参数,全部参数请查看该函数的源代码。

xlimit:坐标轴的范围,一般为绘图数据的最大值ylimit:坐标轴的范围,一般为绘图数据的最大值color :设置坐标轴颜色xlab:设置 x 坐标轴的标签,默认是 xylab:设置 y 坐标轴的标签,默认是 ynum_ticks:在每个坐标轴上添加的刻度数目,默认是 10 个刻度


3、本文参考链接

https://stackoverflow.com/questions/17753101/center-x-and-y-axis-with-ggplot2


高颜值免费 SCI 在线绘图(点击图片直达)


最全植物基因组数据库IMP (点击图片直达)

往期精品(点击图片直达文字对应教程)

机器学习