This code produces the first plot below:
water.height <- seq(0, 5, 1)
y <- seq(0, 1500, length.out = 6)
df <- data.frame(water.height, y)
library(ggplot2)
ggplot(df, aes(water.height, y)) + geom_blank()+ theme_bw()

I have photoshopped in this blue background:

Can I produce the same blue background with R code?
Select the Gradient tool in the toolbar. In the selected artwork you'll see the gradient annotator, which shows the gradient slider and the color stops. Double-click a color stop on the artwork to edit the color, drag the color stops, click beneath the gradient slider to add new color stops, and more.
To create the most basic type of gradient, all you need is to specify two colors. These are called color stops. You must have at least two, but you can have as many as you want.
The relevant link to the ggplot2 approach was given in the comments. Copied from there:
library(grid) 
g <- rasterGrob(blues9, width=unit(1,"npc"), height = unit(1,"npc"), 
interpolate = TRUE) 
# grid.draw(g) 
library(ggplot2) 
ggplot(mtcars, aes(factor(cyl))) + # add gradient background 
   annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) + 
   geom_bar() # add data layer 
My own approach:
As usual, I cannot compete with the simple elegance of baptiste's solutions for problems with grid graphics, but here is my approach since I went to all that work:
gg.background.fill <- function(gg.plot, cols = "white", which = "x") {
  #does not work with facets
  stopifnot(which %in% c("x", "y"))
  which1 <- if (which == "x") "width" else "height"
  require(gridExtra)
  g <- ggplotGrob(gg.plot)
  #g <- ggplotGrob(p)
  gg <- g$grobs      
  findIt <- vapply(gg, function(x) grepl("GRID.gTree", x$name, fixed = TRUE), TRUE)
  n1 <- getGrob(gg[findIt][[1]], "grill.gTree", grep=TRUE)$name
  n2 <- getGrob(gg[findIt][[1]], "panel.background.rect", grep=TRUE)$name
  gg[findIt][[1]]$children[[n1]]$children[[n2]]$gp$fill <- cols
  x <- gg[findIt][[1]]$children[[n1]]$children[[n2]][[which]]
  w <- gg[findIt][[1]]$children[[n1]]$children[[n2]][[which1]]
  attr <- attributes(x)
  x <- seq(0 + c(w)/length(cols)/2, 1 - c(w)/length(cols)/2, length.out = length(cols))
  attributes(x) <- attr
  gg[findIt][[1]]$children[[n1]]$children[[n2]][[which]] <- x
  w <- c(w)/length(cols) 
  attributes(w) <- attr
  gg[findIt][[1]]$children[[n1]]$children[[n2]][[which1]] <- w
  g$grobs <- gg
  class(g) = c("arrange", "ggplot", class(g)) 
  g
}
p1 <-  gg.background.fill(p, colorRampPalette(c("red", "blue"))(100))
print(p1)

p2 <-  gg.background.fill(p, colorRampPalette(c("red", "blue"))(100), "y")
print(p2)

This modifies the existing background which might be considered an advantage, but in contrast to the annotation_custom approach it doesn't work with faceting. More work would be required for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With