diff --git a/R/draw_legend.R b/R/draw_legend.R
index 1f5aba88..f46baf86 100644
--- a/R/draw_legend.R
+++ b/R/draw_legend.R
@@ -129,119 +129,47 @@ draw_legend = function(
     
     #
     ## legend args ----
-    
-    legend_args = sanitize_legend(legend, legend_args)
-    
-    ## Use `!exists` rather than `is.null` for title in case user specified no title
-    if (!exists("title", where = legend_args)) legend_args[["title"]] = by_dep
-  
-    legend_args[["pch"]] = legend_args[["pch"]] %||% pch
-    legend_args[["lty"]] = legend_args[["lty"]] %||% lty
-    legend_args[["col"]] = legend_args[["col"]] %||% col
-    legend_args[["bty"]] = legend_args[["bty"]] %||% "n"
-    legend_args[["horiz"]] = legend_args[["horiz"]] %||% FALSE
-    legend_args[["xpd"]] = legend_args[["xpd"]] %||% NA
-  
-    if (!isTRUE(type %in% c("p", "ribbon", "polygon", "polypath"))) {
-      legend_args[["lwd"]] = legend_args[["lwd"]] %||% lwd
-    }
-  
-    if (is.null(type) || type %in% c("p", "pointrange", "errorbar", "text")) {
-      legend_args[["pt.cex"]] = legend_args[["pt.cex"]] %||% (cex %||% par("cex"))
-    }
-  
-    # turn off inner line for "barplot" type
-    if (identical(type, "barplot")) {
-      legend_args[["lty"]] = 0
-    }
-    
-    if (isTRUE(type %in% c("rect", "ribbon", "polygon", "polypath", "boxplot", "hist", "histogram", "spineplot", "ridge", "barplot", "violin")) || gradient) {
-      legend_args[["pch"]] = 22
-      legend_args[["pt.cex"]] = legend_args[["pt.cex"]] %||% 3.5
-      legend_args[["y.intersp"]] = legend_args[["y.intersp"]] %||% 1.25
-      legend_args[["seg.len"]] = legend_args[["seg.len"]] %||% 1.25
-    }
-  
-    if (isTRUE(type %in% c("ribbon", "hist", "histogram", "spineplot"))) {
-      legend_args[["pt.lwd"]] = legend_args[["pt.lwd"]] %||% 0
-    }
-  
-    if (identical(type, "p")) {
-      legend_args[["pt.lwd"]] = legend_args[["pt.lwd"]] %||% lwd
-    }
-  
-    if (identical(type, "n") && isFALSE(gradient)) {
-      legend_args[["pch"]] = legend_args[["pch"]] %||% par("pch")
-    }
-  
-    if (identical(type, "spineplot")) {
-      legend_args[["pt.bg"]] = legend_args[["pt.bg"]] %||% legend_args[["col"]]
-    }
-  
-    if (identical(type, "ridge") && isFALSE(gradient)) {
-      legend_args[["pt.bg"]] = legend_args[["pt.bg"]] %||% sapply(legend_args[["col"]], function(ccol) seq_palette(ccol, n = 2)[2])
-    }
-  
-    legend_args[["pt.bg"]] = legend_args[["pt.bg"]] %||% bg
-  
-    legend_args[["legend"]] = legend_args[["legend"]] %||% lgnd_labs
-    if (length(lgnd_labs) != length(eval(legend_args[["legend"]]))) {
-      warning(
-        "\nUser-supplied legend labels do not match the number of groups.\n",
-        "Defaulting to automatic labels determined by the group splits in `by`,\n"
-      )
-      legend_args[["legend"]] = lgnd_labs
-    }
-  
-    if (isTRUE(gradient)) {
-      legend_args[["ncol"]] = NULL
-    }
-    # flag for multicolumn legend
-    mcol_flag = !is.null(legend_args[["ncol"]]) && legend_args[["ncol"]] > 1
-    
-    # flag for (extra) user inset (also used for dual legends)
-    user_inset = !is.null(legend_args[["inset"]])
+
+    outer_side = outer_end = outer_right = outer_bottom = FALSE
+    list2env(
+      compute_legend_args(
+        legend = legend,
+        legend_args = legend_args,
+        by_dep = by_dep,
+        lgnd_labs = lgnd_labs,
+        type = type,
+        pch = pch,
+        lty = lty,
+        lwd = lwd,
+        col = col,
+        bg = bg,
+        cex = cex,
+        gradient = gradient
+      ),
+      environment()
+    )
   
     #
     ## legend placement ----
-    
-    # Note: "side" = left/right ; "end" = top/bottom
-    outer_side = outer_end = outer_right = outer_bottom = FALSE ## placeholders
-    
-    ooma = par("oma")
-    omar = par("mar")
-    topmar_epsilon = 0.1
-    
-    # Catch to avoid recursive offsets, e.g. repeated tinyplot calls with
-    # "bottom!" legend position.
-    
-    ## restore inner margin defaults
-    ## (in case the plot region/margins were affected by the preceding tinyplot call)
     dynmar = isTRUE(.tpar[["dynmar"]])
-    if (any(ooma != 0) && !dynmar) {
-      if ( ooma[1] != 0 & omar[1] == par("mgp")[1] + 1*par("cex.lab") ) omar[1] = 5.1
-      if ( ooma[2] != 0 & omar[2] == par("mgp")[1] + 1*par("cex.lab") ) omar[2] = 4.1
-      if ( ooma[3] == topmar_epsilon & omar[3] != 4.1 ) omar[3] = 4.1
-      if ( ooma[4] != 0 & omar[4] == 0 ) omar[4] = 2.1
-      par(mar = omar)
-    }
-    ## restore outer margin defaults
-    par(omd = c(0,1,0,1))
+
+    # flag for (extra) user inset (also used for dual legends)
+    user_inset = !is.null(legend_args[["inset"]])
+
+    ## restore margin defaults
+    ## (in case the plot region/margins were affected by the preceding tinyplot call)
+    topmar_epsilon = 0.1
+    restore_margin_outer()
+    if (!dynmar) restore_margin_inner(ooma, topmar_epsilon = topmar_epsilon)
+
     ooma = par("oma")
+    omar = par("mar")
     
     ## Legend to outer side (either right or left) of plot
-    if (grepl("right!$|left!$", legend_args[["x"]])) {
-      
-      outer_side = TRUE
-      outer_right = grepl("right!$", legend_args[["x"]])
-      
+    if (outer_side) {
       # extra bump for spineplot if outer_right legend (to accommodate secondary y-axis)
       if (identical(type, "spineplot")) lmar[1] = lmar[1] + 1.1
       
-      ## Switch position anchor (we'll adjust relative to the _opposite_ side below)
-      if (outer_right) legend_args[["x"]] = gsub("right!$", "left", legend_args[["x"]])
-      if (!outer_right) legend_args[["x"]] = gsub("left!$", "right", legend_args[["x"]])
-      
       ## We have to set the inner margins of the plot before the (fake) legend is
       ## drawn, otherwise the inset calculation---which is based in the legend
       ## width---will be off the first time.
@@ -271,24 +199,17 @@ draw_legend = function(
         }
       }
       
-      legend_args[["horiz"]] = FALSE
-      
       ## Legend at the outer top or bottom of plot
-    } else if (grepl("bottom!$|top!$", legend_args[["x"]])) {
-
-      outer_end = TRUE
-      outer_bottom = grepl("bottom!$", legend_args[["x"]])
-
-      ## Switch position anchor (we'll adjust relative to the _opposite_ side below)
-      if (outer_bottom) legend_args[["x"]] = gsub("bottom!$", "top", legend_args[["x"]])
-      if (!outer_bottom) legend_args[["x"]] = gsub("top!$", "bottom", legend_args[["x"]])
+    } else if (outer_end) {
 
       ## We have to set the inner margins of the plot before the (fake) legend is
       ## drawn, otherwise the inset calculation---which is based in the legend
       ## width---will be off the first time.
       if (outer_bottom) {
         omar[1] = par("mgp")[1] + 1*par("cex.lab")
-        if (has_sub && (is.null(.tpar[["side.sub"]]) || .tpar[["side.sub"]]==1)) omar[1] = omar[1] + 1*par("cex.sub")
+        if (has_sub && (is.null(.tpar[["side.sub"]]) || .tpar[["side.sub"]]==1)) {
+          omar[1] = omar[1] + 1*par("cex.sub")
+        }
       } else {
         ## For "top!", the logic is slightly different: We don't expand the outer
         ## margin b/c we need the legend to come underneath the main title. So
@@ -318,42 +239,11 @@ draw_legend = function(
         }
       }
 
-      # enforce horizontal legend if user hasn't specified ncol arg
-      # (exception: gradient legends at bottom/top are always horizontal)
-      if (is.null(legend_args[["ncol"]]) || gradient) legend_args[["horiz"]] = TRUE
 
     } else {
-      
-      legend_args[["inset"]] = 0
-      # if (new_plot && draw) plot.new()
       if (new_plot) plot.new()
       
     }
-  
-    # Additional tweaks for horiz and/or multi-column legends
-    if (isTRUE(legend_args[["horiz"]]) ||  mcol_flag) {
-      # tighter horizontal labelling
-      # See: https://github.com/grantmcdermott/tinyplot/issues/434
-      if (!gradient) {
-        legend_args[["text.width"]] = NA
-        # Add a space to all labs except the outer most right ones
-        nlabs = length(legend_args[["legend"]])
-        nidx = nlabs
-        if (mcol_flag) nidx = tail(1:nlabs, (nlabs %/% legend_args[["ncol"]]))
-        legend_args[["legend"]][-nidx] = paste(legend_args[["legend"]][-nidx], " ")
-      }
-      # catch for horizontal ribbon legend spacing
-      if (type=="ribbon") {
-        if (legend_args[["pt.lwd"]] == 1) {
-          legend_args[["x.intersp"]] = 1
-        } else {
-          legend_args[["x.intersp"]] = 0.5
-        }
-      } else if (gradient) {
-        legend_args[["x.intersp"]] = 0.5
-      }
-    }
-    
     #
     ## draw the legend ----
     # Legend drawing is handled by the internal `tinylegend()` function, which:
@@ -736,4 +626,4 @@ sanitize_legend = function(legend, legend_args) {
     }
   }
   return(legend_args)
-}
\ No newline at end of file
+}
diff --git a/R/draw_legend_utils.R b/R/draw_legend_utils.R
new file mode 100644
index 00000000..1e4a76ce
--- /dev/null
+++ b/R/draw_legend_utils.R
@@ -0,0 +1,174 @@
+restore_margin_outer = function() {
+  par(omd = c(0,1,0,1))
+}
+
+
+restore_margin_inner = function(ooma, topmar_epsilon = 0.1) {
+  ooma = par("oma")
+  omar = par("mar")
+
+  if (!any(ooma != 0)) return(invisible(NULL))
+
+  ## restore inner margin defaults
+  ## (in case the plot region/margins were affected by the preceding tinyplot call)
+  if (any(ooma != 0)) {
+    if (ooma[1] != 0 && omar[1] == par("mgp")[1] + 1 * par("cex.lab")) {
+      omar[1] = 5.1
+    }
+    if (ooma[2] != 0 && omar[2] == par("mgp")[1] + 1 * par("cex.lab")) {
+      omar[2] = 4.1
+    }
+    if (ooma[3] == topmar_epsilon && omar[3] != 4.1) {
+      omar[3] = 4.1
+    }
+    if (ooma[4] != 0 && omar[4] == 0) {
+      omar[4] = 2.1
+    }
+    par(mar = omar)
+  }
+  ## restore outer margin defaults (with a catch for custom mfrow plots)
+  if (all(par("mfrow") == c(1, 1))) {
+    par(omd = c(0, 1, 0, 1))
+  }
+}
+
+
+compute_legend_args = function(
+  legend,
+  legend_args,
+  by_dep,
+  lgnd_labs,
+  type,
+  pch,
+  lty,
+  lwd,
+  col,
+  bg,
+  cex,
+  gradient
+) {
+  legend_args = sanitize_legend(legend, legend_args)
+  ## Use `!exists` rather than `is.null` for title in case user specified no title
+  if (!exists("title", where = legend_args)) legend_args[["title"]] = by_dep
+  legend_args[["pch"]] = legend_args[["pch"]] %||% pch
+  legend_args[["lty"]] = legend_args[["lty"]] %||% lty
+  legend_args[["col"]] = legend_args[["col"]] %||% col
+  legend_args[["bty"]] = legend_args[["bty"]] %||% "n"
+  legend_args[["horiz"]] = legend_args[["horiz"]] %||% FALSE
+  legend_args[["xpd"]] = legend_args[["xpd"]] %||% NA
+  if (!isTRUE(type %in% c("p", "ribbon", "polygon", "polypath"))) {
+    legend_args[["lwd"]] = legend_args[["lwd"]] %||% lwd
+  }
+  if (is.null(type) || type %in% c("p", "pointrange", "errorbar", "text")) {
+    legend_args[["pt.cex"]] = legend_args[["pt.cex"]] %||% (cex %||% par("cex"))
+  }
+  # turn off inner line for "barplot" type
+  if (identical(type, "barplot")) {
+    legend_args[["lty"]] = 0
+  }
+  if (isTRUE(type %in% c("rect", "ribbon", "polygon", "polypath", "boxplot", "hist", "histogram", "spineplot", "ridge", "barplot", "violin")) || gradient) {
+    legend_args[["pch"]] = 22
+    legend_args[["pt.cex"]] = legend_args[["pt.cex"]] %||% 3.5
+    legend_args[["y.intersp"]] = legend_args[["y.intersp"]] %||% 1.25
+    legend_args[["seg.len"]] = legend_args[["seg.len"]] %||% 1.25
+  }
+  if (isTRUE(type %in% c("ribbon", "hist", "histogram", "spineplot"))) {
+    legend_args[["pt.lwd"]] = legend_args[["pt.lwd"]] %||% 0
+  }
+  if (identical(type, "p")) {
+    legend_args[["pt.lwd"]] = legend_args[["pt.lwd"]] %||% lwd
+  }
+  if (identical(type, "n") && isFALSE(gradient)) {
+    legend_args[["pch"]] = legend_args[["pch"]] %||% par("pch")
+  }
+  if (identical(type, "spineplot")) {
+    legend_args[["pt.bg"]] = legend_args[["pt.bg"]] %||% legend_args[["col"]]
+  }
+  if (identical(type, "ridge") && isFALSE(gradient)) {
+    legend_args[["pt.bg"]] = legend_args[["pt.bg"]] %||% sapply(legend_args[["col"]], function(ccol) seq_palette(ccol, n = 2)[2])
+  }
+  legend_args[["pt.bg"]] = legend_args[["pt.bg"]] %||% bg
+  legend_args[["legend"]] = legend_args[["legend"]] %||% lgnd_labs
+  if (length(lgnd_labs) != length(eval(legend_args[["legend"]]))) {
+    warning(
+      "\nUser-supplied legend labels do not match the number of groups.\n",
+      "Defaulting to automatic labels determined by the group splits in `by`,\n"
+    )
+    legend_args[["legend"]] = lgnd_labs
+  }
+  if (isTRUE(gradient)) {
+    legend_args[["ncol"]] = NULL
+  }
+  # flag for multicolumn legend
+  mcol_flag = !is.null(legend_args[["ncol"]]) && legend_args[["ncol"]] > 1
+  # flag for (extra) user inset (also used for dual legends)
+  user_inset = !is.null(legend_args[["inset"]])
+
+  # placement flags and anchor normalization (no par() calls here)
+  outer_side = outer_end = outer_right = outer_bottom = FALSE
+  if (grepl("right!$|left!$", legend_args[["x"]])) {
+    outer_side = TRUE
+    outer_right = grepl("right!$", legend_args[["x"]])
+  } else if (grepl("bottom!$|top!$", legend_args[["x"]])) {
+    outer_end = TRUE
+    outer_bottom = grepl("bottom!$", legend_args[["x"]])
+  }
+
+  ## Switch position anchor (we'll adjust relative to the _opposite_ side below)
+  if (outer_end) {
+    if (outer_bottom) {
+      legend_args[["x"]] = gsub("bottom!$", "top", legend_args[["x"]])
+    }
+    if (!outer_bottom) {
+      legend_args[["x"]] = gsub("top!$", "bottom", legend_args[["x"]])
+    }
+
+    # enforce horizontal legend if user hasn't specified ncol arg
+    # (exception: gradient legends at bottom/top are always horizontal)
+    if (is.null(legend_args[["ncol"]]) || gradient) legend_args[["horiz"]] = TRUE
+
+  } else if (outer_side) {
+    if (outer_right) {
+      legend_args[["x"]] = gsub("right!$", "left", legend_args[["x"]])
+    }
+    if (!outer_right) {
+      legend_args[["x"]] = gsub("left!$", "right", legend_args[["x"]])
+    }
+  } else {
+      legend_args[["inset"]] = 0
+  }
+
+  # Additional tweaks for horiz and/or multi-column legends
+  if (isTRUE(legend_args[["horiz"]]) ||  mcol_flag) {
+    # tighter horizontal labelling
+    # See: https://github.com/grantmcdermott/tinyplot/issues/434
+    if (!gradient) {
+      legend_args[["text.width"]] = NA
+      # Add a space to all labs except the outer most right ones
+      nlabs = length(legend_args[["legend"]])
+      nidx = nlabs
+      if (mcol_flag) nidx = tail(1:nlabs, (nlabs %/% legend_args[["ncol"]]))
+      legend_args[["legend"]][-nidx] = paste(legend_args[["legend"]][-nidx], " ")
+    }
+    # catch for horizontal ribbon legend spacing
+    if (type=="ribbon") {
+      if (legend_args[["pt.lwd"]] == 1) {
+        legend_args[["x.intersp"]] = 1
+      } else {
+        legend_args[["x.intersp"]] = 0.5
+      }
+    } else if (gradient) {
+      legend_args[["x.intersp"]] = 0.5
+    }
+  }
+  
+  list(
+    legend_args = legend_args,
+    mcol_flag = mcol_flag,
+    user_inset = user_inset,
+    outer_side = outer_side,
+    outer_end = outer_end,
+    outer_right = outer_right,
+    outer_bottom = outer_bottom
+  )
+}
diff --git a/R/tinyplot.R b/R/tinyplot.R
index bba3ff0d..973a39dc 100644
--- a/R/tinyplot.R
+++ b/R/tinyplot.R
@@ -848,59 +848,30 @@ tinyplot.default = function(
 
 
   # swap x and y values if flip is TRUE
-  assert_flag(flip)
   # extra catch for boxplots
-  # now swap the values
+  assert_flag(flip)
   if (isTRUE(flip)) {
-    if (type != "boxplot") {
-      # limits, labs, etc.
-      xlim_cp = xlim
-      xlim = ylim
-      ylim = xlim_cp
-      xlab_cp = xlab
-      xlab = ylab
-      ylab = xlab_cp
-      xlabs_cp = xlabs
-      xlabs = ylabs
-      ylabs = xlabs_cp
-      xaxt_cp = xaxt
-      xaxt = yaxt
-      yaxt = xaxt_cp
-      xaxs_cp = xaxs
-      xaxs = yaxs
-      yaxs = xaxs_cp
-      xaxb_cp = xaxb
-      xaxb = yaxb
-      yaxb = xaxb_cp
-      xaxl_cp = xaxl
-      xaxl = yaxl
-      yaxl = xaxl_cp
-      if (!is.null(log)) {
-        log = if (log == "x") "y" else if (log == "y") "x" else log
-      }
-      # x/y vars
-      x_cp = datapoints[["x"]]
-      datapoints[["x"]] = datapoints[["y"]]
-      datapoints[["y"]] = x_cp
-      # x/y min and max vars
-      xmin_cp = if (!is.null(datapoints[["xmin"]])) datapoints[["xmin"]] else NULL
-      datapoints[["xmin"]] = if (!is.null(datapoints[["ymin"]])) datapoints[["ymin"]] else NULL
-      datapoints[["ymin"]] = if (!is.null(xmin_cp)) xmin_cp else NULL
-      xmax_cp = if (!is.null(datapoints[["xmax"]])) datapoints[["xmax"]] else NULL
-      datapoints[["xmax"]] = if (!is.null(datapoints[["ymax"]])) datapoints[["ymax"]] else NULL
-      datapoints[["ymax"]] = if (!is.null(xmax_cp)) xmax_cp else NULL
-      # clean up
-      rm(xlim_cp, xlab_cp, xlabs_cp, xaxt_cp, xaxs_cp, xaxb_cp, xaxl_cp, x_cp, xmin_cp, xmax_cp)
+    if (type == "boxplot") {
+      # boxplot: let horizontal=TRUE do most work; only swap labels
+      swap_variables(environment(), c("xlab", "ylab"))
     } else {
-      # We'll let boxplot(..., horizontal = TRUE) handle most of the adjustments
-      # and just catch a few elements that we draw beforehand.
-      xlab_cp = xlab
-      xlab = ylab
-      ylab = xlab_cp
-      rm(xlab_cp)
+      swap_variables(
+        environment(),
+        c("xlim", "ylim"),
+        c("xlab", "ylab"),
+        c("xlabs", "ylabs"),
+        c("xaxt", "yaxt"),
+        c("xaxs", "yaxs"),
+        c("xaxb", "yaxb"),
+        c("xaxl", "yaxl"))
+      if (!is.null(log)) log = chartr("xy", "yx", log)
+      datapoints = swap_columns(datapoints, "x", "y")
+      datapoints = swap_columns(datapoints, "xmin", "ymin")
+      datapoints = swap_columns(datapoints, "xmax", "ymax")
     }
   }
   
+
   # For cases where x/yaxb is provided and corresponding x/ylabs is not null...
   # We can subset these here to provide breaks
   if (!is.null(xaxb) && !is.null(xlabs)) {
@@ -1132,21 +1103,7 @@ tinyplot.default = function(
 
     # Catch to avoid recursive offsets, e.g. repeated tinyplot calls with
     # "bottom!" legend position.
-
-    ## restore inner margin defaults
-    ## (in case the plot region/margins were affected by the preceding tinyplot call)
-    if (any(ooma != 0)) {
-      if (ooma[1] != 0 && omar[1] == par("mgp")[1] + 1 * par("cex.lab")) omar[1] = 5.1
-      if (ooma[2] != 0 && omar[2] == par("mgp")[1] + 1 * par("cex.lab")) omar[2] = 4.1
-      if (ooma[3] == topmar_epsilon && omar[3] != 4.1) omar[3] = 4.1
-      if (ooma[4] != 0 && omar[4] == 0) omar[4] = 2.1
-      par(mar = omar)
-    }
-    ## restore outer margin defaults (with a catch for custom mfrow plots)
-    if (all(par("mfrow") == c(1, 1))) {
-      par(omd = c(0, 1, 0, 1))
-    }
-
+    restore_margin_inner(ooma)
     # clean up for now
     rm(omar, ooma, topmar_epsilon)
 
diff --git a/R/utils.R b/R/utils.R
index 90368f19..9443a7c2 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -1,7 +1,7 @@
-rescale_num = function (x, from = NULL, to = NULL) {
+rescale_num = function(x, from = NULL, to = NULL) {
   if (is.null(from)) from = range(x)
   if (is.null(to)) to = c(0, 1)
-  (x - from[1])/diff(from) * diff(to) + to[1]
+  (x - from[1]) / diff(from) * diff(to) + to[1]
 }
 
 ## Function for efficiently checking whether a vector has more than n unique
@@ -31,21 +31,38 @@ more_than_n_unique = function(x, n, small_vec_len = 1e3L) {
 
 ## Null coalescing operator
 if (getRversion() <= "4.4.0") {
-   `%||%` = function(x, y) if (is.null(x)) y else x
+  `%||%` = function(x, y) if (is.null(x)) y else x
 }
 
 
 ## Function that computes an appropriate bandwidth kernel based on a string
 ## input
 bw_fun = function(kernel, x) {
-    kernel = tolower(kernel)
-    switch(
-        kernel,
-        nrd0 = bw.nrd0(x),
-        nrd  = bw.nrd(x),
-        ucv  = bw.ucv(x),
-        bcv  = bw.bcv(x),
-        sj   = bw.SJ(x),
-        stop("Invalid `bw` string. Choose from 'nrd0', 'nrd', 'ucv', 'bcv', or 'SJ'.")
-    )
+  kernel = tolower(kernel)
+  switch(kernel,
+    nrd0 = bw.nrd0(x),
+    nrd  = bw.nrd(x),
+    ucv  = bw.ucv(x),
+    bcv  = bw.bcv(x),
+    sj   = bw.SJ(x),
+    stop("Invalid `bw` string. Choose from 'nrd0', 'nrd', 'ucv', 'bcv', or 'SJ'.")
+  )
+}
+
+
+swap_variables = function(env, ...) {
+  pairs = list(...)
+  for (p in pairs) {
+    tmp = get(p[1], envir = env)
+    assign(p[1], get(p[2], envir = env), envir = env)
+    assign(p[2], tmp, envir = env)
+  }
+}
+
+swap_columns = function(dp, a, b) {
+  va = dp[[a]]
+  vb = dp[[b]]
+  dp[[a]] = if (!is.null(vb)) vb else NULL
+  dp[[b]] = if (!is.null(va)) va else NULL
+  dp
 }
diff --git a/inst/tinytest/test-tinyplot_add.R b/inst/tinytest/test-tinyplot_add.R
index 39d5918b..ed9fecef 100644
--- a/inst/tinytest/test-tinyplot_add.R
+++ b/inst/tinytest/test-tinyplot_add.R
@@ -49,7 +49,7 @@ expect_snapshot_plot(f, label = "tinyplot_add_rug")
 
 # type = "rug" (adding to "density" should default to x variable)
 f = function() {
-  tinyplot( ~ eruptions, data = faithful, type = "density")
+  tinyplot(~eruptions, data = faithful, type = "density")
   tinyplot_add(type = "rug")
 }
 expect_snapshot_plot(f, label = "tinyplot_add_rug_density")
@@ -57,14 +57,14 @@ expect_snapshot_plot(f, label = "tinyplot_add_rug_density")
 
 # type = "rug" (adding to "density" should default to x variable)
 f = function() {
-  tinyplot( ~ eruptions, data = faithful, type = "density")
+  tinyplot(~eruptions, data = faithful, type = "density")
   tinyplot_add(type = "rug")
 }
 expect_snapshot_plot(f, label = "tinyplot_add_rug_density")
 
 
 # use tinyplot_add() inside a custom function with local variables
-tinyplot_lollipop <- function(x, y) {
+tinyplot_lollipop = function(x, y) {
   tinyplot(x, y, type = "h")
   tinyplot_add(type = "p", pch = 19)
   tinyplot_add(type = "hline")
