1. geom_polygon 画多边形

geom_polygon 与 geom_path 类似,不过起点和末端也会连起来,且使用fill颜色填充内部。

library(ggplot2)
ggplot() + 
  geom_polygon(data= data.frame(
    x=c(1,1,2,2),
    y=c(3,1,1,2)
  ), mapping=aes(x, y),
  linetype=1,
  size=2, #边缘的线宽
  fill="#FFFFFF", #填充白色
  color="#FF0000") #描边红色

例1: 连接圆心和圆上两点的多边形

圆上两点与圆心连线的夹角为 angle 。

2pi=360度,pi=180度。R中的三角公式使用弧度制。 x轴正向是弧度0,逆时针方向是角度的正方向。

angle=30 #角度
r=10  #半径

# 换算成弧度
angle=angle/180*3.1415926

# 圆心是 (0,0), 其中一个顶点在x轴上 (r,0)
# 计算第三个顶点
x3=r*cos(angle)
y3=r*sin(angle)

# 填充该三角形
library(ggplot2)

tmpAngle=seq(0, 2*pi, length.out=100)
ggplot() + 
  # 画圆
  geom_polygon(data= data.frame(
    x=r*cos(tmpAngle),
    y=r*sin(tmpAngle)
  ), mapping=aes(x, y), color="#0000ff", fill="#ffffff")+
  
  # 画三角形
  geom_polygon(data= data.frame(
    x=c(0, r, x3),
    y=c(0, 0, y3)
  ), mapping=aes(x, y),
  linetype=1,
  size=2, #边缘的线宽
  fill="#FFFFFF00", #填充白色。颜色的7-8位的不透明度0: 表示全透明
  color="#FF0000") #描边红色

例2: 画一个n变形。

思路:计算每个顶点的弧度,通过弧度计算其坐标,依次连起来。

len=8  #n变形
r=10  #半径

# 计算角度
angle=360/len 
# 换算成弧度
angle=angle/180*3.1415926

# 计算第i个顶点
# 假设圆心是(0,0)
xx=numeric(len)
yy=numeric(len)
for(i in 1:len){
  xx[i]=0 + r * cos(i*angle)
  yy[i]=0 + r * sin(i*angle)
}


# 填充该n变形
library(ggplot2)
ggplot() + 
  geom_polygon(data= data.frame(
    x=xx,
    y=yy
  ), mapping=aes(x, y),
  linetype=1,
  size=1, #边缘的线宽
  fill="#00000000", #不透明度0,就是全透明
  color="#aaaaaa")+ #描边灰色
  theme_void() #不显示坐标轴、背景虚线等

包装成函数

# 多边形数据: 获取圆上的n个点的坐标
# rotate: 为了美观,整体逆时针旋转的弧度
getPointsOnCircle=function( radius=1, npoints=10, center=c(0,0), rotate=pi/2){
  angle=seq(0, 2*pi, length.out=npoints+1)
  xx=center[1] + radius*cos(angle+rotate)
  yy=center[2] + radius*sin(angle+rotate)
  return(data.frame(x=xx, y=yy))
}

# 画多边形
drawPolygon = function(radius, npoints=10, linetype=1, size=0.5){
  geom_polygon(data= getPointsOnCircle(radius, npoints), aes(x, y),
               linetype=linetype,
               size=size, fill="#FFFFFF00", color="#AAAAAA")
}


# 绘制3个6边形
library(ggplot2)
ggplot() + 
  drawPolygon(10, 6)+
  drawPolygon(5, 6)+
  drawPolygon(2.5, 6)+
  theme_void()

2. geom_path 画路径

就是把指定的点用线连起来。

例1: 画三个相连的线段,共4个顶点

library(ggplot2)
ggplot() + 
  geom_path(data= data.frame(
    x=c(1,1,2,2),
    y=c(3,1,1,2)
  ), mapping=aes(x, y),
  linetype=1,
  size=2, #边缘的线宽
  color="#0000FF") #描边蓝色

例2: 原点连接多边形的每个顶点

思路: 每个顶点和原点交替排列。相当于每个放射线画两遍: 原点到一个顶点,再回到原点。

len=5 #n边形
maxR=10 #半径

arr=pi/2 + seq(0, 2*pi, length.out=len+1); #首尾是一个点,所以需要输出 n+1 个点
xx=c()
yy=c()
for(i in arr){
  xx=c(xx, c(0, maxR)*cos(i))
  yy=c(yy, c(0, maxR)*sin(i))
}

library(ggplot2)
ggplot() + 
  geom_path(data= data.frame(
    x=xx,
    y=yy
  ), mapping=aes(x, y),
  linetype=1,
  size=1, #边缘的线宽
  color="#0000FF") #描边蓝色

包装成函数

# (原点到各个顶点)放射线 顶点坐标
getRadialLines = function(maxR=10, npoints=10){
  arr=pi/2 + seq(0, 2*pi, length.out=npoints+1);
  x=c()
  y=c()
  for(i in arr){
    x=c(x, c(0, maxR)*cos(i))
    y=c(y, c(0, maxR)*sin(i))
  }

  return(data.frame(x, y))
}


ggplot()+
  geom_path(data=getRadialLines(10, 6), mapping=aes(x,y), color="#AAAAAA", linetype=1)+
  theme_void()

3. 整体效果

(1) 测试数据:GO分析结果,10 行 4列(Desc, id, log10padj, Count)

$ cat dustbin/8dat.csv 
Desc,id,log10padj,Count
IL-17,1,9.87,11
Rheumatoi,2,7.27,9
Viroal,3,7.16,9
TNF signal,4,5.54,8
Cytokine,5,5.25,11
Chemokine,6,4.98,9
Glycolysis,7,4.69,6
Legionell,8,3.786,5
Lipid and,9,3.782,8
Amoebiasi,10,3.782,6
# 读取数据
dat=read.csv("/data/wangjl/rmarkdown_demo/bookdown-demo-main/dustbin/8dat.csv");

# 10个富集分析: 10边形
dat2=dat
dat2$angle=pi/2+seq(0, 2*pi, length.out=11)[1:10]
dat2$x=dat2$log10padj * cos(dat2$angle)
dat2$y=dat2$log10padj * sin(dat2$angle)
dat2
##          Desc id log10padj Count    angle             x         y
## 1       IL-17  1     9.870    11 1.570796  6.043632e-16  9.870000
## 2   Rheumatoi  2     7.270     9 2.199115 -4.273199e+00  5.881554
## 3      Viroal  3     7.160     9 2.827433 -6.809565e+00  2.212562
## 4  TNF signal  4     5.540     8 3.455752 -5.268853e+00 -1.711954
## 5    Cytokine  5     5.250    11 4.084070 -3.085873e+00 -4.247339
## 6   Chemokine  6     4.980     9 4.712389 -9.148112e-16 -4.980000
## 7  Glycolysis  7     4.690     6 5.340708  2.756713e+00 -3.794290
## 8   Legionell  8     3.786     5 5.969026  3.600700e+00 -1.169938
## 9   Lipid and  9     3.782     8 6.597345  3.596896e+00  1.168702
## 10  Amoebiasi 10     3.782     6 7.225663  2.223004e+00  3.059702

(2) 绘图依赖前面的3个函数:

  • getPointsOnCircle 获取多边形的顶点
  • drawPolygon 绘制多边形
  • getRadialLines 获取放射线顶点
library(ggplot2)
g1=ggplot()+ xlim(-12, 12) + ylim(-12, 12)+
  drawPolygon(10)+drawPolygon(7.5)+drawPolygon(5)+drawPolygon(2.5)+ #雷达图 几层多边形
  geom_path(data=getRadialLines(10, 10), mapping=aes(x,y), color="#AAAAAA", linetype=1)+ #雷达图放射直线
  geom_polygon(data=dat2, aes(x, y), fill="#CB5656",alpha=0.5, color="#CF0015",size=1 )+ #填充不规则多边形
  #
  geom_point(data=dat2, aes(x,y, fill=Count), size=5, shape=21, color="black", stroke=0.5)+ #添加大点
  scale_fill_gradient(low="white", high="#00B858", breaks=seq(5, 11, 2) )+ #点的渐变色。控制图例数字 breaks+labels
  #
  geom_text(data=data.frame(x=-0.8, y=seq(0,10,2.5) ), aes(x, y, label=y),
            color='black', angle=0, hjust=1, vjust=1 )+ # 仿y坐标值刻度 tick
  annotate(geom="text",x=0.2, y=5,
           label="-log[10]*italic(P)*adj", parse=T,
           color="black", angle=90, vjust=1 )+ #仿y轴名字 label
  #
  geom_text(data=dat2, aes(x=11*cos(angle), y=11*sin(angle), label=Desc), color="black")+# 每条边的文字
  #
  coord_equal()+ #保证x和y轴等长
  theme_void(base_size = 12)+ #去掉坐标轴、边框
  theme(
    legend.position = "top",
    legend.justification = "left", #靠左对齐
    legend.key = element_rect(fill = "black") #不起作用 //todo
  )
g1

## pdf("dustbin/radar.pdf", width=4, height=4)
## g1
## dev.off()

输出pdf矢量图,然后可以使用 Illustrator 编辑文字:添加换行、调整文字位置、字号等。


rmarkdown::render(“./backup/GO_plot_new.Rmd”)