美文网首页
【R>>>gggrid】ggplot2中实现grid功能

【R>>>gggrid】ggplot2中实现grid功能

作者: 高大石头 | 来源:发表于2021-06-11 00:06 被阅读0次

在用ggplot2画图的过程中我们经常会用一些basic plot 功能,用grid实现会很方便,但是ggplot2和grid好像有不太兼容,如何才能做到大一统,为你我所用呢?

针对这种情况,Paul Murrel大神开发了R包gggrid,将grid的常用功能融合到了ggplot2中。

知识点

npc : Normalised Parent Coordinates, 规范化的父区域坐标,gird中的默认单位。


核心图:


核心函数:

  • grid_panel()
  • grid_group()

1. R包下载及安装

Google或Bing搜素gggrid it's g-g-great! Accessing grid from ggplot2,便可以发现gggrid的简介,翻到底部,找到这个:


再转到github的,下载tar.gz文件

本地安装
install.packages("./gggrid-0.1-0.tar.gz",repos = NULL,type = "source")

2.示例1

添加一个长方形到ggplot2绘图中

library(gggrid)
grad <- radialGradient(c("transparent", "black"), r2=.6)
ggplot(mtcars) +
  geom_point(aes(disp, mpg)) +
  grid_panel(rectGrob(gp=gpar(fill=grad)))

不知道为啥,我的画出来没有那种径向的感觉。

3.示例2:精确定位的label

首先生成一个textGrob对象

label <- textGrob("Label",
                  x=unit(1, "npc") - unit(5, "mm"),
                  y=unit(1, "npc") - unit(5, "mm"),
                  just=c("right", "top"))

先简单的画一画

grid.rect()
grid.draw(label)

他就这么静静的出现在你的figure里。接下来,将label添加到你的figure中,有两种方式:

# 方式一
ggplot(mtcars) +
  geom_point(aes(disp, mpg)) +
  annotation_custom(label)

# 方式二
ggplot(mtcars, aes(disp, mpg)) +
    geom_point() +
    grid_panel(label)

来个复杂点的操作:

bg <- rectGrob(gp=gpar(fill="firebrick3")) #背景色
lab <- textGrob("mtcars",gp=gpar(col="white")) #字体颜色
vp <- viewport(x=1,y=1,width = .2,height = unit(1.5,"lines"),
               just=c("right","top")) #展示区域大小
banner <- gTree(children = gList(bg,lab),vp=vp)
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  grid_panel(banner)

需要注意的是,及时我们只提供一个空的长方形(宽边框),默认情况下,它仍然是和窗口完美匹配的。

rect <- rectGrob(gp=gpar(fill=NA,lwd=7))
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  grid_panel(rect)

还可以直接根据x,y轴的最大和最小值设置边框

rectFun <- function(data,coords){
  left=min(coords$x)
  bottom=min(coords$y)
  width=diff(range(coords$x))
  height=diff(range(coords$y))
  rectGrob(left,bottom,width,height,
           just=c("left","bottom"),
           gp=gpar(fill=NA,lwd=1))
}
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  grid_panel(rectFun)

注意:grid_panel()grid_group()都有debug参数,可以用来监测传递给grob功能的值。
debugHead <- function(data,coords){
  print(head(data))
  print(head(coords))
}
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  grid_panel(debug=debugHead)

3.示例3:边际地毯图

rug <- function(data,coords){
  segmentsGrob(unit(1,"npc"),
               coords$y,
               unit(1,"npc")-unit(2,"mm"),
               coords$y,
               gp=gpar(lwd=2,col="firebrick3"))
}
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  grid_panel(rug)

分面

mtcars$manual <- ifelse(mtcars$am==0,"FALSE","TRUE")
mtcars$manual <- factor(mtcars$manual,levels= c("FALSE","TRUE"))
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  facet_wrap("manual")+
  grid_panel(rug)

当然,还可以用panel_group()展示不同分组的信息
rugGroup <- function(data,coords){
  segmentsGrob(unit(1,"npc"),
               coords$y,
               unit(1,"npc")-unit(2,"mm"),
               coords$y,
               gp=gpar(lwd=2,col=adjustcolor(data$colour,alpha=.5)))
}
ggplot(mtcars,aes(disp,mpg,color=manual))+
  geom_point()+
  grid_group(rugGroup)

同样的,也可以应用debug功能,展示不同的数值

ggplot(mtcars,aes(disp,mpg,color=manual))+
  geom_point()+
  grid_panel(stat = "smooth",debug = debugHead)

示例4:回归方程

addLabel <- function(data,coords){
  label=expression(y==alpha+beta*x+epsilon) #输入的公式
  xpos=which(coords$x>.5)[1]
  dx=convertWidth(unit(diff(coords$x[1:2]),"npc"),"in",valueOnly = T)
  dy=convertHeight(unit(diff(coords$y[1:2]),"npc"),"in",valueOnly = T)
  angle = 180*atan2(dy,dx)/pi
  textGrob(label,
           x=unit(coords$x[xpos],"npc"),
           y=unit(coords$y[xpos],"npc")+unit(3,"mm"),
           rot = angle,
           gp=gpar(col=2))
}
ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  geom_smooth(method = "lm",colour=2)+
  grid_panel(addLabel,stat="smooth",method="lm")

示例5:post-hoc修改

marker <- function(data,coords){
  nullGrob(coords$x[which.max(coords$y)],
           max(coords$y),
           name = "mark")
}
g <- ggplot(mtcars,aes(disp,mpg))+
  geom_point()+
  facet_wrap("manual")+
  grid_panel(marker)+
  coord_cartesian(clip = "off")

grid.newpage()
pushViewport(viewport(y=0,
                      height = unit(1,"npc")-unit(2,"lines"),
             just="bottom",
             name="ggplot"))
plot(g,newpage = F)
upViewport()             
grid.force()
markers <- grid.grep("mark",global = T,viewports = T)
text <- textGrob("most.efficient",
                 x=unit(1,"lines"),
                 y=unit(1,"npc")-unit(1,"lines"),
                 just = c("left","top"))
grid.draw(text)
drawLine <- function(x){
  depth=downViewport(attr(x,"vpPath"))
  m=grid.get(x)
  loc=deviceLoc(m$x,m$y)
  upViewport(depth)
  grid.curve(grobX(text,0),grobY(text,0),
             loc$x,loc$y,
             square=F,curvature=-.5,angle=45,ncp=4,
             arrow=arrow(length = unit(3,"mm"),angle=20,type="closed"),
             gp=gpar(col="firebrick3",fill="firebrick3"))
}
lapply(markers, drawLine)

不禁由衷发出感叹,grid包真强大!gggrid更强大!
参考链接:
gggrid的github主页(还是不放链接了,要不然又要被锁定。有兴趣自行查阅原文吧)

相关文章

网友评论

      本文标题:【R>>>gggrid】ggplot2中实现grid功能

      本文链接:https://www.haomeiwen.com/subject/sfzasltx.html