gg1 <- baseplot +
geom_col(aes(count, country, fill=pet), position="dodge") +
basetheme
print(gg1)

labels <- c(" dogs", " cats")
grid.legend <- function() {
grid.segments(.2, .2, .2, .8, gp=gpar(col="grey"))
grid.rect(.2, rep(.5, 2), .2, .2, hjust=0, vjust=1:0,
gp=gpar(col=NA, fill=cols))
grid.text(labels, .4, just="left",
unit(.5, "npc") + unit(c(1, -1), "lines"),
gp=gpar(fontsize=18))
}
grid.legend()
legendGrob <- function(width=.2, height=.2, fontsize=18) {
line <- segmentsGrob(.2, .5 + height + .1,
.2, .5 - height - .1,
gp=gpar(col="grey"))
bars <- rectGrob(.2, rep(.5, 2), width, height, hjust=0, vjust=1:0,
gp=gpar(col=NA, fill=cols))
labs <- textGrob(labels, .2 + width, just="left",
.5 + c(1, -1)*.5*height,
gp=gpar(fontsize=fontsize))
grobTree(line, bars, labs)
}
grid.draw(legendGrob())


legendFun <- function(data, coords) {
panelViewport <- viewport(x=1, width=.2, just="left", y=coords$y[1])
h <- abs(diff(coords$y)[2])*.9/2
grobTree(legendGrob(height=h, fontsize=12), vp=panelViewport)
}
gg4 <- gg2 +
coord_cartesian(clip="off") +
grid_panel(legendFun, aes(count, country))
pushViewport(viewport(x=0, width=.8, just="left"))
print(gg4, newpage=FALSE)
popViewport()
legendConvert <- function(data, coords) {
panelViewport <- viewport(x=1, width=.2, just="left", y=coords$y[1])
h <- abs(diff(coords$y)[2])*.9/2
hin <- convertHeight(unit(h, "npc"), "in")
w <- convertWidth(hin, "npc", valueOnly=TRUE)
grobTree(legendGrob(width=w, height=h, fontsize=12), vp=panelViewport)
}
gg5 <- gg2 +
coord_cartesian(clip="off") +
grid_panel(legendConvert, aes(count, country))
pushViewport(viewport(x=0, width=.8, just="left"))
print(gg5, newpage=FALSE)
popViewport()
makeContent.legend <- function(x) {
h <- abs(diff(x$coords$y)[2])*.9/2
hin <- convertHeight(unit(h, "npc"), "in")
w <- convertWidth(hin, "npc", valueOnly=TRUE)
setChildren(x,
gList(grobTree(legendGrob(width=w, height=h, fontsize=12))))
}
legendDelayed <- function(data, coords) {
panelViewport <- viewport(x=1, width=.2, just="left", y=coords$y[1])
gTree(coords=coords, cl="legend", vp=panelViewport)
}

layout
background.1-13-16-1
plot.background..zeroGrob.470
panel.9-7-9-7
panel-1.gTree.458
grill.gTree.456
panel.background..zeroGrob.454
panel.grid.minor.x..zeroGrob.450
panel.grid.major.y..zeroGrob.451
panel.grid.major.x..polyline.453

print(gg2, newpage=FALSE)
grid.force()
barPath <- grid.grep("geom_rect", grep=TRUE, viewports=TRUE)
barPathlayout::panel.9-7-9-7::panel-1.gTree.507::geom_rect.rect.497
[1] "layout::panel.9-7-9-7::GRID.VP.82"

print(gg2, newpage=FALSE)
grid.force()
barPath <- grid.grep("geom_rect", grep=TRUE, viewports=TRUE)
bars <- grid.get(barPath)
downViewport(attr(barPath, "vpPath"))
barHeight <- convertHeight(bars$height[1], "in")
barHeight[1] 0.61327121682363inches
[1] 0.20442373894121inches

labelGrob <- textGrob(labels, gp=gpar(fontsize=10))
gap <- unit(10, "mm")
legendWidth <- 3*gap + barHeight + grobWidth(labelGrob)
legend <- function(data, coords) {
line <- segmentsGrob(2*gap, unit(.5, "npc") + barHeight + bottomGap,
2*gap, unit(.5, "npc") - barHeight - bottomGap,
gp=gpar(col="grey", lwd=1.5))
bars <- rectGrob(2*gap, rep(.5, 2), barHeight, barHeight,
hjust=0, vjust=1:0,
gp=gpar(col=NA, fill=cols))
labs <- textGrob(labels, 2*gap + barHeight, just="left",
unit(.5, "npc") + c(1, -1)*.5*barHeight,
gp=gpar(fontsize=10))
vp <- viewport(x=1, width=legendWidth, y=coords$y[1], just="left")
grobTree(line, bars, labs, vp=vp)
}