I want to add a zig-zag to the bottom of an y-axis to a ggplot2 plot using grid functions. This should be doable by retrieving the axis grob from the gtable that is created by the print and adding points to the horizontal line.
Here's a toy example:
library(ggplot2)
data(airquality)
data <- na.exclude(airquality)
model <- lm(Temp ~ Wind, data)
png(filename = "basic_plot.png", width=500, height=500, type = "cairo", res = 120)
ggplot(data=data, aes(y=Temp, x=Wind)) +
geom_point() +
geom_abline(intercept=coef(model)[1],
slope=coef(model)[2])+
theme_bw()
dev.off()
Here's the core idea (sorry the ugliness, Gimp is not the ideal tool for this):
The tools that I need help with are thus:
- Find the axis-grob in gtable
- Modify this by using grid.edit
alternatively I've started looking at the ggplot-code but I haven't found where the axis grobs are created, ideally I would like to locate these and add a theme option that allows for this.
I'm aware of Hadley´s concerns to adding this feature but as I understand it this was mostly in the presence of scatterplots where I agree. My use case is a survival curve where it's important to notify that the bottom isn't 0%.
Update
The core function for navigating the viewport tree is seekViewpor
and in order to look at the tree we can use the current.vpTree
:
library(grid)
current.vpTree()
# viewport[ROOT]->
# (viewport[GRID.VP.397]->(
# viewport[GRID.VP.398]),
# viewport[GRID.VP.399]->(viewport[GRID.VP.400]),
# viewport[GRID.VP.401]->(viewport[GRID.VP.402]),
# viewport[GRID.VP.404]->(viewport[GRID.VP.405]),
# viewport[layout]->(
# viewport[panel.6-4-6-4],
# viewport[subtitle.3-4-3-4],
# viewport[xlab-b.8-4-8-4]->(viewport[GRID.VP.397]->(viewport[GRID.VP.398])),
# viewport[axis-r.6-5-6-5],
# viewport[title.2-4-2-4],
# viewport[spacer.5-5-5-5],
# viewport[background.1-7-10-1],
# viewport[xlab-t.4-4-4-4],
# viewport[axis-l.6-3-6-3]->(
# viewport[GRID.VP.404]->(viewport[GRID.VP.405]),
# viewport[GRID.VP.406]->(
# viewport[GRID.VP.404]->(viewport[GRID.VP.405]),
# viewport[axis]->(
# viewport[axis.1-1-1-1]->(viewport[GRID.VP.404]->(viewport[GRID.VP.405])),
# viewport[axis.1-2-1-2]))),
# viewport[caption.9-4-9-4],
# viewport[ylab-l.6-2-6-2]->(viewport[GRID.VP.399]->(viewport[GRID.VP.400])),
# viewport[spacer.5-3-5-3],
# viewport[axis-b.7-4-7-4]->(
# viewport[GRID.VP.401]->(viewport[GRID.VP.402]),
# viewport[GRID.VP.403]->(viewport[GRID.VP.401]->(viewport[GRID.VP.402]),
# viewport[axis]->(
# viewport[axis.1-1-1-1],
# viewport[axis.2-1-2-1]->(
# viewport[GRID.VP.401]->(
# viewport[GRID.VP.402]))))),
# viewport[spacer.7-5-7-5],
# viewport[ylab-r.6-6-6-6],
# viewport[axis-t.5-4-5-4],
# viewport[spacer.7-3-7-3]))
The commented is a prettified output from ggplot. Note that some of the numbers are changed for every plot, i.e. GRID.VP.397 changes betweeen plots. We can now navigate to the left axis and add a transparent rectangle around the y-axis:
seekViewport("axis-l.6-3-6-3")
grid.rect(gp = gpar(fill="#66666666"))
This results in:
The questions that remain are:
- How to get a list of grobs within the viewport
- How to edit the y-line grob (this may be part of a rectangle around the entire page)
- The viewport is cropped and this may cause an issue with the zig-zag patterns that goes between grobs
- How to get the location of the bottom y-tick as a starter point for the zig-zag