tidyplots: a pipe-first grammar for publication-ready R plots
Tidy Plots for Scientific Papers
At a glance
- What is it?
- tidyplots is an R package that builds scientific figures by piping a data frame into a tidyplot call and then adding one plot component at a time, so a mean bar, a standard error bar and a beeswarm of raw points are three separate additions rather than one large ggplot2 specification. It ships on CRAN, and its dependency list shows that the heavy lifting is done by ggplot2 and the tidyverse.
- Who is it for?
- tidyplots is worth adopting if you make the same statistical figure over and over and want the appearance of a well-designed plot without writing a full ggplot2 layer specification each time, because the add_ functions encode the decisions a biomedical paper needs, such as showing the raw data behind a summary, and because the pipe syntax keeps a multi-panel figure readable as a single expression.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 135 days ago.
- What is it written in?
- Mainly R, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One pipe expression builds the whole figure
tidyplots states its goal plainly: to streamline the creation of publication-ready plots for scientific papers, allowing you to gradually add, remove and adjust plot components using a consistent and intuitive syntax.
That word gradually is the design. The typical ggplot2 script for a paper figure is one long expression with a stack of geoms, stats, positions and theme overrides, and changing one element means finding the right line in it. Here the figure is built by adding named components to a pipe:
``` r study |> tidyplot(x = treatment, y = score, color = treatment) |> add_mean_bar(alpha = 0.4) |> add_sem_errorbar() |> add_data_points_beeswarm() ```
The tidyplot call establishes the mappings, and each add_ function contributes one visual element. The example is a standard biomedical figure: a translucent mean bar, a standard error bar on top of it, and a beeswarm of the underlying data points so the reader can see the distribution rather than only the summary.
The value of the decomposition is that the elements can be rearranged independently. Swapping the beeswarm for a different summary, or removing the error bar for a figure where it does not apply, is a matter of changing one line in the pipe rather than rewriting the specification.
The syntax is also the tidyverse syntax, and the package acknowledges that directly. The acknowledgements say tidyplots is built upon the software and coding paradigms of the R and tidyverse communities and that it would not have been possible without their contributions, and the listed dependencies are the ones you would expect: ggplot2, dplyr, forcats, ggbeeswarm, ggpubr, ggrastr, ggrepel, glue, scales, stringr, tidyr, tidyselect, purrr, rlang, lifecycle, cli and htmltools, with Hmisc also in the list.
The data flows in with the native pipe, so a plot is a transformation of the data frame rather than a separate object you construct and then configure.
The available components are a catalogue of decisions, not a general layer API
What the add_ functions cover is best read as a list of the choices a paper figure requires, which is a narrower and more opinionated thing than a general plotting grammar.
The summary and spread functions include add_mean_bar, add_mean_line, add_mean_dot, add_mean_dash, add_mean_value and add_sem_errorbar, plus add_sem_ribbon for a shaded band instead of error bars. The composition functions include add_boxplot, add_data_points_beeswarm, add_barstack_absolute, add_barstack_relative, add_areastack_absolute and add_areastack_relative. There is add_donut, add_heatmap, and a family of statistical annotation helpers: add_test_pvalue, add_test_asterisks and add_mean_value.
The annotation helpers are where the package makes a real editorial decision on your behalf. add_test_asterisks takes a hide_info argument, which lets you show the significance stars without the statistical detail, and the boxplot example pairs it with add_test_pvalue and a ref.group argument so the comparison is against a chosen group rather than against whatever the first level happens to be.
The layout functions are adjust_size, which takes a width and a height, split_plot, which takes a by argument and produces one panel per group, remove_x_axis_title, and view_plot, which takes a title. The colour side is adjust_colors, which accepts a named colour scheme.
Two of the documented articles are worth knowing about for a specific reason. There is an article on visualising data with examples for common data visualisations, one on advanced plotting with techniques and workflows, and one on colour schemes. The cheatsheet is a one-page PDF that gives a high level overview of the available functions, and the package index is the full reference of every function.
So the honest characterisation is this: tidyplots is not a plotting language with a tidy syntax, it is a curated set of components for scientific figures, and the value is in the curation rather than in the extensibility.
Colour and size are adjusted, not themed
The way colour is handled in tidyplots is a deliberate limitation rather than an oversight, and the example in the README makes it visible.
``` r study |> tidyplot(x = treatment, y = score, color = treatment) |> add_mean_bar(alpha = 0.4) |> add_sem_errorbar() |> add_data_points_beeswarm() |> view_plot(title = "Default color scheme: 'friendly'") |> adjust_colors(colors_discrete_apple) |> view_plot(title = "Alternative color scheme: 'apple'") ```
The pipe calls view_plot twice, once before and once after the colour change, so the same figure appears with the default scheme and then with the alternative. The default scheme is called friendly, and the alternative shown here is called apple.
The point of the example is that adjust_colors takes a named scheme rather than a set of hex values, and that switching between the built-in schemes is a single call placed in the pipe. The colour schemes article covers this in more depth, and the existence of a named-scheme mechanism at all is a design decision: for a paper with several figures, you want the same palette across all of them, and a named scheme gives you that guarantee without tracking hex values.
The size adjustment is the same shape. adjust_size takes a width and a height, and in the donut and gene expression examples it is used with values of 25 and 25 alongside split_plot, so a multi-panel figure gets a consistent per-panel size.
What is not here is a theme function. There is no way in these examples to set the base font, the grid, the background or the axis line width through tidyplots, and if you need any of that you are back to ggplot2. That is the boundary of the package, and it is a sensible one: the components cover the statistical content of a figure, and the styling stays with the tools that already do it well.
split_plot and the pipeline approach to multi-panel figures
Multi-panel figures get a first-class function rather than a faceting call, and that is worth understanding because it changes how the data is treated.
The pipeline example filters the energy data down to four years and builds a donut chart, then splits it:
``` r energy |> dplyr::filter(year %in% c(2005, 2010, 2015, 2020)) |> tidyplot(y = energy, color = energy_source) |> add_donut() |> adjust_size(width = 25, height = 25) |> split_plot(by = year) ```
The gene expression example does the same thing at a different scale, filtering to four named genes and splitting by external_gene_name, with a per-panel size adjustment applied before the split.
The ordering matters in both examples. adjust_size comes before split_plot, so the size is set on the individual plot and then the split produces panels of that size. Doing it the other way round would set the size on the combined figure, which is a different result.
Notice also that the filter is applied with dplyr::filter before the tidyplot call, using the fully qualified name. That is tidyverse practice, and it is the reason the pipe works on a data frame with no wrapper object. The plot pipeline is a transformation of the data, and anything you want to do to the data first, filtering, aggregation, joining, happens before the first pipe stage.
There is also the heatmap example, which takes x = month, y = year and a continuous colour mapping, and the area stack examples, where add_areastack_absolute and add_areastack_relative are two different but related compositions that both work from the same tidyplot call. The relative variant is the one you want when the parts do not sum to a meaningful total, and the difference between the two is a single word in the function name.
CRAN release, a documented API, and a package still finding its shape
tidyplots is on CRAN, and the released version is installed with the standard call:
``` r install.packages("tidyplots")
The development version comes from GitHub through pak, and the README leaves the pak install commented out so you can read it first:
r # install.packages("pak") pak::pak("jbengler/tidyplots") ```
The release history is v0.4.0 from 2026-01-08, v0.3.1 from 2025-07-02 and v0.2.2 from 2025-03-07. The repository is not archived and the last push was on 2026-06-10, so the tree is being worked on about half a year after the last release, which is normal for a package that is still shaping its API.
The versioning is worth noticing. A package at 0.4.0 is signalling that the API may still change, and for a plotting package that is not a formality, because the names of the add_ functions are the entire interface. The acknowledgements thank Lars Binkle-Ladisch for discussions and for consistently challenging the author's decisions regarding the naming of functions and their arguments, which is a nice signal that the naming was argued over rather than settled by accident.
The documentation is structured as a pkgdown site with a package index, a getting started guide, and the three articles on visualising data, advanced plotting and colour schemes. The vignettes/ directory and the data/ and data-raw/ directories are the conventional R package layout, and the README itself is generated from README.Rmd, which means every example in it is executed as part of the build and the images beside them are current.
There is a peer-reviewed citation for the package, an iMeta article by Engler, Jan Broder, titled Tidyplots Empowers Life Scientists With Easy Code-Based Data Visualization, which is the kind of thing a methods paper in a life sciences journal usually does not have.
The licence field is recorded as one GitHub cannot classify, with LICENSE and LICENSE.md both present at the root, so the terms are worth reading before you redistribute anything derived from it.
Editorial conclusion
tidyplots is worth adopting if you make the same statistical figure over and over and want the appearance of a well-designed plot without writing a full ggplot2 layer specification each time, because the add_ functions encode the decisions a biomedical paper needs, such as showing the raw data behind a summary, and because the pipe syntax keeps a multi-panel figure readable as a single expression. It is the wrong tool if you need a chart type the package does not cover, since you would be back to raw ggplot2 with the tidyplots layer on top, and it is the wrong tool if you need full control of the theme, since adjust_colors and adjust_size are deliberately narrow. Before you build a figure on it, verify three things yourself: that the add_ function you need exists, since the cheatsheet is the authoritative list and the API is still moving, that the version you install matches your ggplot2, since the package leans on ggplot2 and the tidyverse and the CRAN release is v0.4.0, and that the statistical annotations it draws, such as the p-value and asterisk helpers, match the test you actually ran, because the package will place a test result on the plot whether or not that is the test you intended.
Frequently asked questions
What is the tidyplots R package?
It is a package for creating publication-ready plots for scientific papers, letting you gradually add, remove and adjust plot components with a consistent syntax. The heavy lifting is done by dependencies including ggplot2, dplyr, ggbeeswarm, ggpubr, ggrepel, scales and tidyr.
How do I install tidyplots?
The released version installs from CRAN with install.packages("tidyplots"), and the development version comes from GitHub with pak::pak("jbengler/tidyplots"), after installing pak. The newest listed release is v0.4.0 from 2026-01-08.
Which plot components does tidyplots provide?
Mean summaries such as add_mean_bar, add_mean_line, add_mean_dot, add_mean_dash and add_mean_value, spread layers such as add_sem_errorbar and add_sem_ribbon, compositions such as add_boxplot, add_data_points_beeswarm, add_barstack_absolute, add_donut and add_heatmap, statistical annotations including add_test_pvalue and add_test_asterisks, and layout helpers adjust_size, split_plot, remove_x_axis_title and view_plot.
How do I change colours in tidyplots?
With the adjust_colors function, which takes a named colour scheme rather than individual hex values. The default scheme is called friendly, and the README example shows a plot rendered with the default and then again with an alternative scheme called apple, using view_plot to display each step.
How do I make a multi-panel figure with tidyplots?
Use the split_plot function with a by argument, after setting the per-panel size with adjust_size. The README examples filter the data first with dplyr::filter, then apply adjust_size and then split_plot, for example splitting a donut chart by year or a gene expression plot by external gene name.
Official sources
Was this useful?