Точно подогнать ggplot к размеру области просмотра

Предположим, у меня есть объект 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)

Но я хочу, чтобы график внутри этой страницы был таким, чтобы область построения (а не поля) точно заполняла это поле, а легенда, метки осей и т. Д. Как бы «перетекали» за пределы графика. Есть какой-либо способ сделать это?


person Sacha Epskamp    schedule 09.04.2015    source источник
comment
Взгляните на пакет яйца на github   -  person baptiste    schedule 02.02.2017


Ответы (1)


Возможно, есть более простой способ, чем следующий.

Это использует функции 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()

введите здесь описание изображения

person Sandy Muspratt    schedule 14.04.2015
comment
FWIW pkg egg определяет некоторые функции в этом направлении, чтобы обернуть ggplot в gtable 3x3, где центральной ячейкой является панель. - person baptiste; 02.02.2017