Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
336 views
in Technique[技术] by (71.8m points)

r - ggplot2 - custom grob over axis lines

I'm trying to generate an axis line break in ggplot2 (with a white segment over the axis lines) and I'm having some trouble.

Using the informative post annotate-ggplot-with-an-extra-tick-and-label I was able to generate the custom grobs in given location, while also turning the panel off to "draw" outside of the plotting area.

I'm also familiar with other packages such as plotrix and am able to replicate broken axis in base, but more than anything I'm interested in learning why the axis grobs I'm creating aren't overwriting the line. Here is some sample code:

library(ggplot2) # devtools::install_github("hadley/ggplot2")
library(grid)
library(scales)


data("economics_long")
econ <- economics_long
econ$value01 <- (econ$value01/2)
x <- ggplot(econ, aes(date, value01,group=1)) + scale_y_continuous(labels=c(0.0,0.1,0.2,0.3,0.4,0.5,1.0), breaks=c(0.0,0.1,0.2,0.3,0.4,0.5,0.6),limits = c(0,.6),expand = c(0, 0)) +
  geom_smooth(colour="deepskyblue", show.legend = TRUE ) + theme_bw()

theme_white <- theme(panel.background=element_blank(),
                     panel.border=element_rect(color="white"),
                     plot.margin = unit(c(.2, 0, .2, .2), "cm"),
                     panel.grid.major.y=element_blank(),
                     panel.grid.major.x=element_blank(),
                     panel.grid.minor.x=element_blank(),
                     panel.grid.minor.y=element_blank(),
                     axis.title.y = element_blank(),
                     axis.line.x=element_line(color="gray", size=1),
                     axis.line.y=element_line(color="gray", size=1),
                     axis.text.x=element_text(size=12),
                     axis.text.y=element_text(size=12),
                     axis.ticks=element_line(color="gray", size=1),
                     legend.position="none"
)
x <- x + theme_white


gline = linesGrob(y = c(0, 1.5),x = c(-.015, .015),  gp = gpar(col = "black", lwd = 2.5)) 
gline2 = linesGrob(y = c(-0.25, 0.5),x = c(0, 0),  gp = gpar(col = "red", lwd = 5))

p = x + annotation_custom(gline, ymin=.55, ymax=.575, xmin=-Inf, xmax=Inf) + 
  annotation_custom(gline, ymin=.525, ymax=.55, xmin=-Inf, xmax=Inf) +
  annotation_custom(gline2, ymin=.55, ymax=.575, xmin=-Inf, xmax=Inf)

# grobs are placed under the axis lines....

g = ggplotGrob(p)
g$layout$clip[g$layout$name=="panel"] <- "off"
grid.draw(g)

Which creates this image: enter image description here

I'm curious why the annotation_custom grobs are placed under the axis lines and whether there is a better solution to adding custom grobs using ggplot2. There appears to be an order in which graphics are placed in the plotting windows - how might this be alternated so that the custom grobs are placed after the axis lines?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You were close. The layout data frame is were you turned off clipping. There is another column in the layout data frame that gives the order in which the various plot elements are drawn - z. The plot panel (including the annotation) is drawn second (after the background), then later the axes are drawn. Change the value of z for the plot panel to something larger than the z values for the axes.

library(ggplot2) # devtools::install_github("hadley/ggplot2")
library(grid)
library(scales)


data("economics_long")
econ <- economics_long
econ$value01 <- (econ$value01/2)


x <- ggplot(econ, aes(date, value01,group=1)) + scale_y_continuous(labels=c(0.0,0.1,0.2,0.3,0.4,0.5,1.0), breaks=c(0.0,0.1,0.2,0.3,0.4,0.5,0.6),limits = c(0,.6),expand = c(0, 0)) +
  geom_smooth(colour="deepskyblue", show.legend = TRUE ) + theme_bw()

theme_white <- theme(panel.background=element_blank(),
                     panel.border=element_rect(color="transparent"),
                     plot.margin = unit(c(.2, 0, .2, .2), "cm"),
                     panel.grid.major.y=element_blank(),
                     panel.grid.major.x=element_blank(),
                     panel.grid.minor.x=element_blank(),
                     panel.grid.minor.y=element_blank(),
                     axis.title.y = element_blank(),
                     axis.line.x=element_line(color="gray", size=1),
                     axis.line.y=element_line(color="gray", size=1),
                     axis.text.x=element_text(size=12),
                     axis.text.y=element_text(size=12),
                     axis.ticks=element_line(color="gray", size=1),
                     legend.position="none"
)
x <- x + theme_white


gline = linesGrob(y = c(0, 1.5),x = c(-.015, .015),  gp = gpar(col = "black", lwd = 2.5)) 
gline2 = linesGrob(y = c(-0.25, 0.5),x = c(0, 0),  gp = gpar(col = "red", lwd = 5))

p = x + annotation_custom(gline, ymin=.55, ymax=.575, xmin=-Inf, xmax=Inf) + 
  annotation_custom(gline, ymin=.525, ymax=.55, xmin=-Inf, xmax=Inf) +
  annotation_custom(gline2, ymin=.55, ymax=.575, xmin=-Inf, xmax=Inf)

# grobs are placed under the axis lines....

g = ggplotGrob(p)
g$layout$clip[g$layout$name=="panel"] <- "off"

g$layout  # Note that z for panel is 1.  Change it to something bigger.

g$layout$z[g$layout$name=="panel"] = 17    

grid.newpage()
grid.draw(g)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...