diff --git a/DESCRIPTION b/DESCRIPTION index be99668..58af8d5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: flipPlots Type: Package Title: Creates Plots -Version: 1.3.7 +Version: 1.3.8 Author: Displayr Maintainer: Displayr Description: Wrappers for various plot types. @@ -9,13 +9,12 @@ License: GPL-3 LazyData: FALSE Imports: flipTransformations, + flipStandardCharts, flipU (>= 1.6.2), networkD3, mgcv, - ggplot2 (<= 3.4.4), plotly, scales, - rlang, verbs Suggests: flipExampleData, @@ -23,6 +22,7 @@ Suggests: testthat, Remotes: Displayr/flipTransformations, + Displayr/flipStandardCharts, Displayr/flipU, Displayr/networkD3, Displayr/plotly, diff --git a/NAMESPACE b/NAMESPACE index 0f2e58d..c6233be 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,29 +2,24 @@ export(SankeyDiagram) export(SplineWithSimultaneousConfIntervals) +importFrom(flipStandardCharts,Line) importFrom(flipTransformations,AdjustDataToReflectWeights) importFrom(flipTransformations,AsNumeric) importFrom(flipTransformations,DichotomizeFactor) importFrom(flipTransformations,Factor) importFrom(flipU,MakeUniqueNames) importFrom(flipU,StopForUserError) -importFrom(ggplot2,aes) -importFrom(ggplot2,geom_path) -importFrom(ggplot2,geom_ribbon) -importFrom(ggplot2,ggplot) -importFrom(ggplot2,labs) -importFrom(ggplot2,scale_y_continuous) -importFrom(ggplot2,theme_bw) -importFrom(ggplot2,theme_set) importFrom(grDevices,col2rgb) importFrom(grDevices,rgb) importFrom(mgcv,gam) importFrom(mgcv,mroot) importFrom(networkD3,JS) importFrom(networkD3,sankeyNetwork) +importFrom(plotly,add_lines) +importFrom(plotly,add_ribbons) importFrom(plotly,config) -importFrom(plotly,ggplotly) -importFrom(rlang,.data) +importFrom(plotly,layout) +importFrom(plotly,plot_ly) importFrom(scales,percent) importFrom(stats,binomial) importFrom(stats,coef) diff --git a/R/splinewithsimultaneousconfint.R b/R/splinewithsimultaneousconfint.R index 40dc87f..c51e60e 100644 --- a/R/splinewithsimultaneousconfint.R +++ b/R/splinewithsimultaneousconfint.R @@ -1,5 +1,6 @@ #' Plots spline with confidence intervals #' +#' @inheritParams flipStandardCharts::Line #' @param outcome Outcome variable shown in the y-axis. This should be convertible using \code{AsNumeric}. #' @param predictor Predictor variable shown in the x-axis. This should be a numeric or date variable. #' @param type Regression link function used. Currently can be "Binary Logit" or "Linear". @@ -9,17 +10,25 @@ #' @param weights Optional numeric vector used as sampling weights. #' @param seed Random seed for reproducibility #' @param confidence Width of confidence interval shown around the spline. +#' @param ci.color Color of the ribbon showing the confidence interval. #' @param number.draws Number of possible trend lines to super-impose. -#' @param trim.padding Logical; whether to remove padding around plotly chart. +#' @param draw.color Color of the possible trend lines. +#' @param draw.weight Line weight of the possible trend line. +#' @param mean.color Line color of the mean (or predicted) line. +#' @param mean.weight Line weight of the mean line. +#' @param font.units One of "px" of "pt". By default all font sizes are specified in terms of +#' pixels ("px"). But changing this to "pt" will mean that the font sizes will be in terms +#' points ("pt"), which will be consistent with font sizes in text boxes. +#' @param trim.padding (Deprecated)Logical; whether to remove padding around plotly chart. #' Default is set to false so that output is the same as old charts. +#' @param ... Other parameters to pass to flipStandardCharts::Line. +#' @importFrom flipStandardCharts Line #' @importFrom flipTransformations AsNumeric AdjustDataToReflectWeights DichotomizeFactor #' @importFrom flipU StopForUserError #' @importFrom mgcv gam mroot -#' @importFrom ggplot2 ggplot geom_ribbon geom_path aes theme_set theme_bw labs scale_y_continuous -#' @importFrom plotly ggplotly config +#' @importFrom plotly plot_ly add_ribbons add_lines layout config #' @importFrom utils stack #' @importFrom scales percent -#' @importFrom rlang .data #' @importFrom stats binomial coef complete.cases family predict quantile rnorm vcov gaussian #' @importFrom verbs Sum #' @export @@ -31,7 +40,28 @@ SplineWithSimultaneousConfIntervals <- function(outcome, seed = 42, number.draws = 30, confidence = 0.95, - trim.padding = FALSE) + mean.color = "#000000", + mean.weight = 2, + draw.color = "#33333366", + draw.weight = 1, + ci.color = "#FF000033", + y.tick.format = NULL, + x.grid.width = 1, + y.hovertext.format = ".1f", + title = NULL, + x.title = NULL, + y.title = NULL, + global.font.family = "Open Sans", + global.font.color = rgb(44, 44, 44, maxColorValue = 255), + title.font.size = 12, + hovertext.font.size = 9, + y.title.font.size = 10, + x.title.font.size = 10, + y.tick.font.size = 9, + x.tick.font.size = 9, + font.units = "pt", + trim.padding = FALSE, + ...) { if (length(unique(outcome)) == 1) StopForUserError("Could not construct model as outcome variable contains only one value.") @@ -115,14 +145,46 @@ SplineWithSimultaneousConfIntervals <- function(outcome, sims <- rmvn(N, mu = coef(m), sig = Vb) fits <- Cg %*% t(sims) + if (is.null(title)) + title <- paste0("Simultaneous ", confidence * 100, "% confidence intervals for fitted GAM") + if (is.null(x.title)) + x.title <- xlab + if (is.null(y.title)) + y.title <- ylab + if (is.null(y.tick.format) && logit) + y.tick.format <- "%" + + # For the standard charts, the font size conversion happens inside flipChart::CChart + if (tolower(font.units) %in% c("pt", "point", "points")) + { + fsc <- 1.3333 + title.font.size = round(fsc * title.font.size, 0) + hovertext.font.size = round(fsc * hovertext.font.size, 0) + y.title.font.size = round(fsc * y.title.font.size, 0) + x.title.font.size = round(fsc * x.title.font.size, 0) + y.tick.font.size = round(fsc * y.tick.font.size, 0) + x.tick.font.size = round(fsc * x.tick.font.size, 0) + } + # Create plot - theme_set(theme_bw()) - p <- ggplot(pred, aes(x = .data$predictor, y = .data$fit)) + - geom_ribbon(aes(ymin = .data$lwrS, ymax = .data$uprS), alpha = 0.2, fill = "red") + - geom_path(lwd = 2) + - labs(y = ylab, x = xlab, - title = paste0("Simultaneous ", confidence * 100, "% confidence intervals for fitted GAM"), - subtitle = sprintf("Each line is one of %i draws from the Bayesian posterior distribution of the model", number.draws)) + plot.data <- pred$fit + names(plot.data) <- pred$predictor + pp <- Line(plot.data, colors = mean.color, line.thickness = mean.weight, + title = title, x.title = x.title, y.title = y.title, + y.tick.format = y.tick.format, y.hovertext.format = y.hovertext.format, + global.font.family = global.font.family, global.font.color = global.font.color, + title.font.size = title.font.size, x.grid.width = x.grid.width, + y.title.font.size = y.title.font.size, x.title.font.size = x.title.font.size, + y.tick.font.size = y.tick.font.size, x.tick.font.size = x.tick.font.size, + hovertext.font.size = hovertext.font.size, legend.show = FALSE, ...) + + pp$htmlwidget <- add_ribbons(pp$htmlwidget, x = pred$predictor, + ymin = pred$lwrS, ymax = pred$uprS, + fillcolor = ci.color, line = list(color = "transparent"), + text = sprintf(paste0("[%", y.hovertext.format, ", %", y.hovertext.format, "]"), pred$lwrS, pred$uprS), + hovertemplate = "%{x}: %{text}", + hoverlabel = list(font = list(color = flipStandardCharts:::autoFontColor(ci.color))), + name = "Confidence Interval") if (number.draws > 0) { @@ -131,14 +193,14 @@ SplineWithSimultaneousConfIntervals <- function(outcome, else stack(as.data.frame(fits[, rnd])) stackFits <- transform(stackFits, predictor.numeric = rep(newd$predictor.numeric, length(rnd))) stackFits$predictor = newd$predictor - p = p + geom_path(data = stackFits, - mapping = aes(y = .data$values, x = .data$predictor, group = .data$ind), - alpha = 0.4, colour = "grey20") + for (i in unique(stackFits$ind)) + { + ind <- which(stackFits$ind == i) + pp$htmlwidget <- add_lines(pp$htmlwidget, x = stackFits$predictor[ind], y = stackFits$values[ind], + line = list(color = draw.color, width = draw.weight), + hoverlabel = list(font = list(color = flipStandardCharts:::autoFontColor(draw.color))), + name = paste("Draw", i)) + } } - if (logit) - p <- p + scale_y_continuous(labels = percent) - p <- ggplotly(p) - p <- config(p, displayModeBar = FALSE) - p$sizingPolicy$browser$padding <- if (trim.padding) 0 else 40 - p + pp } diff --git a/man/SplineWithSimultaneousConfIntervals.Rd b/man/SplineWithSimultaneousConfIntervals.Rd index f6de87d..26fad3d 100644 --- a/man/SplineWithSimultaneousConfIntervals.Rd +++ b/man/SplineWithSimultaneousConfIntervals.Rd @@ -13,7 +13,28 @@ SplineWithSimultaneousConfIntervals( seed = 42, number.draws = 30, confidence = 0.95, - trim.padding = FALSE + mean.color = "#000000", + mean.weight = 2, + draw.color = "#33333366", + draw.weight = 1, + ci.color = "#FF000033", + y.tick.format = NULL, + x.grid.width = 1, + y.hovertext.format = ".1f", + title = NULL, + x.title = NULL, + y.title = NULL, + global.font.family = "Open Sans", + global.font.color = rgb(44, 44, 44, maxColorValue = 255), + title.font.size = 12, + hovertext.font.size = 9, + y.title.font.size = 10, + x.title.font.size = 10, + y.tick.font.size = 9, + x.tick.font.size = 9, + font.units = "pt", + trim.padding = FALSE, + ... ) } \arguments{ @@ -35,8 +56,58 @@ in the analysis.} \item{confidence}{Width of confidence interval shown around the spline.} -\item{trim.padding}{Logical; whether to remove padding around plotly chart. +\item{mean.color}{Line color of the mean (or predicted) line.} + +\item{mean.weight}{Line weight of the mean line.} + +\item{draw.color}{Color of the possible trend lines.} + +\item{draw.weight}{Line weight of the possible trend line.} + +\item{ci.color}{Color of the ribbon showing the confidence interval.} + +\item{y.tick.format}{A string representing a d3 formatting code. +See https://github.com/d3/d3/blob/master/API.md#number-formats-d3-format} + +\item{x.grid.width}{Width of y-grid lines in pixels; 0 = no line} + +\item{y.hovertext.format}{A string representing a d3 formatting code +See https://github.com/d3/d3/blob/master/API.md#number-formats-d3-format} + +\item{title}{Character; chart title.} + +\item{x.title}{Character, x-axis title; defaults to chart input values; +to turn off set to "FALSE".} + +\item{y.title}{Character, y-axis title; defaults to chart input values; +to turn off set to "FALSE".} + +\item{global.font.family}{Character; font family for all occurrences of any +font attribute for the chart unless specified individually.} + +\item{global.font.color}{Global font color as a named color in character format +(e.g. "black") or an a hex code.} + +\item{title.font.size}{Integer; Title font size; default = 10.} + +\item{hovertext.font.size}{Font size of hover text.} + +\item{y.title.font.size}{Integer; y-axis title font size} + +\item{x.title.font.size}{Integer; x-axis title font size} + +\item{y.tick.font.size}{Integer; y-axis tick label font size} + +\item{x.tick.font.size}{Integer; x-axis tick label font size} + +\item{font.units}{One of "px" of "pt". By default all font sizes are specified in terms of +pixels ("px"). But changing this to "pt" will mean that the font sizes will be in terms +points ("pt"), which will be consistent with font sizes in text boxes.} + +\item{trim.padding}{(Deprecated)Logical; whether to remove padding around plotly chart. Default is set to false so that output is the same as old charts.} + +\item{...}{Other parameters to pass to flipStandardCharts::Line.} } \description{ Plots spline with confidence intervals