4

How do I abbreviate ggplot's horizontal grid lines after extending the range of the horizontal axis? I am extending the range in order to display geom_text elements.

I want to make the horizontal grid lines in my line graph disappear after x >= 2014. I am using geom_text to label one of the geom_lines. Is this possible, or is extending the range the wrong approach to begin with?

Here is how I create the plot:

library(quantmod)
library(plyr)
library(ggplot2)

abblist <- list(CA="California",IL="Illinois",TX="Texas",NY="New York")

cleandata <- function(thelist,i) {
    abbname <- names(thelist)[[i]]
    fullname <- thelist[[i]]
    seriesname <- paste(abbname, "UR", sep = "")
    df <- apply.yearly(getSymbols(seriesname,src='FRED',auto.assign=F),mean)
    df <- data.frame(year=time(df),coredata(df))
    df$year <- as.numeric(format(df$year, "%Y"))
    names(df)[names(df)==seriesname] <- "urate"
    df$state <- as.factor(fullname)
    df
}

urates <- rbind.fill(lapply(seq_along(abblist), cleandata, thelist=abblist))

mytheme <- theme_grey() +
theme(
    panel.background = element_rect(fill="white"),
    legend.position="none",
    axis.title.x = element_blank(),
    axis.title.y = element_blank()
)

p <- ggplot(urates, aes(x=year, y=urate)) +
geom_line(data=subset(urates,state!="New York"), aes(group=state), color="grey") +
geom_line(data=subset(urates,state=="New York"), color="maroon") +
geom_text(data=subset(urates,year==max(year) & state == "New York"), aes(label=state,x=year+0.25), hjust=0, color="grey20", size=3) + 
mytheme +
scale_x_continuous(limits=c(2000,2015),breaks=seq(2000,2014,2),minor_breaks=seq(2001,2013,2))
tacobean
  • 45
  • 5

1 Answers1

2

Borrowing some ideas from this answer, here's something that may work for you.

First calculate the values for the NY label

ny.year <- max(urates$year)
ny.val <- urates$urate[urates$year==ny.year & urates$state=="New York"]
ny.year <- ny.year +.25 # offset padding

We also need to change the theme to leave some room on the right margin

mytheme <- theme_grey() +
theme(
    panel.background = element_rect(fill="white"),
    legend.position="none",
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    plot.margin = unit(c(1,5,1,1), "lines")
)

Now instead of using geom_text, use a custom annotation. Additionally we clip the limits at 2000-2014 and tell ggplot not to expand them.

p <- ggplot(urates, aes(x=year, y=urate)) +
geom_line(data=subset(urates,state!="New York"), aes(group=state), color="grey") +
geom_line(data=subset(urates,state=="New York"), color="maroon") +
mytheme +
scale_x_continuous(expand=c(0,0), limits=c(2000,2014),
    breaks=seq(2000,2014,2), minor_breaks=seq(2001,2013,2))+
annotation_custom(
    grob = textGrob(label = "New York", hjust = 0, gp=gpar(col="grey20", fontsize=3)),
    ymin = ny.val, ymax = ny.val,
    xmin = ny.year, xmax = ny.year)

Now the annotation will get clipped unless we disable panel clipping. Se we disable that with

library(grid)
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)

which finally gives us this plot.

add desc outside plot

Basically this strategy is really just plotting things outside the plot rather than really clipping the grid lines, but it's a different way to achieve a similar result I believe.

Community
  • 1
  • 1
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Thanks, this is great -- I didn't know about annotation_custom() or the clipping options. To get your code to work in one fell swoop, one needs to add the padding to ny.year after calculating the unadjusted ny.val. Also, within the gpar of the textGrob, I needed to change `color` to `col` and `size` to `fontsize`. – tacobean Jun 01 '14 at 18:09
  • @user1462014 Good points. Sorry about that, i tried to optimize as i was posting and didn't fully test. I've updated the code based on your comments. – MrFlick Jun 01 '14 at 18:32