Search code examples
rggplot2interpolationcontourclip

How to clip an interpolated layer in R so it does not extend past data boundaries


I am trying to display a cross-section of conductivity in a lagoon environment using isolines. I have applied interp() and stat_contour() to my data, but I would like to clip the interpolated output so that it doesn't extend past my data points. This way the bathymetry of the lagoon in the cross-section is clear. Here is the code I have used so far:

cond_df <- read_csv("salinity_profile.csv")

di <- interp(cond_df$stop, cond_df$depth, cond_df$conductivity, 
         xo = seq(min(cond_df$stop), max(cond_df$stop), length = 200), 
         yo = seq(min(cond_df$depth), max(cond_df$depth), length = 200))
dat_interp <- data.frame(expand.grid(x=di$x, y=di$y), z=c(di$z))

ggplot(dat_interp) +
  aes(x=x, y=y, z=z, fill=z)+
  scale_y_reverse() +
  geom_tile()+
  stat_contour(colour="white", size=0.25) +
  scale_fill_viridis_c() +
  theme_tufte(base_family="Helvetica")

Here is the output:

interpolated plot

To help clarify, here is the data just as a geom_point() graph, and I do not want the interpolated layer going past the lower points of the graph:

cond_df%>%
  ggplot(mapping=aes(x=stop, y=depth, z=conductivity, fill=conductivity)) +
  geom_point(aes(colour = conductivity), size = 3) +
  scale_y_reverse()

point plot


Solution

  • You can mask the unwanted region of the plot by using geom_ribbon.

    You will need to generate a data.frame with values for the max depth at each stop. Here's one somewhat inelegant way to do that:

    # Create the empty data frame for all stops 
    bathymetry <- data.frame(depth = as.numeric(NA),
                             stop = unique(cond_df$stop))
    
    # Find the max depth for each stop
    for(thisStop in bathymetry$stop){
        bathymetry[bathymetry$stop==thisStop, "depth"] <- max(cond_df[cond_df$stop==thisStop, "depth"])
    }
    

    Then, you can add the geom_ribbon as the last geom of your plot, like so

    geom_ribbon(data=bathymetry, aes(x=stop, ymin=depth, ymax=max(cond_df$depth)), inherit.aes = FALSE)