diff --git a/R/add_new_par.R b/R/add_new_par.R index 22e241b..c9dd635 100644 --- a/R/add_new_par.R +++ b/R/add_new_par.R @@ -7,7 +7,7 @@ add_new_par <- function(object, field){ defaults <- list(c()) if (field == 'global'){ - defaults <- config('par') + defaults <- config('par', custom.config = object[["global"]][["config"]][["config.file"]]) } if ('par' %in% names(object[[field]])) stop('par in ', field, ' already exists, cannot add it.', call. = FALSE) diff --git a/R/add_to_view.R b/R/add_to_view.R index 5e2891f..f88dee3 100644 --- a/R/add_to_view.R +++ b/R/add_to_view.R @@ -57,6 +57,7 @@ add_to_view <- function(object, call.args, side, where){ #' @param fun.name the name of the rendering function #' @param \dots arguments to \code{fun.name} or an embedded function #' within it. +#' @param custom.config logical to use custom or global config file #' @return list with arguments. List is named according to function #' names. #' @examples @@ -70,14 +71,14 @@ add_to_view <- function(object, call.args, side, where){ #' gsplot:::filter_arguments('points', x=1:5, y=1:5, xlim=c(0,10), ylim=c(0,10), #' callouts(labels=c(rep(NA, 4), "oh")))$extracted.args #' @keywords internal -filter_arguments <- function(fun.name, ...){ +filter_arguments <- function(fun.name, ..., custom.config = FALSE){ dots <- separate_args(...) standard.eval.args <- standard_eval_arguments(dots$args) if (is.null(fun.name)){ function.args <- NULL } else { - function.args <- function_call_args(fun.name, standard.eval.args) + function.args <- function_call_args(fun.name, standard.eval.args, custom.config = custom.config) } option.args <- standard.eval.args[!names(standard.eval.args) %in% c("", names(function.args[[1]]))] @@ -101,14 +102,16 @@ standard_eval_arguments <- function(.dots){ #' get the arguments that go into the function call, stripping out others and adding config defaults #' #' @param fun.name the name of the rendering function +#' @param custom.config logical whether or not to use custom.config or global config defaults #' @param .dots lazy_dots arguments #' @keywords internal -function_call_args <- function(fun.name, all.args){ +function_call_args <- function(fun.name, all.args, custom.config=FALSE){ fun.defaults <- function_defaults(fun.name) - args <- set_args(fun.name, all.args, package=fun.defaults$package) - call.args <- list(formal_arguments(args, fun.defaults$def.funs, keep.names = names(config(fun.name)))) + args <- set_args(fun.name, all.args, custom.config = custom.config, package=fun.defaults$package) + call.args <- list(formal_arguments(args, fun.defaults$def.funs, + keep.names = names(config(fun.name, custom.config = custom.config)))) names(call.args) <- fun.name return(call.args) } diff --git a/R/axis.R b/R/axis.R index e062f87..d34593a 100644 --- a/R/axis.R +++ b/R/axis.R @@ -67,7 +67,8 @@ axis.gsplot <- function(object, ..., n.minor=0, tcl.minor=0.15, reverse=NULL) { fun.name <- "axis" - user_args <- filter_arguments(fun.name = fun.name, ...)$call.args + user_args <- filter_arguments(fun.name = fun.name, ..., + custom.config = object[["global"]][["config"]][["config.file"]])$call.args sides <- user_args[[fun.name]]$side user_args[[fun.name]]$side <- NULL diff --git a/R/bgCol.R b/R/bgCol.R index 7f3a1f0..53677a9 100644 --- a/R/bgCol.R +++ b/R/bgCol.R @@ -36,7 +36,8 @@ bgCol <- function(object, ...) { bgCol.gsplot <- function(object, ...){ - to.gsplot <- filter_arguments(fun.name = "bgCol", ...)$call.args + to.gsplot <- filter_arguments(fun.name = "bgCol", ..., + custom.config = object[["global"]][["config"]][["config.file"]])$call.args object$global$bgCol <- append_replace(object$global$bgCol, to.gsplot[[1]]) return(object) diff --git a/R/config.R b/R/config.R index 4116549..cf93365 100644 --- a/R/config.R +++ b/R/config.R @@ -1,4 +1,7 @@ gsconfig <- new.env(parent = emptyenv()) +gsconfig$original.par <- par(no.readonly = TRUE) + +#Question...how can I update the user's par? #' @title Load gsplot config #' @@ -22,13 +25,36 @@ loadConfig = function(filename) { } graphTemplate <- yaml.load_file(filename) - if(.Device != "null device"){ - dev.off() + + if(length(all.equal(gsconfig$original.par, par(no.readonly = TRUE))) > 1){ + par(gsconfig$original.par) } - gsconfig$options <- graphTemplate } +#' @title Load gsplot temporary config +#' +#' @description Loads the config file into options which are +#'used elsewhere in the application. This will only change the config paremeters while +#'building up the gsplot object, not on print. +#' +#' @param filename string to custom file +#' +#' @importFrom graphics plot.xy +#' @importFrom graphics par +#' @importFrom yaml yaml.load_file +#' @importFrom grDevices dev.off +load_temp_config = function(filename) { + + gsconfig$original.par <- par(no.readonly = TRUE) + + graphTemplate <- yaml.load_file(filename) + + if(length(all.equal(gsconfig$original.par, par(no.readonly = TRUE))) > 1){ + par(gsconfig$original.par) + } + gsconfig$temp.config <- graphTemplate +} #' @title Get configuration for gsplot @@ -39,6 +65,7 @@ loadConfig = function(filename) { #' @param type string of gsplot config object to retrieve #' @param ... additional configuration to override what is pulled from config #' @param persist logical of whether to persist overrides to config +#' @param custom.config logical of whether to use default global (FALSE) or a config set for only one gsplot object #' #' @examples #' config("par") @@ -46,7 +73,7 @@ loadConfig = function(filename) { #' @importFrom graphics plot.xy #' @importFrom graphics par #' @export -config <- function(type, ..., persist=FALSE){ +config <- function(type, ..., persist=FALSE, custom.config = FALSE){ allowedTypes <- names(pkg.env$fun.details) type <- match.arg(type, choices = allowedTypes) @@ -55,7 +82,11 @@ config <- function(type, ..., persist=FALSE){ loadConfig() } - config_list <- gsconfig$options + if(custom.config){ + config_list <- gsconfig$temp.config + } else { + config_list <- gsconfig$options + } globalConfig <- config_list[!(names(config_list) %in% allowedTypes[allowedTypes != "par"])] diff --git a/R/gather_function_info.R b/R/gather_function_info.R index 82efc38..a030b08 100644 --- a/R/gather_function_info.R +++ b/R/gather_function_info.R @@ -20,7 +20,7 @@ #' @return a code{gsplot} object #' @keywords internal gather_function_info <- function(object, fun.name, ..., legend.name, side, where){ - arguments <- filter_arguments(fun.name, ..., side=side) + arguments <- filter_arguments(fun.name, ..., custom.config = object[["global"]][["config"]][["config.file"]], side=side) call.args <- arguments$call.args option.args <- arguments$option.args diff --git a/R/grid.R b/R/grid.R index 34088dc..af3b007 100644 --- a/R/grid.R +++ b/R/grid.R @@ -57,7 +57,7 @@ draw_custom_grid <- function(object, view.name){ view.name <- names(object[view.name]) - grid.args <- set_args("grid", object[[view.name]][['grid']], package = "graphics") + grid.args <- set_args("grid", object[[view.name]][['grid']],custom.config = object[["global"]][["config"]][["config.file"]], package = "graphics") if (is.null(grid.args$nx)){ x.side <- as.x_side_name(view.name) diff --git a/R/gsplot-class.R b/R/gsplot-class.R index db4b4ca..c704d47 100644 --- a/R/gsplot-class.R +++ b/R/gsplot-class.R @@ -4,6 +4,8 @@ #' #' @param x list #' @param \dots Further graphical parameters may also be supplied as arguments. See 'Details'. +#' @param config.file path to config yaml for individual gsplot object +#' @param theme path to theme #' @return gsplot #' @export #' @rdname gsplot @@ -13,12 +15,24 @@ gsplot <- function(x = NULL, ...) UseMethod("gsplot") #' @rdname gsplot #' @export -gsplot.default <- function(...) { - object <- gsplot(list(global=list('config'=list(frame.plot=TRUE)))) +gsplot.default <- function(...,config.file=NA, theme=NA) { + object <- gsplot(list(global=list('config'=list(frame.plot=TRUE, + config.file=!is.na(config.file))))) + + if (!is.na(config.file)){ + load_temp_config(config.file) + } + + # if(length(all.equal(gsconfig$original.par, par(no.readonly = TRUE))) > 1){ + # par(gsconfig$original.par) + # } + object <- add_new_par(object, 'global') - if (length(list(...)) > 0){ + + if(length(list(...)) > 0){ object <- par(object, ...) } + return(object) } diff --git a/R/legend.R b/R/legend.R index 822a8da..686d822 100644 --- a/R/legend.R +++ b/R/legend.R @@ -85,10 +85,10 @@ draw_legend <- function(gsplot) { for (legend.name in names(gsplot[['legend']])) { - par(xpd=TRUE) - legend <- gsplot[['legend']][[legend.name]] if (legend$draw) { + par(xpd=TRUE) + legend <- appendLegendColumnInfo(legend) legend <- appendLegendPositionConfiguration(legend) # set required legend argument to NA if not exists @@ -99,8 +99,11 @@ draw_legend <- function(gsplot) { #set bg so that fill/border/etc args are correct, then evaluate any quoted list items if (any(names(legend) %in% c("bg"))) { par(bg=legend$bg) + } else { + par(bg = ifelse(par('bg') == "transparent", "#FFFFFF", par('bg'))) } legend <- lapply(legend, function(x) {unname(sapply(x, function(x) {eval(x)}))}) + # clean out arguments not allowed by legend legend <- legend[na.omit(match(names(default.args), names(legend)))] legend(legend) diff --git a/R/par.R b/R/par.R index 5b6f6bd..cc3ecc4 100644 --- a/R/par.R +++ b/R/par.R @@ -23,6 +23,7 @@ #' gs2 par <- function(object, ...) { override("graphics", "par", object, ...) + gsconfig$original.par <- par(no.readonly = TRUE) } @@ -36,4 +37,5 @@ par.gsplot <- function(object, ...){ object <- modify_global_par(object, arguments) return(object) -} \ No newline at end of file +} + diff --git a/R/print.R b/R/print.R index 765f640..98cda97 100644 --- a/R/print.R +++ b/R/print.R @@ -75,7 +75,9 @@ print.gsplot <- function(x, ...){ } if(par('ann')){ - mtext(text=label(views, side), side=side, line = 2, las=config("mtext")$las) + mtext(text=label(views, side), + side=side, line = 2, + las=config("mtext", custom.config = x[["global"]][["config"]][["config.file"]])$las) } par(old.par) } diff --git a/R/set_args.R b/R/set_args.R index 9b13ba7..6cb8d6e 100644 --- a/R/set_args.R +++ b/R/set_args.R @@ -4,13 +4,14 @@ #' into a function-ready list. #' #' @param fun.name the name of the function to generate an arg list for +#' @param custom.config logical #' @param \dots user arguments to be used for the list #' @param package the package to use to get the function from (defaults to 'graphics') #' #' @keywords internal -set_args <- function(fun.name, ..., package='graphics'){ +set_args <- function(fun.name, ..., custom.config = FALSE, package='graphics'){ - config_args <- config(fun.name) + config_args <- config(fun.name, custom.config = custom.config) user_args <- function_args(name=fun.name, package=package, ...) indicesToAdd <- !(names(config_args) %in% names(user_args)) diff --git a/R/title.R b/R/title.R index 7a29076..b9be1e2 100644 --- a/R/title.R +++ b/R/title.R @@ -33,7 +33,7 @@ title <- function(object, ...) { title.gsplot <- function(object, ..., legend.name=NULL, side=c(1,2)){ - to.gsplot <- set_args("title", ..., package = "graphics") + to.gsplot <- set_args("title", ..., custom.config = object[["global"]][["config"]][["config.file"]], package = "graphics") object$global$title <- append_replace(object$global$title, to.gsplot) return(object) diff --git a/R/utils-side.R b/R/utils-side.R index 9c215b7..4ff7012 100644 --- a/R/utils-side.R +++ b/R/utils-side.R @@ -227,7 +227,9 @@ add_new_side <- function(object, side.name){ if (side.name %in% side_names(object)) stop(side.name, ' already exists, cannot add it.', call. = FALSE) side.template <- list(list( - axis = set_args('axis', side=as.side(side.name), package='graphics'), + axis = set_args('axis', side=as.side(side.name), + custom.config = object[["global"]][["config"]][["config.file"]], + package='graphics'), lim = c(NA, NA), log=FALSE, label="", axes = TRUE, reverse = FALSE, usr.lim=c(FALSE, FALSE), usr.axes=FALSE)) names(side.template) <- side.name diff --git a/README.Rmd b/README.Rmd index 919792e..5c3405c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -9,6 +9,7 @@ output: ```{r global_options, include=FALSE} knitr::opts_chunk$set(fig.width=6, fig.height=6, + echo=TRUE, warning=FALSE, message=FALSE) ``` diff --git a/README.md b/README.md index 7243f17..3f3f94e 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,8 @@ myplot <- myplot %>% points(4,3,col="blue") myplot ``` + + #### Automatic legend diff --git a/README_files/figure-markdown_github/unnamed-chunk-3-1.png b/README_files/figure-markdown_github/unnamed-chunk-3-1.png index 78b1389..b24203b 100644 Binary files a/README_files/figure-markdown_github/unnamed-chunk-3-1.png and b/README_files/figure-markdown_github/unnamed-chunk-3-1.png differ diff --git a/inst/doc/gsplotIntro.html b/inst/doc/gsplotIntro.html index b267144..43a7861 100644 --- a/inst/doc/gsplotIntro.html +++ b/inst/doc/gsplotIntro.html @@ -69,7 +69,7 @@
Demo workflow
+gsplot
uses similar plotting graphics to R base graphics, but allows users to execute them in a more intuitive manner. Additionally, as the complexity of the plot features increase, gpslot
code is simplistic compared to that of base graphics. gsplot
also includes features not present in base graphics that are useful when working with USGS data, such as callouts
(combines segments
and text
into a single call), error_bar
(allows an error to be given as y.high
, y.low
, x.high
, and x.low
and automatically builds an error bar), and the argument legend.name
(an argument within points
, lines
, etc. which does not require colors, linetypes, and other par information to be redefined within the legend
call).
Fig. 1 Simple flow timeseries using gsplot
.
Fig. 2 Simple flow timeseries with a logged y-axis using gsplot
.
Fig. 3 (a) pH vs water temperature, (b) pH timeseries, (c) water temperature timeseries.
Fig. 4 Water temperature timeseries on primary y-axis with pH timeseries on secondary y-axis.
Fig. 5 Initial plot of water temperature timeseries.
# notice the missing data from ~ 1991 through ~2011 and add a callout
diff --git a/inst/extdata/lineScatter.yaml b/inst/extdata/lineScatter.yaml
index 64c8acd..1d2e4ee 100644
--- a/inst/extdata/lineScatter.yaml
+++ b/inst/extdata/lineScatter.yaml
@@ -16,7 +16,6 @@ lines:
col: "black"
lty: 1
lwd: 1
- labels: FALSE
abline:
col: "grey"
lty: 1
diff --git a/man/config.Rd b/man/config.Rd
index f5ea0b0..0062de9 100644
--- a/man/config.Rd
+++ b/man/config.Rd
@@ -4,7 +4,7 @@
\alias{config}
\title{Get configuration for gsplot}
\usage{
-config(type, ..., persist = FALSE)
+config(type, ..., persist = FALSE, custom.config = FALSE)
}
\arguments{
\item{type}{string of gsplot config object to retrieve}
@@ -12,6 +12,8 @@ config(type, ..., persist = FALSE)
\item{...}{additional configuration to override what is pulled from config}
\item{persist}{logical of whether to persist overrides to config}
+
+\item{custom.config}{logical of whether to use default global (FALSE) or a config set for only one gsplot object}
}
\description{
Gets config for gsplot, mostly used internally
diff --git a/man/filter_arguments.Rd b/man/filter_arguments.Rd
index c66a48a..6619f35 100644
--- a/man/filter_arguments.Rd
+++ b/man/filter_arguments.Rd
@@ -4,11 +4,13 @@
\alias{filter_arguments}
\title{extract the call arguments}
\usage{
-filter_arguments(fun.name, ...)
+filter_arguments(fun.name, ..., custom.config = FALSE)
}
\arguments{
\item{fun.name}{the name of the rendering function}
+\item{custom.config}{logical to use custom or global config file}
+
\item{\dots}{arguments to \code{fun.name} or an embedded function
within it.}
}
diff --git a/man/function_call_args.Rd b/man/function_call_args.Rd
index 713751d..64db6cf 100644
--- a/man/function_call_args.Rd
+++ b/man/function_call_args.Rd
@@ -4,11 +4,13 @@
\alias{function_call_args}
\title{get the arguments that go into the function call, stripping out others and adding config defaults}
\usage{
-function_call_args(fun.name, all.args)
+function_call_args(fun.name, all.args, custom.config = FALSE)
}
\arguments{
\item{fun.name}{the name of the rendering function}
+\item{custom.config}{logical whether or not to use custom.config or global config defaults}
+
\item{.dots}{lazy_dots arguments}
}
\description{
diff --git a/man/gsplot.Rd b/man/gsplot.Rd
index beb4c27..da81a43 100644
--- a/man/gsplot.Rd
+++ b/man/gsplot.Rd
@@ -8,13 +8,17 @@
\usage{
gsplot(x = NULL, ...)
-\method{gsplot}{default}(...)
+\method{gsplot}{default}(..., config.file = NA, theme = NA)
\method{gsplot}{list}(x)
}
\arguments{
\item{x}{list}
+\item{config.file}{path to config yaml for individual gsplot object}
+
+\item{theme}{path to theme}
+
\item{\dots}{Further graphical parameters may also be supplied as arguments. See 'Details'.}
}
\value{
diff --git a/man/load_temp_config.Rd b/man/load_temp_config.Rd
new file mode 100644
index 0000000..a6f98b2
--- /dev/null
+++ b/man/load_temp_config.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/config.R
+\name{load_temp_config}
+\alias{load_temp_config}
+\title{Load gsplot temporary config}
+\usage{
+load_temp_config(filename)
+}
+\arguments{
+\item{filename}{string to custom file}
+}
+\description{
+Loads the config file into options which are
+used elsewhere in the application. This will only change the config paremeters while
+building up the gsplot object, not on print.
+}
+
diff --git a/man/set_args.Rd b/man/set_args.Rd
index dc7ecff..3a7b21b 100644
--- a/man/set_args.Rd
+++ b/man/set_args.Rd
@@ -4,11 +4,13 @@
\alias{set_args}
\title{set argument list for a given function}
\usage{
-set_args(fun.name, ..., package = "graphics")
+set_args(fun.name, ..., custom.config = FALSE, package = "graphics")
}
\arguments{
\item{fun.name}{the name of the function to generate an arg list for}
+\item{custom.config}{logical}
+
\item{package}{the package to use to get the function from (defaults to 'graphics')}
\item{\dots}{user arguments to be used for the list}
diff --git a/tests/testthat/test-add_new_side.R b/tests/testthat/test-add_new_side.R
index d46f285..aa62cca 100644
--- a/tests/testthat/test-add_new_side.R
+++ b/tests/testthat/test-add_new_side.R
@@ -1,7 +1,7 @@
context("test add new side")
test_that("add new side", {
- obj <- list()
+ obj <- gsplot()
obj <- gsplot:::add_new_side(obj, 'side.1')
expect_true('side.1' %in% gsplot:::side_names(obj))
@@ -10,7 +10,7 @@ test_that("add new side", {
test_that("par defaults on new side", {
- obj <- list()
+ obj <- gsplot()
obj <- gsplot:::add_new_side(obj, 'side.1')
obj <- gsplot:::modify_side_par(obj, arguments =list(las='2'), side=1)
expect_true('par' %in% names(obj[['side.1']]))
@@ -18,7 +18,7 @@ test_that("par defaults on new side", {
test_that("axis defaults on new side", {
- obj <- list()
+ obj <- gsplot()
obj <- gsplot:::add_new_side(obj, 'side.1')
expect_true(all(c("lim", "log", "label", "usr.lim") %in% names(obj[['side.1']])))
expect_false(any(obj[['side.1']][['usr.lim']]))
diff --git a/tests/testthat/tests-config.R b/tests/testthat/tests-config.R
index 4dcac63..dde1db0 100644
--- a/tests/testthat/tests-config.R
+++ b/tests/testthat/tests-config.R
@@ -30,3 +30,27 @@ test_that("formals are correctly retrieved", {
test_that("non-existant type hits error", {
expect_error(config("foo"))
})
+
+test_that("config temp", {
+ df <- data.frame(x = 1:10, y=1:10, z = seq(2,20,2))
+
+ gsp <- gsplot(config.file = system.file("extdata", "lineScatter.yaml", package = "gsplot")) %>%
+ lines(df$x, df$y, col="red", legend.name = "points")
+ expect_true(gsp$global$config$config.file)
+
+ gspDef <- gsplot() %>%
+ lines(df$x, df$y, col="red", legend.name = "points")
+ expect_false(gspDef$global$config$config.file)
+
+ loadConfig(system.file("extdata", "lineScatter.yaml", package = "gsplot"))
+ gsp <- gsplot() %>%
+ lines(df$x, df$y, col="red", legend.name = "points")
+ expect_false(gsp$global$config$config.file)
+ expect_equal(gsp$side.1$axis$lwd, 0.8)
+
+ loadConfig()
+ gspDef2 <- gsplot() %>%
+ lines(df$x, df$y, col="red", legend.name = "points")
+ expect_false(gspDef2$global$config$config.file)
+ expect_null(gspDef2$side.1$axis$lwd)
+})