完全符合视口大小的ggplot

时间:2015-04-09 10:17:08

标签: r ggplot2 r-grid

假设我有一个ggplot对象:

library("ggplot2")
library("grid")
p <- qplot(0:10,0:10)

还有一个带框的网格页面:

grid.newpage()
vp <- viewport(width = unit(210, "mm"), height = unit(297, "mm"))
pushViewport(vp)

# Inner box:
box <- viewport(unit(105,"mm"),unit(150,"mm"),width=unit(150,"mm"),height=unit(150,"mm"))
pushViewport(box)
grid.rect()

我可以将内容拟合如下:

# Print ggplot plot:
upViewport()
print(p ,vp = box)

但是我想完成这个页面内的情节,使得绘图区域(不是边距)正好填充这个框,而图例,轴标签等等#&#34;溢出&#34;在情节之外。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:4)

可能比以下方式更容易。

这使用gtable函数将ggplot反汇编到绘图面板和两个轴中。然后,它将组件定位到视口中,以便绘图面板精确填充内部框,但轴位于内部框的边界之外。红色边界线和旋转是为了证明(主要是对我自己)轴是在外面但随着内盒移动。

library(ggplot2)
library(gtable)
library(grid)

p <- qplot(0:10,0:10)

# Convert the plot to a grob
gt <- ggplotGrob(p)

# Extract panel, axes and axis labels
panel = gtable_filter(gt, "panel")
axis_l = gtable_filter(gt, "axis-l")
axis_b = gtable_filter(gt, "axis-b")
xlab = gtable_filter(gt, "xlab-b")
ylab = gtable_filter(gt, "ylab-l")

# Put labels and axes together
left = cbind(ylab, axis_l, size = "first")
bottom = rbind(axis_b, xlab, size = "last")

# Get their width / height
w = convertX(sum(left$width), "mm") 
h = convertX(sum(bottom$height), "mm")

# Outer box
grid.newpage()
outerBox <- viewport(width = unit(125, "mm"), height = unit(150, "mm"))
pushViewport(outerBox)
grid.rect(gp = gpar(col = "red", fill = NA))

# Width and height of inner box (in mm)
width = 60
height = 70

# Inner box
innerBox <- viewport(x = unit(0.5, "npc"), y = unit(0.6, "npc"), 
                width = unit(width, "mm"), height = unit(height, "mm"), angle = -30)

# Viewport for left axis and label
Vleft = viewport(x = unit(0, "npc") - .5*w, y = unit(0.5, "npc"), 
                width = w, height = unit(height, "mm"))

# Viewport for bottom axis and label
Vbottom = viewport(x = unit(0.5, "npc"), y = unit(0, "npc") - .5*h, 
                width = unit(width, "mm"), height = h)

pushViewport(innerBox)
grid.draw(panel)
grid.rect(gp = gpar(col = "red", fill = NA, lwd = 2))

pushViewport(Vbottom)
grid.draw(bottom)

upViewport()
pushViewport(Vleft)
grid.draw(left)

popViewport()
popViewport()
popViewport()

enter image description here