Introduction
grid包是一个底层的绘图系统,能够灵活地控制图形输出的外观和布局,它能把图形逐个地添加到画布中设定好的位置上去。grid包不仅可以输出图形,还可以产生图形组件并复用和重组,形成复杂图形,也是lattice 和 ggplot2 的基础系统,理论上来讲能够完成一切可视化方案。 由于lattice 和 ggplot2 是基于grid 开发的,所以了解grid 系统有利于实现更灵活多变的可视化方案。
start a new page
All grid output occurs relative to the current viewport (region) on a page. In order to start a new page of output, the user must call the grid.newpage() function.
Create a Grid Viewport
viewport是grid包的核心对象和基础,即画布中的一个矩形的绘图区域,可通过viewport()函数新建窗口对象。
参数注释:
x:x坐标相对整个窗口x轴位置
y:y坐标中心相对整个窗口y轴位置
just:x和y所指的位置,默认为矩形中心位置
plotViewport()
dataViewport()
换句话说:通过这三个参数即可设定可视化窗口。
library(grid)
library(ggplot2)
####
grid.newpage()
grid.show.viewport(viewport(x = 0.5, y = 0.5, width = 0.5,height = 0.5))
####
grid.newpage()
vp1 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5)
plot1 <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(colour = Species))
print(plot1, vp = vp1)
image.png
####
grid.newpage()
grid.show.viewport(viewport(x=0.5, y= 0.5, width = 0.5, height=0.5, just = c("left","bottom")))
image.png
####
grid.newpage()
vp2 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5, just = c("left","bottom"))
print(plot1, vp = vp2)
image.png
viewport layout
layout:申明对目前画布进行拆分 layout.pos.row;layout.pos.col:可视化实现的位置,一般与grid.layout() 参数有关。
library(grid)
library(ggplot2)
####
plot <- ggplot(data = iris, aes(x = Sepal.Length,
y = Sepal.Width)) +
geom_point(aes(colour = Species)) +
theme(legend.position=c(0.8,0.7))
####
grid.newpage()
pushViewport(viewport(layout = grid.layout(4, 4)))
print(plot, vp = viewport(layout.pos.row = 3:4, layout.pos.col = 1:2))
print(plot, vp = viewport(layout.pos.row = 1, layout.pos.col = 1:2))
print(plot, vp = viewport(layout.pos.row = 1:2, layout.pos.col = 3:4))
image.png
viewport tree
Grid同样能够通过树状结构管理矩形区域。 * pushViewport():将指定的矩形区域插入为当前画布的子节点,同时画布转移为刚插入的viewport。 * upViewport():当前viewport移动到父节点; * downViewport():当前viewport移动到指定name的子节点;
library(grid)
library(ggplot2)
grid.newpage()
####
vp1 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5)
pushViewport(vp1)
plot <- ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(aes(colour = Species))
print(plot , newpage = F)
upViewport() #返回父节点
####
vp2 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5, just = c("left","bottom"))
pushViewport(vp2)
print(plot , newpage = F)
image.png
vpTree
可以利用vpTree提前规划作图矩形区域,以便进行分区域可视化。 * seekViewport():搜索指定name的viewport,将其设置为当前画布。 * popViewport():删除当前viewport,同时转移画布为其的父节点; ** vpList 里面的所有viewport 的等级是平行的,而vpStack中的是按输入viewport 的顺序 树状排列。**
####
library(grid)
library(ggplot2)
grid.newpage()
# set up viewport
vp1 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5,
name = "vp1")
vp2 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5,
just = c("left","bottom"), name = "vp2")
vp3 <- viewport(x = 0.5, y = 0.5, width = 0.5, height = 0.5,
just = c("right","top"), name = "vp3")
# 规划矩形区域: vp为第一层, vp1-3并列为第二层
tree <- vpTree(viewport(x = 0.5, y = 0.5, width = 1, height = 1,
name = "vp"),
vpList(vp1, vp2, vp3))
# push
pushViewport(tree)
plot <- ggplot(data = iris, aes(x = Sepal.Length,
y = Sepal.Width)) +
geom_point(aes(colour = Species)) +
theme(legend.position=c(0.8,0.7))
seekViewport("vp")
print(plot, newpage = FALSE)
seekViewport("vp1")
print(plot, newpage = FALSE)
seekViewport("vp2")
print(plot, newpage = FALSE)
seekViewport("vp3")
print(plot, newpage = FALSE)
image.png
geom
以grid.XX 格式出现的相关函数,基本和ggplot2 中geom_格式的函数相似,一般用于图形变换。
grid.rect(...)
grid.lines(...)
grid.polygon(...)
grid.circle(...)
grid.text(...)
Grob
与grid.XX 一样,但Grob 对象不会输出可视化结果,而是创建可以复用和重组的图形组件。 可用grid.draw() 显示相应组件,而grid.edit 可用于修改相应组件。
有的包如ggplot2 只是在作图ing时,才会产生grid 组件,因此可以先进行可视化,然后通过grid.force() 强制产生组件,然后用grid.ls()查看组件然后修改。其实没太大意义,首先是ggplot2 图形界面修改链接已经非常多了。而且其输出对象非常复杂,如不是特殊必要(写包),可能没必要去阅读那些组件。
####
library(grid)
library(ggplot2)
####
grid.newpage()
my_rect <- rectGrob(name = "my_rect", x = 0.5,
y = 0.5, width = 0.8, height = 0.3)
grid.draw(my_rect)
image.png
grid.edit("my_rect", gp = gpar(col = "red", lty = 1))
image.png
####
grid.newpage()
plot <- ggplot(data = iris, aes(x = Sepal.Length,
y = Sepal.Width)) +
geom_point(aes(colour = Species))
plot
grid.force()
image.png
grid.ls()
## layout
## background.1-11-12-1
## panel.7-5-7-5
## grill.gTree.743
## panel.background..rect.734
## panel.grid.minor.y..polyline.736
## panel.grid.minor.x..polyline.738
## panel.grid.major.y..polyline.740
## panel.grid.major.x..polyline.742
## NULL
## geom_point.points.730
## NULL
## panel.border..zeroGrob.731
## spacer.8-6-8-6
## spacer.8-4-8-4
## spacer.6-6-6-6
## spacer.6-4-6-4
## axis-t.6-5-6-5
## axis-l.7-4-7-4
## NULL
## axis
## axis.1-1-1-1
## GRID.text.750
## axis.1-2-1-2
## axis-r.7-6-7-6
## axis-b.8-5-8-5
## NULL
## axis
## axis.1-1-1-1
## axis.2-1-2-1
## GRID.text.746
## xlab-t.5-5-5-5
## xlab-b.9-5-9-5
## GRID.text.754
## ylab-l.7-3-7-3
## GRID.text.757
## ylab-r.7-7-7-7
## guide-box.7-9-7-9
## legend.box.background.2-4-4-2
## guides.3-3-3-3
## background.1-6-7-1
## title.2-5-2-2
## guide.title.titleGrob.762
## GRID.text.760
## key-3-1-bg.4-2-4-2
## key-3-1-1.4-2-4-2
## key-4-1-bg.5-2-5-2
## key-4-1-1.5-2-5-2
## key-5-1-bg.6-2-6-2
## key-5-1-1.6-2-6-2
## label-3-3.4-4-4-4
## guide.label.titleGrob.765
## GRID.text.763
## label-4-3.5-4-5-4
## guide.label.titleGrob.768
## GRID.text.766
## label-5-3.6-4-6-4
## guide.label.titleGrob.771
## GRID.text.769
## subtitle.4-5-4-5
## title.3-5-3-5
## caption.10-5-10-5
## tag.2-2-2-2
# grid.edit("geom_point.points.2855",
# gp = gpar(col = c("white","red", "navy")))
# point 后缀数字一直在改变。。。
gpar
gpar() 和基础绘图函数par()一样,用于创建图形参数对象,例如:外框颜色、填充颜色、透明度、线段类型、线段宽度等。
gp <- get.gpar() # 获取现存gpar参数
utils::str(gp) # 整齐输出gpar参数
col Colour for lines and borders.
fill Colour for filling rectangles, polygons, …
alpha Alpha channel for transparency
lty Line type
lwd Line width
lex Multiplier applied to line width
lineend Line end style (round, butt, square)
linejoin Line join style (round, mitre, bevel)
linemitre Line mitre limit (number greater than 1)
fontsize The size of text (in points)
cex Multiplier applied to fontsize
fontfamily The font family
fontface The font face (bold, italic, …)
lineheight The height of a line as a multiple of the size of text
font Font face (alias for fontface; for backward compatibility)
gTree
利用gTree 的可以灵活的构建复杂的gpar 组件,其中一般是就近原则,靠近谁就用谁的参数,可以用grid包自带的函数进行说明:
####
library(grid)
####
grid.newpage()
vp <- viewport(w = .8, h = .8, gp = gpar(col="blue"))
pushViewport(vp) #push viewport
gp <- get.gpar() # 获取现存gpar参数
utils::str(gp) # 整齐输出gpar参数
## List of 14
## $ fill : chr "white"
## $ col : chr "blue"
## $ lty : chr "solid"
## $ lwd : num 1
## $ cex : num 1
## $ fontsize : num 12
## $ lineheight: num 1.2
## $ font : int 1
## $ fontfamily: chr ""
## $ alpha : num 1
## $ lineend : chr "round"
## $ linejoin : chr "round"
## $ linemitre : num 10
## $ lex : num 1
## - attr(*, "class")= chr "gpar"
grid.text("This text is the colour set by the viewport (blue)",
y = 1, just = c("center", "bottom"),
gp = gpar(fontsize = 20), vp = vp)
# viewport = vp, 表现与vp中的gpar参数想同
####
grid.draw(gTree(children = gList(rectGrob(gp = gpar(col="red")),
textGrob(paste("The rect is its own colour (red)",
"but this text is the colour",
"set by the gTree (green)",
sep = "\n"))),
gp = gpar(col = "green"), vp = vp))
image.png
gp <- get.gpar() # 获取现存gpar参数
utils::str(gp) # 整齐输出gpar参数
## List of 14
## $ fill : chr "white"
## $ col : chr "blue"
## $ lty : chr "solid"
## $ lwd : num 1
## $ cex : num 1
## $ fontsize : num 12
## $ lineheight: num 1.2
## $ font : int 1
## $ fontfamily: chr ""
## $ alpha : num 1
## $ lineend : chr "round"
## $ linejoin : chr "round"
## $ linemitre : num 10
## $ lex : num 1
## - attr(*, "class")= chr "gpar"
我们可以看到现存图形界面中的gpar是没有改变的,但:
grid.text 以vp 中的gpar 参数为基础
rectGrob 以自带的gpar 参数构建
textGrob 以gTree 设定的 gpar 构建
more
package document
gridExtra CRAN page