grantmcdermott · GitHub

Closes #661

(Follow-up to #637)

Expands and improves on my initial PR, by:

  1. Adding facet.axes as a tpar() parameter, so the behaviour can be set globally and hence by themes. Speaking of which...

  2. Using it in the themes. "classic", "socviz", "tufte" and "float" now default to facet.axes = "outer". The frameless themes declare it explicitly too. (This is a no-op today, but it means they no longer depend on frame.plot = FALSE being inferred from their xaxt/yaxt styling, giving us a migration path if we later deprecate the old logic.)

  3. Fixing the spacing. facet.args = list(axes = "outer") dropped the redundant interior axes but left the whitespace they would have occupied behind. (Reason: the tightening keyed off frame.plot rather than off whether the interior axes are actually drawn.) Both now route through a single outer_axes_only() predicate / source of truth.

  4. Dropping interior frame edges for L-shaped axes (bty = "l"). A theme with an L-shaped frame (e.g. "classic") drew that L in every panel, leaving bare rules floating in the gutter once the interior axes were suppressed. Since base bty has no code for a single edge, I ended up rolling a bespoke draw_facet_box() function for these cases that decomposes the bty into its sides, drops any facing a neighbour, and draws the rest.

  5. Incidentally fixed an unrelated (longstanding) bug spotted along the way: free facets were silently ignoring the themed cex.axis, lwd.axis and lty.axis. This was quite an edge case, e.g., only really visible under, say, tinytheme("bw") with free facets. But the fix now stops those axis lines from being rendered at the wrong width (too thick in the case of the "bw" theme).

MWE

pkgload::load_all("~/Documents/Projects/tinyplot/")
#> ℹ Loading tinyplot
# "classic" among several themes that now use tpar(facet.axes = "outer") by default
plt(mpg ~ wt, mtcars, facet = ~am:vs, theme = "classic")

# you can override either at call time...
plt(mpg ~ wt, mtcars, facet = ~am:vs, theme = "classic", facet.args = list(axes = "all"))

# ... or, by adjusting the theme settings
plt(mpg ~ wt, mtcars, facet = ~am:vs, theme = list("classic", facet.axes = "all"))

# works the other way too: themes that wouldn't normally suppress can be made to
plt(mpg ~ wt, mtcars, facet = ~am:vs, theme = list("default", facet.axes = "outer"))

# note that free axes never suppress the inner axes
plt(mpg ~ wt, mtcars, facet = ~am:vs, theme = "classic", facet.args = list(free = TRUE))

Created on 2026-07-31 with reprex v2.1.1

Read the original on github.com ↗