Translates formula into the typed AST, builds the per-layer panel UI,
and wires the server end-to-end. Returns a shiny.appobj ready to be run.
This page is the canonical reference for the formula grammar and the
empty-call cleanup rule used by every public entry point.
Usage
ptr_app(
formula,
envir = parent.frame(),
ui_text = NULL,
expr_check = TRUE,
safe_to_remove = character(),
css = NULL,
spec = NULL
)Arguments
- formula
Either a single character scalar containing a ggplot expression with
ggpaintrplaceholders, or an unquoted ggplot expression supplied directly. Expression-mode is captured withrlang::enexpr()at the public boundary, then deparsed to a string before reaching the shared translate pipeline; both modes produce equivalent apps. A bare symbol bound to a string in the calling frame (e.g.f <- "..."; ptr_app(f)) is resolved and treated as string mode. Pre-quoted wrappers (rlang::expr(),rlang::quo(),base::quote(),base::bquote()) at the captured root are unwrapped one level.!!splicing inside the captured expression is honoured viarlang::enexpr(). Native pipe (|>) caveat: in expression mode, R's parser desugars|>before capture, so the rendered code shows the desugared nested-call form. Stay in string mode (or use%>%) if you need|>preserved.- envir
Environment used to resolve local data objects.
- ui_text
Optional named list of copy overrides; see
ptr_ui_text()for the full schema and current defaults.- expr_check
Controls formula-level
ppExprvalidation. Three modes:TRUE(default) applies the built-in denylist + AST walker;FALSEdisables formula-level validation (for local prototyping with trusted formulas only); alistwithdeny_listand/orallow_listentries (character vectors) customises the formula-level policy without disabling it. Code typed into appExprbox at runtime is always screened against the built-in denylist, regardless of this setting. For the walker model see the safety chapter of the ggpaintr book (development-version docs): https://willju-wangqian.github.io/ggpaintr-book/safety.html.- safe_to_remove
Character vector of additional function names whose zero-argument calls should be dropped after placeholder substitution leaves them empty. Defaults to
character(). See Empty-call cleanup below. A user-typedppExpralways wins — whatever the user enters into anppExprbox is honoured verbatim, even if its top-level name is insafe_to_remove.- css
Optional character vector of paths to additional CSS files. Each is served as a static resource and linked after
ggpaintr's bundled stylesheet, so its rules override the default.ptr-*styling. Relativeurl(...)references inside a file resolve against that file's own directory. Defaults toNULL(no extra stylesheet).- spec
An optional named list of fully-qualified Shiny input id -> value, used to override widget defaults at session boot.
Formula grammar
A ggpaintr formula is a single ggplot() call written as a string. Drop
one of five placeholder keywords anywhere a value would normally go, and
the runtime substitutes the user's input back into the expression at
render time.
ppVarColumn picker, data-aware. Renders as a
selectInputpopulated with the upstream data's column-name vector. Example:aes(x = ppVar).ppTextFree-text input. Renders as a
textInput. Example:labs(title = text).ppNumNumeric input. Renders as a
numericInput. Example:geom_point(size = ppNum).ppExprCode editor, validated by
expr_check. The only keyword that accepts arbitrary R code; for the safety model see the ggpaintr book's safety chapter (development-version docs, https://willju-wangqian.github.io/ggpaintr-book/safety.html). Example:facet_wrap(ppExpr).ppUploadFile picker, returns a data frame. Renders as a
fileInputplus an optional dataset-name textbox. Accepted formats:.csv,.tsv,.rds,.xlsx,.xls,.json. Uploaded data is normalized viaptr_normalize_column_names()automatically. Example:ggplot(ppUpload, ...).
Any keyword occurrence may carry shared = "<id>" to lift the widget out
of its per-layer panel into a top-level shared section. Used by
ptr_app_grid() to drive multiple plots from one control. See
vignette("ggpaintr-tutorial") for worked examples of each keyword.
Empty-call cleanup
When a placeholder resolves to "missing" (an empty ppVar pick, a blank
ppText, a cleared ppNum, an unchecked layer checkbox), its argument is
dropped from the generated code. If the surrounding call is left empty
and its bare name is in the curated cleanup list, the whole call
disappears too. This rule applies to both placeholder-driven empties and
user-authored literal empty calls like + labs().
Curated ggplot2 names that are dropped when empty:
theme, labs, xlab, ylab, ggtitle,
facet_wrap, facet_grid, facet_null,
xlim, ylim, lims, expand_limits,
guides, annotate, annotation_custom,
annotation_map, annotation_raster,
aes, aes_, aes_q, aes_string,
element_text, element_line, element_rect,
element_point, element_polygon, element_geomEmpty calls to similar no-op helpers from dplyr, tidyr, tibble,
pillar, purrr, stringr, forcats, lubridate, and hms are
covered by the same rule.
geom_*() and stat_*() layers are never dropped, regardless of
whether they end up empty — they inherit their aesthetics from
ggplot() and remain meaningful with no arguments.
element_blank() is intentionally not in the cleanup list: its
empty form is a meaningful "suppress" directive, not a no-op.
Third-party helpers (e.g. pcp_theme() from ggpcp) are not in the
cleanup list — being absent is the "removal safety unknown" signal.
Use safe_to_remove = c("pcp_theme") to opt a specific name in.
See also
ptr_app_bslib() for the same contract with a bslib theme;
ptr_app_grid() for multi-plot apps with shared widgets;
ptr_define_placeholder_value() et al. for registering custom
keywords; ptr_ui_text() for copy overrides; ptr_css() for the
css = argument and themable CSS custom properties;
vignette("ggpaintr-tutorial") for tutorial examples.
Examples
if (interactive()) {
# Expression mode (primary): pass the unquoted ggplot expression.
ptr_app(ggplot(mtcars, aes(x = ppVar, y = ppVar)) + geom_point())
# `!!` splices a value into the expression.
col <- rlang::sym("mpg")
ptr_app(ggplot(mtcars, aes(x = !!col, y = ppVar)) + geom_point())
# String mode (fallback): the same formula as text.
ptr_app("ggplot(mtcars, aes(x = ppVar, y = ppVar)) + geom_point()")
}
