Skip to content

Instantly share code, notes, and snippets.

@fawda123
Created August 29, 2016 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fawda123/00003218e6a913f681fa16e587c7fbbb to your computer and use it in GitHub Desktop.
Save fawda123/00003218e6a913f681fa16e587c7fbbb to your computer and use it in GitHub Desktop.
plotFlowConc for OWI blog
plotFlowConc <- function(eList, month = c(1:12), years = NULL, col_vec = c('red', 'green', 'blue'), ylabel = NULL, xlabel = NULL, alpha = 1, size = 1, allflo = FALSE, ncol = NULL, grids = TRUE, scales = NULL, interp = 4, pretty = TRUE, use_bw = TRUE, fac_nms = NULL, ymin = 0){
localDaily <- getDaily(eList)
localINFO <- getInfo(eList)
localsurfaces <- getSurfaces(eList)
# plot title
toplab <- with(eList$INFO, paste(shortName, paramShortName, sep = ', '))
# flow, date info for interpolation surface
LogQ <- seq(localINFO$bottomLogQ, by=localINFO$stepLogQ, length.out=localINFO$nVectorLogQ)
year <- seq(localINFO$bottomYear, by=localINFO$stepYear, length.out=localINFO$nVectorYear)
jday <- 1 + round(365 * (year - floor(year)))
surfyear <- floor(year)
surfdts <- as.Date(paste(surfyear, jday, sep = '-'), format = '%Y-%j')
surfmos <- as.numeric(format(surfdts, '%m'))
surfday <- as.numeric(format(surfdts, '%d'))
# interpolation surface
ConcDay <- localsurfaces[,,3]
# convert month vector to those present in data
month <- month[month %in% surfmos]
if(length(month) == 0) stop('No observable data for the chosen month')
# salinity/flow grid values
flo_grd <- LogQ
# get the grid
to_plo <- data.frame(date = surfdts, year = surfyear, month = surfmos, day = surfday, t(ConcDay))
# reshape data frame, average by year, month for symmetry
to_plo <- to_plo[to_plo$month %in% month, , drop = FALSE]
names(to_plo)[grep('^X', names(to_plo))] <- paste('flo', flo_grd)
to_plo <- tidyr::gather(to_plo, 'flo', 'res', 5:ncol(to_plo)) %>%
mutate(flo = as.numeric(gsub('^flo ', '', flo))) %>%
select(-day)
# smooth the grid
if(!is.null(interp)){
to_interp <- to_plo
to_interp <- ungroup(to_interp) %>%
select(date, flo, res) %>%
tidyr::spread(flo, res)
# values to pass to interp
dts <- to_interp$date
fit_grd <- select(to_interp, -date)
flo_fac <- length(flo_grd) * interp
flo_fac <- seq(min(flo_grd), max(flo_grd), length.out = flo_fac)
yr_fac <- seq(min(dts), max(dts), length.out = length(dts) * interp)
to_interp <- expand.grid(yr_fac, flo_fac)
# bilinear interpolation of fit grid
interps <- interp.surface(
obj = list(
y = flo_grd,
x = dts,
z = data.frame(fit_grd)
),
loc = to_interp
)
# format interped output
to_plo <- data.frame(to_interp, interps) %>%
rename(date = Var1,
flo = Var2,
res = interps
) %>%
mutate(
month = as.numeric(format(date, '%m')),
year = as.numeric(format(date, '%Y'))
)
}
# subset years to plot
if(!is.null(years)){
to_plo <- to_plo[to_plo$year %in% years, ]
to_plo <- to_plo[to_plo$month %in% month, ]
if(nrow(to_plo) == 0) stop('No data to plot for the date range')
}
# summarize so no duplicate flos for month/yr combos
to_plo <- group_by(to_plo, year, month, flo) %>%
summarize(res = mean(res, na.rm = TRUE)) %>%
ungroup
# axis labels
if(is.null(ylabel))
ylabel <- localINFO$paramShortName
if(is.null(xlabel))
xlabel <- expression(paste('Discharge in ', m^3, '/s'))
# constrain plots to salinity/flow limits for the selected month
if(!allflo){
#min, max flow values to plot
lim_vals<- group_by(data.frame(localDaily), Month) %>%
summarize(
Low = quantile(LogQ, 0.05, na.rm = TRUE),
High = quantile(LogQ, 0.95, na.rm = TRUE)
)
# month flo ranges for plot
lim_vals <- lim_vals[lim_vals$Month %in% month, ]
lim_vals <- rename(lim_vals, month = Month)
# merge limits with months
to_plo <- left_join(to_plo, lim_vals, by = 'month')
to_plo <- to_plo[to_plo$month %in% month, ]
# reduce data
sel_vec <- with(to_plo,
flo >= Low &
flo <= High
)
to_plo <- to_plo[sel_vec, !names(to_plo) %in% c('Low', 'High')]
to_plo <- arrange(to_plo, year, month)
}
# months labels as text
mo_lab <- data.frame(
num = seq(1:12),
txt = c('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
)
mo_lab <- mo_lab[mo_lab$num %in% month, ]
to_plo$month <- factor(to_plo$month, levels = mo_lab$num, labels = mo_lab$txt)
# reassign facet names if fac_nms is provided
if(!is.null(fac_nms)){
if(length(fac_nms) != length(unique(to_plo$month)))
stop('fac_nms must have same lengths as months')
to_plo$month <- factor(to_plo$month, labels = fac_nms)
}
# convert discharge to arithmetic scale
to_plo$flo <- exp(to_plo$flo)
# make plot
p <- ggplot(to_plo, aes(x = flo, y = res, group = year)) +
facet_wrap(~month, ncol = ncol, scales = scales)
# set lower limit for y-axis if applicable
lims <- coord_cartesian(ylim = c(ymin, max(to_plo$res, na.rm = TRUE)))
if(!is.null(scales)){
if(scales == 'free_x') p <- p + lims
} else {
p <- p + lims
}
# return bare bones if FALSE
if(!pretty) return(p + geom_line())
# get colors
cols <- col_vec
# use bw theme
if(use_bw) p <- p + theme_bw()
# log scale breaks
brks <- c(0, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000)
p <- p +
geom_line(size = size, aes(colour = year), alpha = alpha) +
scale_y_continuous(ylabel, expand = c(0, 0)) +
scale_x_log10(xlabel, expand = c(0, 0), breaks = brks) +
theme(
legend.position = 'top',
axis.text.x = element_text(size = 8),
axis.text.y = element_text(size = 8)
) +
scale_colour_gradientn('Year', colours = cols) +
guides(colour = guide_colourbar(barwidth = 10)) +
ggtitle(toplab)
# remove grid lines
if(!grids)
p <- p +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)
return(p)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment