From 3aa51aba2ae92ccb5bc17fc4915a307d1c9871f8 Mon Sep 17 00:00:00 2001 From: nperez Date: Wed, 2 Oct 2019 11:39:20 +0200 Subject: [PATCH 1/2] Adding ybreaks and rain palette --- R/PlotForecastPDF.R | 55 +++++++++++++++++++++++++++++++++++------- man/PlotForecastPDF.Rd | 12 ++++++--- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/R/PlotForecastPDF.R b/R/PlotForecastPDF.R index cf531063..799ba289 100644 --- a/R/PlotForecastPDF.R +++ b/R/PlotForecastPDF.R @@ -1,6 +1,9 @@ #'Plot one or multiple ensemble forecast pdfs for the same event #' -#'@author Llorenç Lledó \email{llledo@bsc.es} +#'@author +#' History: +#' 1.0.0 - 2019-04 (Llorenç Lledó, \email{llledo@bsc.es}) - Original code +#' 2.0.0 - 2019-09 (Carmen Alvarez-Castro, \email{carmen.alvarez-castro@cmcc.it}) - Add color palette and ybreak parameter #'@description This function plots the probability distribution function of several ensemble forecasts for the same event, either initialized at different moments or by different models. Probabilities for tercile categories are computed, plotted in colors and annotated. An asterisk marks the tercile with higher probabilities. Probabilities for extreme categories (above P90 and below P10) can also be included as hatched areas. Individual ensemble members can be plotted as jittered points. The observed value is optionally shown as a diamond. #' #'@param fcst a dataframe or array containing all the ensember members for each frecast. If \code{'fcst'} is an array, it should have two labelled dimensions, and one of them should be \code{'members'}. If \code{'fcsts'} is a data.frame, each column shoul be a separate forecast, with the rows beeing the different ensemble members. @@ -11,6 +14,7 @@ #'@param title a string with the plot title. #'@param var.name a string with the variable name and units. #'@param fcst.names (optional) an array of strings with the titles of each individual forecast. +#'@param ybreak (optional) a ... #'@param add.ensmemb either to add the ensemble members \code{'above'} (default) or \code{'below'} the pdf, or not (\code{'no'}). #'@param color.set a selection of predefined color sets: use \code{'ggplot'} (default) for blue/green/red, \code{'s2s4e'} for blue/grey/orange, or \code{'hydro'} for yellow/gray/blue (suitable for precipitation and inflows). #' @@ -35,8 +39,9 @@ #'} #'@export PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = NULL, - plotfile = NULL, title = "Set a title", var.name = "Varname (units)", fcst.names = NULL, - add.ensmemb = c("above", "below", "no"), color.set = c("ggplot", "s2s4e", "hydro")) { + plotfile = NULL, title = "Set a title", var.name = "Varname (units)", + fcst.names = NULL, ybreak = NULL, + add.ensmemb = c("above", "below", "no"), color.set = c("ggplot", "s2s4e", "hydro", "rain")) { value <- init <- extremes <- x <- ymin <- ymax <- tercile <- y <- xend <- yend <- yjitter <- MLT <- NULL ggColorHue <- function(n) { hues <- seq(15, 375, length = n + 1) @@ -64,8 +69,15 @@ PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = N colorMember <- c("#ffff7f") colorObs <- "purple" colorLab <- c("blue", "red") + } else if (color.set == "rain") { + colorFill <- rev(c("#4CAF50", "#B0BEC5", "#FFCA28")) + colorHatch <- c("#E65100","#33691E") + colorMember <- c("#795548") + colorObs <- "#9C27B0" + colorLab <- c("#E65100","#33691E") } else { - stop("Parameter 'color.set' should be one of ggplot/s2s4e/hydro") + stop("Parameter 'color.set' should be one of 'ggplot', 's2s4e',", + " 'hydro' or 'rain'.") } #------------------------ # Check input arguments @@ -120,6 +132,18 @@ PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = N coord_flip() + facet_wrap(~init, strip.position = "top", nrow = 1) + xlim(range(c(obs, density(melt.df$value, na.rm = T)$x))) ggp <- ggplot_build(plot) + #-------------------------- + # Add detailed y axes + #------------------------ + left_major = seq(round(min(melt.df$value,na.rm=TRUE),-1), 0, ybreaks) + right_major = seq(0, round(max(melt.df$value,na.rm=TRUE),-1), ybreaks) + left_minor = seq(round(min(melt.df$value,na.rm=TRUE),-1), 0, ybreaks/2) + right_minor = seq(0, round(max(melt.df$value,na.rm=TRUE),-1), ybreaks/2) + plot <- plot + + scale_x_continuous(name = "Anomaly (mm/month) \n", + limits = range(c(obs, density(melt.df$value, na.rm = T)$x)), + breaks = c(left_major, 0, right_major), + minor_breaks = c(left_minor,0,right_minor)) #------------------------ # Gather the coordinates of the plots together with init and corresponding # terciles @@ -217,7 +241,7 @@ PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = N } } #------------------------ - # Add obs line + # Add obs line and value #------------------------ if (!is.null(obs)) { plot <- plot + geom_vline(data = obs.dt, aes(xintercept = value), linetype = "dashed", @@ -295,6 +319,14 @@ PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = N dim(fcst.df)[2])) } #------------------------ + # Add label for observation + #------------------------ + if (!is.null(obs)) { + plot <- plot + #this adds the observation label + geom_text(data = obs.xy, aes(x = x + 5, y = ymax + 0.005), label = paste0(round(obs.xy$x,2)), + vjust = vjust, angle = -90, size = 3.2, color = colorObs) + } + #------------------------ # Finish all theme and legend details #------------------------ plot <- plot + theme_minimal() + scale_fill_manual(name = "Probability of\nterciles", @@ -302,10 +334,15 @@ PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = N drop = F) + scale_color_manual(name = "Probability of\nextremes", values = colorHatch) + scale_shape_manual(name = "Ensemble\nmembers", values = c(21)) + scale_size_manual(name = "Observation", values = c(3)) + labs(x = var.name, y = "Probability density\n(total area=1)", - title = title) + theme(axis.text.x = element_blank(), panel.grid.minor.x = element_blank(), - legend.key.size = unit(0.3, "in"), panel.border = element_rect(fill = NA, - color = "black"), strip.background = element_rect(colour = "black", fill = "gray80"), - panel.spacing = unit(0.2, "in"), panel.grid.major.x = element_line(color = "grey93")) + + title = title) + + theme(axis.text.x = element_blank(), panel.grid.minor.x = element_blank(), + axis.text.y=element_text(size = 12, face = "bold"), + plot.title=element_text(size = 14, face = "bold"), + legend.key.size = unit(0.3, "in"), + panel.border = element_rect(fill = NA, color = "black"), + strip.background = element_rect(colour = "black", fill = "azure1"), + strip.text=element_text(colour = "black", size = 12, face = "bold"), + panel.grid.major.x = element_line(color = "grey93"))+ guides(fill = guide_legend(order = 1), color = guide_legend(order = 2, reverse = T), shape = guide_legend(order = 3, label = F), size = guide_legend(order = 4, label = F)) diff --git a/man/PlotForecastPDF.Rd b/man/PlotForecastPDF.Rd index bed0bd31..32ae1c1e 100644 --- a/man/PlotForecastPDF.Rd +++ b/man/PlotForecastPDF.Rd @@ -6,8 +6,8 @@ \usage{ PlotForecastPDF(fcst, tercile.limits, extreme.limits = NULL, obs = NULL, plotfile = NULL, title = "Set a title", var.name = "Varname (units)", - fcst.names = NULL, add.ensmemb = c("above", "below", "no"), - color.set = c("ggplot", "s2s4e", "hydro")) + fcst.names = NULL, ybreak = NULL, add.ensmemb = c("above", "below", + "no"), color.set = c("ggplot", "s2s4e", "hydro", "rain")) } \arguments{ \item{fcst}{a dataframe or array containing all the ensember members for each frecast. If \code{'fcst'} is an array, it should have two labelled dimensions, and one of them should be \code{'members'}. If \code{'fcsts'} is a data.frame, each column shoul be a separate forecast, with the rows beeing the different ensemble members.} @@ -26,6 +26,8 @@ PlotForecastPDF(fcst, tercile.limits, extreme.limits = NULL, obs = NULL, \item{fcst.names}{(optional) an array of strings with the titles of each individual forecast.} +\item{ybreak}{(optional) a ...} + \item{add.ensmemb}{either to add the ensemble members \code{'above'} (default) or \code{'below'} the pdf, or not (\code{'no'}).} \item{color.set}{a selection of predefined color sets: use \code{'ggplot'} (default) for blue/green/red, \code{'s2s4e'} for blue/grey/orange, or \code{'hydro'} for yellow/gray/blue (suitable for precipitation and inflows).} @@ -47,6 +49,8 @@ PlotForecastPDF(fcsts2, c(-0.66, 0.66), extreme.limits = c(-1.2, 1.2), } } \author{ -Llorenç Lledó \email{llledo@bsc.es} +History: +1.0.0 - 2019-04 (Llorenç Lledó, \email{llledo@bsc.es}) - Original code +2.0.0 - 2019-09 (Carmen Alvarez-Castro, \email{carmen.alvarez-castro@cmcc.it}) - Add color palette and ybreak parameter } -\encoding{UTF-8} + -- GitLab From 4dc2b07939e3ad46936d18a23399cdbbe38a924d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lloren=C3=A7=20Lled=C3=B3?= Date: Mon, 21 Oct 2019 12:09:51 +0200 Subject: [PATCH 2/2] Update PlotForecastPDF.R to correct ybreak to ybreaks --- R/PlotForecastPDF.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/PlotForecastPDF.R b/R/PlotForecastPDF.R index 799ba289..12de8139 100644 --- a/R/PlotForecastPDF.R +++ b/R/PlotForecastPDF.R @@ -3,7 +3,7 @@ #'@author #' History: #' 1.0.0 - 2019-04 (Llorenç Lledó, \email{llledo@bsc.es}) - Original code -#' 2.0.0 - 2019-09 (Carmen Alvarez-Castro, \email{carmen.alvarez-castro@cmcc.it}) - Add color palette and ybreak parameter +#' 2.0.0 - 2019-09 (Carmen Alvarez-Castro, \email{carmen.alvarez-castro@cmcc.it}) - Add rain color palette and ybreaks parameter #'@description This function plots the probability distribution function of several ensemble forecasts for the same event, either initialized at different moments or by different models. Probabilities for tercile categories are computed, plotted in colors and annotated. An asterisk marks the tercile with higher probabilities. Probabilities for extreme categories (above P90 and below P10) can also be included as hatched areas. Individual ensemble members can be plotted as jittered points. The observed value is optionally shown as a diamond. #' #'@param fcst a dataframe or array containing all the ensember members for each frecast. If \code{'fcst'} is an array, it should have two labelled dimensions, and one of them should be \code{'members'}. If \code{'fcsts'} is a data.frame, each column shoul be a separate forecast, with the rows beeing the different ensemble members. @@ -14,7 +14,7 @@ #'@param title a string with the plot title. #'@param var.name a string with the variable name and units. #'@param fcst.names (optional) an array of strings with the titles of each individual forecast. -#'@param ybreak (optional) a ... +#'@param ybreaks (optional) a ... #'@param add.ensmemb either to add the ensemble members \code{'above'} (default) or \code{'below'} the pdf, or not (\code{'no'}). #'@param color.set a selection of predefined color sets: use \code{'ggplot'} (default) for blue/green/red, \code{'s2s4e'} for blue/grey/orange, or \code{'hydro'} for yellow/gray/blue (suitable for precipitation and inflows). #' @@ -40,7 +40,7 @@ #'@export PlotForecastPDF <- function(fcst, tercile.limits, extreme.limits = NULL, obs = NULL, plotfile = NULL, title = "Set a title", var.name = "Varname (units)", - fcst.names = NULL, ybreak = NULL, + fcst.names = NULL, ybreaks = NULL, add.ensmemb = c("above", "below", "no"), color.set = c("ggplot", "s2s4e", "hydro", "rain")) { value <- init <- extremes <- x <- ymin <- ymax <- tercile <- y <- xend <- yend <- yjitter <- MLT <- NULL ggColorHue <- function(n) { -- GitLab