diff --git a/DESCRIPTION b/DESCRIPTION index f82aa808..27badc44 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -64,6 +64,7 @@ Collate: 'error-checks.R' 'font.R' 'global-vars.R' + 'helpers.R' 'histogram-datamapping.R' 'label.R' 'messages.R' diff --git a/NAMESPACE b/NAMESPACE index 7d8ba79a..acf90922 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -112,7 +112,9 @@ export(getLnTickLabels) export(getLogTickLabels) export(getPKRatioMeasure) export(getPiTickLabels) +export(getSameLimits) export(getSqrtTickLabels) +export(getSymmetricLimits) export(initializePlot) export(loadThemeFromJson) export(plotBoxWhisker) diff --git a/R/aaa-utilities.R b/R/aaa-utilities.R index 187ea083..58b32081 100644 --- a/R/aaa-utilities.R +++ b/R/aaa-utilities.R @@ -92,6 +92,7 @@ #' @title .updateAxes #' @description Updates the plot axes +#' @param plotObject A `ggplot` object #' @return A `ggplot` object #' @keywords internal .updateAxes <- function(plotObject) { @@ -100,3 +101,44 @@ try(suppressMessages(plotObject <- setYAxis(plotObject))) return(plotObject) } + +#' @title .updateSameAxes +#' @description Updates plot configuration axes to get same limits +#' @param plotObject A `ggplot` object +#' @param data A data.frame +#' @param dataMapping A `DataMapping` object +#' @return A `ggplot` object +#' @keywords internal +.updateSameAxes <- function(plotObject, data, dataMapping) { + if(!all( + plotObject$plotConfiguration$defaultSymmetricAxes, + isEmpty(plotObject$plotConfiguration$xAxis$limits), + isEmpty(plotObject$plotConfiguration$yAxis$limits) + )){ + return(plotObject) + } + limits <- .getSameLimitsFromMapping(data, dataMapping) + plotObject$plotConfiguration$xAxis$limits <- limits + plotObject$plotConfiguration$yAxis$limits <- limits + return(plotObject) +} + +#' @title .updateSymmetricAxes +#' @description Updates plot configuration axes to get symmetric limits +#' @param plotObject A `ggplot` object +#' @param data A data.frame +#' @param dataMapping A `DataMapping` object +#' @return A `ggplot` object +#' @keywords internal +.updateSymmetricAxes <- function(plotObject, data, dataMapping) { + if(!all( + plotObject$plotConfiguration$defaultSymmetricAxes, + isEmpty(plotObject$plotConfiguration$yAxis$limits) + )){ + return(plotObject) + } + limits <- getSymmetricLimits(data[, dataMapping$y]) + plotObject$plotConfiguration$yAxis$limits <- limits + return(plotObject) +} + diff --git a/R/helpers.R b/R/helpers.R new file mode 100644 index 00000000..4310eba9 --- /dev/null +++ b/R/helpers.R @@ -0,0 +1,39 @@ +#' @title getSymmetricLimits +#' @description Get symmetric limits from a set of values +#' @param values numeric values +#' @return An array of 2 symmetric values equally distant from 0 +#' @export +#' @examples +#' getSymmetricLimits(seq(-3, 8)) +#' +getSymmetricLimits <- function(values){ + validateIsNumeric(values, nullAllowed = TRUE) + # Remove Inf and NA values + values <- values[!is.infinite(values)] + values <- values[!is.na(values)] + if(isEmpty(values)){ + return(NULL) + } + return(c(-max(abs(values)), max(abs(values)))) +} + + +#' @title getSameLimits +#' @description Get same limits from multiple sets of values +#' @param ... numeric values +#' @return An array of 2 values +#' @export +#' @examples +#' getSameLimits(seq(-3, 8), seq(-12, 4)) +#' +getSameLimits <- function(...){ + values <- c(...) + validateIsNumeric(values, nullAllowed = TRUE) + # Remove Inf and NA values + values <- values[!is.infinite(values)] + values <- values[!is.na(values)] + if(isEmpty(values)){ + return(NULL) + } + return(c(min(values), max(values))) +} \ No newline at end of file diff --git a/R/plot-obs-vs-pred.R b/R/plot-obs-vs-pred.R index e4329a52..3819edc1 100644 --- a/R/plot-obs-vs-pred.R +++ b/R/plot-obs-vs-pred.R @@ -137,6 +137,8 @@ plotObsVsPred <- function(data, data = mapData, mapLabels = mapLabels ) + # Update axes limits if option symmetric and user did not define specific limits + plotObject <- .updateSameAxes(plotObject, mapData, dataMapping) plotObject <- .updateAxes(plotObject) return(plotObject) } diff --git a/R/plot-res-vs-pred.R b/R/plot-res-vs-pred.R index 2d285212..e01b897d 100644 --- a/R/plot-res-vs-pred.R +++ b/R/plot-res-vs-pred.R @@ -108,6 +108,7 @@ plotResVsPred <- function(data, data = mapData, mapLabels = mapLabels ) + plotObject <- .updateSymmetricAxes(plotObject, mapData, dataMapping) plotObject <- .updateAxes(plotObject) return(plotObject) } diff --git a/R/plotconfiguration.R b/R/plotconfiguration.R index 6cb9f633..89cc36a1 100644 --- a/R/plotconfiguration.R +++ b/R/plotconfiguration.R @@ -4,6 +4,7 @@ #' @field defaultXScale Default xAxis scale value when creating a `PlotConfiguration` object #' @field defaultYScale Default yAxis scale value when creating a `PlotConfiguration` object #' @field defaultExpand Default expand value when creating a `PlotConfiguration` object +#' @field defaultSymmetricAxes Default option setting symmetric xAxis and/or yAxis limits when creating a `PlotConfiguration` object #' @family PlotConfiguration classes #' @references For examples, see: #' @@ -17,6 +18,7 @@ PlotConfiguration <- R6::R6Class( defaultXScale = "lin", defaultYScale = "lin", defaultExpand = FALSE, + defaultSymmetricAxes = FALSE, #' @description Create a new `PlotConfiguration` object #' @param title character or `Label` object defining plot title @@ -317,19 +319,27 @@ DDIRatioPlotConfiguration <- R6::R6Class( #' @title ObsVsPredPlotConfiguration #' @description R6 class defining the configuration of a `ggplot` object for Obs vs Pred plots +#' @field defaultSymmetricAxes Default option setting symmetric xAxis and/or yAxis limits when creating a `ObsVsPredPlotConfiguration` object #' @export #' @family PlotConfiguration classes ObsVsPredPlotConfiguration <- R6::R6Class( "ObsVsPredPlotConfiguration", - inherit = PlotConfiguration + inherit = PlotConfiguration, + public = list( + defaultSymmetricAxes = TRUE + ) ) #' @title ResVsPredPlotConfiguration #' @description R6 class defining the configuration of a `ggplot` object for Res vs Pred/Time plots +#' @field defaultSymmetricAxes Default option setting symmetric xAxis and/or yAxis limits when creating a `ResVsPredPlotConfiguration` object #' @export ResVsPredPlotConfiguration <- R6::R6Class( "ResVsPredPlotConfiguration", - inherit = PlotConfiguration + inherit = PlotConfiguration, + public = list( + defaultSymmetricAxes = TRUE + ) ) #' @title ResVsTimePlotConfiguration diff --git a/R/utilities-mapping.R b/R/utilities-mapping.R index ae772a7f..7a1cad39 100644 --- a/R/utilities-mapping.R +++ b/R/utilities-mapping.R @@ -375,3 +375,14 @@ getLinesFromFoldDistance <- function(foldDistance) { return(aggregatedData) } + + +#' @title .getSameLimitsFromMapping +#' @description Get same axes limits from mapped data +#' @param data A data.frame with labels mapped to properties and obtained from a `DataMapping` object +#' @param dataMapping A `ObsVsPredDataMapping` object +#' @keywords internal +.getSameLimitsFromMapping <- function(data, dataMapping){ + getSameLimits(data[,dataMapping$x], data[,dataMapping$y], data[,dataMapping$xmin], data[,dataMapping$xmax]) +} + diff --git a/man/ObsVsPredPlotConfiguration.Rd b/man/ObsVsPredPlotConfiguration.Rd index f86aab69..51d5764b 100644 --- a/man/ObsVsPredPlotConfiguration.Rd +++ b/man/ObsVsPredPlotConfiguration.Rd @@ -20,6 +20,13 @@ Other PlotConfiguration classes: \section{Super class}{ \code{tlf::PlotConfiguration} -> \code{ObsVsPredPlotConfiguration} } +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{defaultSymmetricAxes}}{Default option setting symmetric xAxis and/or yAxis limits when creating a \code{ObsVsPredPlotConfiguration} object} +} +\if{html}{\out{
}} +} \section{Methods}{ \subsection{Public methods}{ \itemize{ diff --git a/man/PlotConfiguration.Rd b/man/PlotConfiguration.Rd index e1936917..04b6ef36 100644 --- a/man/PlotConfiguration.Rd +++ b/man/PlotConfiguration.Rd @@ -31,6 +31,8 @@ Other PlotConfiguration classes: \item{\code{defaultYScale}}{Default yAxis scale value when creating a \code{PlotConfiguration} object} \item{\code{defaultExpand}}{Default expand value when creating a \code{PlotConfiguration} object} + +\item{\code{defaultSymmetricAxes}}{Default option setting symmetric xAxis and/or yAxis limits when creating a \code{PlotConfiguration} object} } \if{html}{\out{}} } diff --git a/man/ResVsPredPlotConfiguration.Rd b/man/ResVsPredPlotConfiguration.Rd index d04071ec..9edd31dc 100644 --- a/man/ResVsPredPlotConfiguration.Rd +++ b/man/ResVsPredPlotConfiguration.Rd @@ -9,6 +9,13 @@ R6 class defining the configuration of a \code{ggplot} object for Res vs Pred/Ti \section{Super class}{ \code{tlf::PlotConfiguration} -> \code{ResVsPredPlotConfiguration} } +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{defaultSymmetricAxes}}{Default option setting symmetric xAxis and/or yAxis limits when creating a \code{ResVsPredPlotConfiguration} object} +} +\if{html}{\out{
}} +} \section{Methods}{ \subsection{Public methods}{ \itemize{ diff --git a/man/dot-getSameLimitsFromMapping.Rd b/man/dot-getSameLimitsFromMapping.Rd new file mode 100644 index 00000000..f762970f --- /dev/null +++ b/man/dot-getSameLimitsFromMapping.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utilities-mapping.R +\name{.getSameLimitsFromMapping} +\alias{.getSameLimitsFromMapping} +\title{.getSameLimitsFromMapping} +\usage{ +.getSameLimitsFromMapping(data, dataMapping) +} +\arguments{ +\item{data}{A data.frame with labels mapped to properties and obtained from a \code{DataMapping} object} + +\item{dataMapping}{A \code{ObsVsPredDataMapping} object} +} +\description{ +Get same axes limits from mapped data +} +\keyword{internal} diff --git a/man/dot-updateAxes.Rd b/man/dot-updateAxes.Rd index 9bc556a4..295af87b 100644 --- a/man/dot-updateAxes.Rd +++ b/man/dot-updateAxes.Rd @@ -6,6 +6,9 @@ \usage{ .updateAxes(plotObject) } +\arguments{ +\item{plotObject}{A \code{ggplot} object} +} \value{ A \code{ggplot} object } diff --git a/man/dot-updateSameAxes.Rd b/man/dot-updateSameAxes.Rd new file mode 100644 index 00000000..bf29adb7 --- /dev/null +++ b/man/dot-updateSameAxes.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aaa-utilities.R +\name{.updateSameAxes} +\alias{.updateSameAxes} +\title{.updateSameAxes} +\usage{ +.updateSameAxes(plotObject, data, dataMapping) +} +\arguments{ +\item{plotObject}{A \code{ggplot} object} + +\item{data}{A data.frame} + +\item{dataMapping}{A \code{DataMapping} object} +} +\value{ +A \code{ggplot} object +} +\description{ +Updates plot configuration axes to get same limits +} +\keyword{internal} diff --git a/man/dot-updateSymmetricAxes.Rd b/man/dot-updateSymmetricAxes.Rd new file mode 100644 index 00000000..16e6a7f1 --- /dev/null +++ b/man/dot-updateSymmetricAxes.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aaa-utilities.R +\name{.updateSymmetricAxes} +\alias{.updateSymmetricAxes} +\title{.updateSymmetricAxes} +\usage{ +.updateSymmetricAxes(plotObject, data, dataMapping) +} +\arguments{ +\item{plotObject}{A \code{ggplot} object} + +\item{data}{A data.frame} + +\item{dataMapping}{A \code{DataMapping} object} +} +\value{ +A \code{ggplot} object +} +\description{ +Updates plot configuration axes to get symmetric limits +} +\keyword{internal} diff --git a/man/getSameLimits.Rd b/man/getSameLimits.Rd new file mode 100644 index 00000000..0c5ca9fb --- /dev/null +++ b/man/getSameLimits.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/helpers.R +\name{getSameLimits} +\alias{getSameLimits} +\title{getSameLimits} +\usage{ +getSameLimits(...) +} +\arguments{ +\item{...}{numeric values} +} +\value{ +An array of 2 values +} +\description{ +Get same limits from multiple sets of values +} +\examples{ +getSameLimits(seq(-3, 8), seq(-12, 4)) + +} diff --git a/man/getSymmetricLimits.Rd b/man/getSymmetricLimits.Rd new file mode 100644 index 00000000..638bf758 --- /dev/null +++ b/man/getSymmetricLimits.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/helpers.R +\name{getSymmetricLimits} +\alias{getSymmetricLimits} +\title{getSymmetricLimits} +\usage{ +getSymmetricLimits(values) +} +\arguments{ +\item{values}{numeric values} +} +\value{ +An array of 2 symmetric values equally distant from 0 +} +\description{ +Get symmetric limits from a set of values +} +\examples{ +getSymmetricLimits(seq(-3, 8)) + +}