R Observatory
Search
install.packages("tinyplot")
CRAN 30-day downloads, method
11,719+48.8% up on the 30 days before, the better direction

Lightweight extension of the base R graphics system, with support for automatic legends, facets, themes, and various other enhancements.

Maintainer
Grant McDermott
Latest release
28 Sep 2026
First release
20 Jun 2024

Compare with another package

More details
Releases
12
Needs compilation
No
Needs R
>= 4.0.0
Config/Needs/website
altdoc (>= 0.7.2), future.apply
Config/roxygen2/version
8.1.0
Date
2026-09-27
Subjects (1) Method, Subjects
Cite

Package

Run in R for the authors' preferred citation:

citation("tinyplot")

The package provides a citation file that builds its entry when R runs it. Run citation() to see it.

R Observatory

For a number measured here: a download total, a coverage figure, an archival date.

APA
Balamuta, J. J. (2026). R Observatory: Metrics for tinyplot version 0.8.0 [Data set]. HJJB, LLC. Data release v2026-10-28. https://doi.org/10.5281/zenodo.21843040
About

From data release v2026-10-28, which the citation names so these numbers can be found later.

All 13 check platforms pass.

  • r-devel-linux-x86_64-debian-clang

    The unreleased R on Linux, x86_64, debian-clang

    OK

    Version checked
    0.8.0
    Time taken
    108 s
  • r-devel-linux-x86_64-debian-gcc

    The unreleased R on Linux, x86_64, debian-gcc

    OK

    Version checked
    0.8.0
    Time taken
    78 s
  • r-devel-linux-x86_64-fedora-clang

    The unreleased R on Linux, x86_64, fedora-clang

    OK

    Version checked
    0.8.0
    Time taken
    70 s
  • r-devel-linux-x86_64-fedora-gcc

    The unreleased R on Linux, x86_64, fedora-gcc

    OK

    Version checked
    0.8.0
    Time taken
    63 s
  • r-devel-windows-x86_64

    The unreleased R on Windows, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    139 s
  • r-oldrel-macos-arm64

    The previous release of R on macOS, arm64

    OK

    Version checked
    0.8.0
    Time taken
    45 s
  • r-oldrel-macos-x86_64

    The previous release of R on macOS, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    142 s
  • r-oldrel-windows-x86_64

    The previous release of R on Windows, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    158 s
  • r-patched-linux-x86_64

    The patched release of R on Linux, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    104 s
  • r-release-linux-x86_64

    The current release of R on Linux, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    104 s
  • r-release-macos-arm64

    The current release of R on macOS, arm64

    OK

    Version checked
    0.8.0
    Time taken
    29 s
  • r-release-macos-x86_64

    The current release of R on macOS, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    158 s
  • r-release-windows-x86_64

    The current release of R on Windows, x86_64

    OK

    Version checked
    0.8.0
    Time taken
    135 s
  • 13 OK

Over time

No change since 4 Aug 2026

As a list (5)
ChangedWorst statusOKNotesWarningsErrors
4 Aug 2026OK13000
1 Aug 2026Note12100
9 Jun 2026OK13000
8 Jun 2026Warning12010
10 Mar 2026OK14000

Since March 2026

Check results on CRAN

Total downloads in the last 30 days
12,289+48.7% up on the 30 days before, the better directionIt is the sum of 4 channels: CRAN, r2u, autoCRAN and conda-forge.

CRAN rank

1,066 of 26,530

CRAN

11,719 downloads in the last 30 days

Rank
1,066 of 26,530
Change
+48.8% up on the 30 days before, the better direction

It is in the total. Take it out

r2u

276 downloads in the last 30 days

Rank
1,476 of 30,526
Change
+40.8% up on the 30 days before, the better direction

It is in the total. Take it out

autoCRAN

1 downloads in the last 30 days

Rank
25,688 of 29,212
Change
−92.9% down on the 30 days before, the worse direction

It is in the total. Take it out

conda-forge

293 downloads in the last 30 days

Rank
2,038 of 3,828
Change
+66.5% up on the 30 days before, the better direction

It is in the total. Take it out

Over time

Compare downloads

Needs
5
Dependent packages
11
Suggested by
9
Needs (5)
  • graphics
  • grDevices
  • stats
  • tools
  • utils
Installing it adds
0 packages, 0 KB of source
Of those, need compilation
0
Optional extras (7)
Dependent packages (11)
PackageTitleDownloads in 30 days
pdpPartial Dependence Plots6,629
etwfeExtended Two-Way Fixed Effects877
PPPerson Parameter Estimation731
joineryHeuristic Index-Based Record Linkage319
fwlplotScatter Plot After Residualizing Using 'fixest' Package317
parttreeVisualize Simple 2-D Decision Tree Partitions311
forrestPublication-Ready Forest Plots294
multiSAMulti-Stock Assessment283
tradepolicyReplication of 'An Advanced Guide To Trade Policy Analysis'278
collettDatasets from "Modelling Survival Data in Medical Research" by Collett262
partialling.outResiduals from Partial Regressions194
Functions
283
Public exports
51
Lines of R code
19,106
Median complexity
4
Functions (283)
Size and composition

Lines by kind (25,715)

KindLinesShare
R code19,10674%
Tests140.1%
Documentation6,59526%

Lines by language

LanguageLinesShare
R19,12074%
Rd6,59526%

Languages are counted from file extensions.

Files
152
R functions
283
Object systems
S3: 9 methods
Complexity
Median
4
Mean
9.42
Highest
200
Median lines per function
17
About complexity

Cyclomatic complexity counts the independent paths through a function: 1 is a straight line, higher is harder to test. R functions only.

Call graph figures
R functions
283
Calls
478
Unconnected
9
Groups
7
Growth (12 releases)
Total lines by release
4,151 on 20 Jun 202425,715 on 28 Sep 2026
Release changes

The tests stopped with an error, so coverage was not obtained.

Lines of tests
14
Exports named in tests
2%
Test suite
Has tests
Yes
Test frameworks
tinytest
Test lines per line of code
0
Exports documented
100%
Arguments documented
84.4%
Return value documented
25%
Help pages with examples
75.4%
Examples run in checks
93.5%
Other documentation
README
Yes, 625 words
Release notes file
Yes
Help pages
61
Lines of documentation
6,595

grantmcdermott / tinyplot on github.com

Stars
429no change on 30 days ago
Forks
25
Open issues
20
Last commit
28 Sep 2026
Activity
Commits
734
Open pull requests
0
Tagged releases
17
Latest tagged release
v0.8.0, 28 Sep 2026
Issues closed in
6 days (median)
Pull requests closed in
0 days (median)
Pull requests merged
93%
Created
21 Feb 2023
Licence file reads as
Apache-2.0
Development practices (10)
KindFound
Continuous integrationGitHub Actions, R CMD check workflow
The R CMD check workflow runs on Linux
Docs sourceREADME.qmd, altdoc
GitHub Pages site last deployed 2026-09-28
The repository has a site deploy workflow
pkgdown site last built 2026-09-28
Reproducibility and dev environmentMakefile, Dev Container
CRAN release processcran-comments.md, CRAN-SUBMISSION

Method, repository practices

Across grantmcdermott

Claude Codeat least 5 crediting itClaude CodeFirst seen 14 May 2026at least 5 crediting it
Claude Opus 4.8Claude Opus 4.815 Aug 20261 commit

Tools

ToolFirst seenFoundCommits crediting it
Claude Code14 May 2026Seen in the repositoryCLAUDE.mdNamed in .Rbuildignore.claudeCLAUDE.mdNamed in .gitignore.claudePull request it wrote: opened by a project member5 at least
  • Seen in the repository
  • Named in .Rbuildignore
  • Named in .gitignore
  • Pull request

Models

ModelCommitsFirst commitLast commitCredit lines of
Claude Opus 4.8115 Aug 202615 Aug 2026Claude Code

Across grantmcdermott

R releases
  • On CRAN
  • Release
VersionReleasedR
0.8.0 current28 Sep 20264.6.1
0.7.03 Jul 20264.6.1
0.6.128 Mar 20264.5.3
0.6.027 Nov 20254.5.2
0.5.022 Sep 20254.5.1
0.4.212 Jul 20254.5.1
0.4.13 Jun 20254.5.0
0.4.023 May 20254.5.0
Earlier versions (4)
VersionReleasedR
0.3.05 Feb 20254.4.2
0.2.126 Aug 20244.4.1
0.2.031 Jul 20244.4.1
0.1.020 Jun 20244.4.1
Release notes (0.8.0)

Breaking changes

  • type_lines() and its shortcut equivalents like "l" and "b" now order categorical x data by (coerced) factor levels, rather than simple order of appearance. This resolves a longstanding tension between line types and other types like type_points(), which have always ordered the x axis by implied factor levels. It also improves layering consistency via plt_add() and co. so that plots are identical, regardless of whether lines are layered on top of points, or vice versa. Note that you can still select into the old behaviour by passing the (new) xord = "asis" argument as an explicit override; see "Other new features" below. (#683 @grantmcdermott)

New features

New plot types

  • type_hexbin() / "hexbin" for hexagonal bin plots, a 2D analogue of a histogram. (#667 @grantmcdermott)
  • type_tile() / "tile" for tile plots, i.e. a grid of rectangles whose fill encodes a third variable. (#677 @grantmcdermott)
  • type_heatmap() / "heatmap" builds on type_tile(), adding a scale argument that scales the fill values _within_ each category of one axis. This is analogous to base R's heatmap() function, and like the latter it z-scores along the chosen margin by default. It also reverses the y-axis by default, so that the first row sits at the top (again matching heatmap()); pass an explicit ylim to override. (#677 @grantmcdermott)
  • type_sina() / "sina" for sina plots, a variant of the violin plot where the raw observations are displayed as points, with each group's width bounded by its density. This makes them arguably a more principled version of the beeswarm plot. (#734 @grantmcdermott)
  • While not strictly a new plot type, type_area() gains a new stack argument for drawing _stacked_ area plots, where each layer represents a discrete by category group. This functionality is further enhanced by two (also new) sister arguments. First, byord enables on-the-fly (re-)ordering of the stacked by layers, via convenience keywords or custom functions (e.g., byord = "end" ranks groups according to their largest final value). Second, a fun argument permits stacking of multi-observation data by collapsing repeated y values. (#688 @grantmcdermott)

Facet improvements

The top-level facet.args list argument gains several new (sub-)arguments that

enable finer control and customization of faceted plots:

  • axes: gives explicit control over which facets draw their own axes: "all", "outer" (drop redundant interior axes), or "none". Previously this was only achievable as a side effect of frame.plot = FALSE, so axes = "outer" now allows redundant axes to be dropped while _keeping_ the facet frames. Left unspecified, the behaviour is still inferred from whether the plot is framed. (#661, #673 @grantmcdermott)
  • Themes with L-shaped axes ("classic", "socviz", "tufte", and "float") now default to facet.axes = "outer", so that they drop the redundant interior axes of faceted plots.
  • drop: allows for the removal of empty facets. The behaviour varies slightly depending on whether a one-sided (wrapped) or two-sided (gridded) facet formula is specified. The former simply removes the missing factor level, while the latter retains its spot (to preserve the rectangular grid) but is not drawn. (#708, #710 @grantmcdermott)
  • drop.levels: allows each free facet (free = TRUE) to keep only the categories of a categorical axis that it actually uses. The panel's axis is recomputed as if its own data had been passed through factor(), so that the surviving categories are re-spaced evenly rather than leaving a gap where an unused one sat. Note the distinction from drop above: the latter removes empty _facets_, whereas drop.levels removes unused _categories within_ a facet. Default is FALSE, i.e. every facet keeps the full set of categories. (#718 @grantmcdermott)
  • labeller: for formatting facet titles via tinylabel(). Accepts the usual mix of convenience keywords (symbols) known to tinylabel(), or formatting functions. A (named) vector or list can be used to separately format multi-variable facets, e.g. labeller = c(country = toupper, size = ","). (#684 @grantmcdermott)
  • prefix: for adding an informative prefix to facet titles. In its simplest form, prefix = TRUE prepends the facet variable name, e.g. "vs = 0" and "vs = 1" (rather than just "0" and "1"). Like labeller above, multi-variable facets can be prefixed separately via a (named) vector or list, e.g. prefix = c(am = "Automatic", vs = "V-shaped"). (#684 @grantmcdermott)
  • sep: controls how the individual variables of a multi-variable facet title are separated, e.g. use sep = "\n" to stack on separate lines rather than concatenating via the default ":". (#684 @grantmcdermott)

Note that each of these facet.args arguments is paired with an equivalent

tpar(facet.<arg>) parameter. For example, call tpar(facet.axes = "outer")

to set this behaviour globally. This also means that they can be set as part of

a (custom) theme, e.g. tinytheme("clean", facet.axes = "outer").

Ordering and labelling categorical variables

This release brings several enhancements for working with _categorical_

variables, i.e. where x, y, or by are characters or factors with discrete

levels. This includes improvements to existing arguments, as well as the

provision of some new arguments that enable finer control over level ordering

and convenient label formatting.

  • xlevels, ylevels: these (type-level) arguments permit on-the-fly reordering of a categorical variable via _literal_ specification, either a character vector of level names (e.g., c("C", "B", "A")), or a numeric vector of level indices (e.g., 3:1). While this argument is not new---having been supported by type_barplot and several other types for a while---we now extend xlevels support to type_points(), type_lines(), type_errorbar(), and type_pointrange(). (#683, #694 @grantmcdermott)
  • xord, yord: these are new (type-level) arguments that provide an alternate ordering interface to x/ylevels. Specifically, while x/ylevels require a literal ordering, x/yord _computes_ the order on the fly, according to (type-appropriate) convenience keywords or a custom ranking function. For example, "desc(ending)"/"asc(ending)" orders by value, while "asis" ignores factor levels and just takes the order of appearance in the data as given. Among other things, this makes it possible to sort barplots by height (e.g., type_barplot(xord = "desc")), or ridges by their spread (e.g., type_ridge(yord = "minvar")) without relevelling the underlying factor by hand. (#683, #694 @grantmcdermott)
  • (Note: users should only supply one of the preceding sets of arguments. If both x/ylevels and x/yord are provided, the former takes precedence as the more explicit.)
  • tinylabel() gains a dictionary form, i.e., a *named* character vector or list that maps existing labels to new ones _a la_ c(old1 = "new1", old2 = "new2"). Partial mapping is fine since the lookup is by value rather than by position, so that some levels can be left unnamed. Importantly, this behaviour extends to the rest of tinyplot's (re)labelling machinery---including x/yaxl, type_text(), and any function with a labeller argument---since everything is routed through tinylabel(). (#690 @grantmcdermott)
  • The type-level x/yaxlabels arguments of type_spineplot() and type_barplot() are deprecated in favour of the top-level x/yaxl arguments. The type-level arguments predated their top-level cousins, which now offer the same functionality via a consistent interface across _all_ types. The old arguments still work (with a warning) for now. But we will be formally removing them in a future release and, going forwards, encourage users to move over to xaxl and yaxl as the idiomatic tinyplot way to relabel and format axis ticks. (#692 @grantmcdermott)

Beyond convenience, these improvements to categorical variable handling also

provide the scaffolding to eliminate some niggling inconsistencies; for example,

related to plot layering. See "Bug fixes" below.

Axis aesthetics

  • Point-like glyphs ("p", "l", "errorbar", and friends) gain smart padding behaviour for categorical axes. Most notably, we now use more generous axis padding when there are few unique categories (levels), so that the end tick marks aren't drawn flush against the plot frame. Users can also override with the new x/ypad arguments (see below) to match their own aesthetic preferences. (#732 @grantmcdermott)

New tinyplot.* methods

  • tinyplot.array(): for (unclassed) array objects with up to four dimensions. This extends the tinyplot.matrix() conventions by mapping the third dimension to facets, and a fourth to a facet grid. The names of the dimnames (if any) are used for the axis, legend, and facet titles. Arrays with a length-2 dimension (e.g., gait) are plotted as x/y pairs, i.e. one slice against the other. See the tinyplot.array-specific xy argument. Passing facet = FALSE draws everything in a single panel instead. (#746 @grantmcdermott)

Other new features

  • New top-level tinyplot()/plt() arguments:
  • xpad and ypad enable control over how much padding (as a fraction of the data range) is added to each end of the axes. Following base R conventions, the default for most plots is 0.04, i.e. 4% padding on each side. Also settable globally via tpar(xpad = <xpad>, ypad = <ypad>). (#729 @grantmcdermott)
  • xaxr and yaxr enable rotating of the x- and y-axis tick labels by arbitrary angles, closing a long-standing feature request (#346). Note that setting one overrides las for that axis. Best combined with a dynamic theme, since the plot margins are resized to fit the rotated labels. Also settable globally via tpar(xaxr = <xaxr>, yaxr = <yaxr>) and thus as part of a tinytheme too. (#717 @grantmcdermott)
  • las does the same thing, but limited to the four right angles of base R's par(las=) convention, having previously been settable only via tpar() or a theme. Note that this top-level argument applies to a single plot only and takes precedence over the active theme, so it can also be used to opt _out_ of a theme's las, e.g. tinyplot(..., theme = "clean", las = 0). (#353 @grantmcdermott)
  • (Experimental) record enables recording plots as replayable objects, closing another long-standing feature request (#121). Specifically, setting record = TRUE returns a "recordedtinyplot" object (see ?recordedtinyplot), allowing for assignment and later recall, e.g. myplot = tinyplot(...); myplot. Also settable globally via tpar(record = TRUE), so that all tinyplot() plots are automatically recorded---with potential memory implications for detailed plots with _many_ elements. Note that a recorded plot will still render its display on the initialising call if you are using an interactive graphics device. While we have done our best to vet this new record functionality carefully, users should still regard it as experimental. We may change its behaviour (availability) in a future release if we observe undesirable side-effects. Please help us by testing on your own machines and reporting any issues. (#686 @grantmcdermott)
  • Type-specific updates:
  • type_lines() and its shortcut equivalents like "l" and "s" now support a _continuous_ by variable, drawing a colour gradient along the line itself rather than reverting to a discrete legend. Useful for trajectories, where a third variable (typically time) orders the path; see the new ?type_lines examples. (#712 @grantmcdermott)
  • type_density() gains an echo.bw argument for reporting the smoothing bandwidth and the number of observations behind it, neither of which is visible from the curve itself. Destinations are "sub", "cap", and "cat" (console), in any combination; a destination the user has already labelled is left alone. Shared bandwidths are reported once and named as joint, individual bandwidths per group. (#287 @haomeng797-ship-it)
  • type_area() gains a stack argument for drawing stacked area plots. See "New plot types" above for more details. (#688 @grantmcdermott)
  • type_summary() gains a dodge (and fixed.dodge) argument, thus enabling dodging of grouped plots. This is mostly useful for adding summaries on top of a base layer that is itself dodged. Separately, type_summary()'s internals have been refactored to use stats::aggregate instead of stats::ave. (#701 @grantmcdermott)
  • type_barplot() gains a na.as.zero argument for controlling whether a category that no observation reaches is treated as a zero (and so marked with a flat bar along the baseline) or left undrawn. The default NULL lets fun decide; see the new "Implicit zeros and empty cells" section of ?type_barplot. (#718 @grantmcdermott)
  • type_barplot()'s aggregation argument is now spelled fun, for consistency with the other types that take a function and with tinyplot's lowercase argument naming generally. FUN is retained as a backwards-compatible alias, so existing code keeps working; supply one or the other, and fun takes precedence if both are given. (#695 @grantmcdermott)
  • type_histogram() now (correctly) supports mapping by grouping along the x variable, e.g. tinyplot(~mpg | mpg, data = mtcars, type = "hist"). Bar colours map to mean bin values. (#727 @grantmcdermott)
  • type_loess() is now much faster on large data. Thanks to @eleuven for bringing this slowness issue to our attention. (#509 @grantmcdermott)
  • Themes:
  • "heatmap" provides a dedicated companion theme to the new type_tile() and type_heatmap() types (see above). The theme removes all axis padding, so that tiles meet the panel edge, and also rotates the tick labels against their respective axes. Colour fills default to the "tealgrn" sequential palette. (#677 @grantmcdermott)
  • New tinytheme_get() function returns the name of the currently active theme. (#629 @grantmcdermott)
  • Custom plot types have more control over the surrounding plot machinery, via a new type_hints mechanism. A type can declare properties about itself---that it draws its own axes, needs a secondary right-hand axis, uses proportional limits, fills its legend key from col, and so on---and tinyplot adjusts margins, axis limits and legend keys accordingly. Previously this behaviour was hard-coded against the names of built-in types, so it was unavailable to custom types. See Advanced customization in the Types vignette for the list of supported hints. (#543 @grantmcdermott)

The notes are cut short here.