ggdist: ggplot2 geoms for distributions and uncertainty, frequentist or Bayesian
Visualizations of distributions and uncertainty
At a glance
- What is it?
- ggdist is an R package of ggplot2 geoms and stats for visualising distributions and uncertainty, built on the idea that both confidence distributions and posterior distributions are distributions, so one set of geoms can draw them. It ships on CRAN, keeps its dependency list short, and its dotplot layouts are implemented in C++ for speed.
- Who is it for?
- Adopt ggdist if you work in ggplot2 and need to show distributions or uncertainty rather than a point estimate, and if you want one set of geoms to cover both confidence intervals and posterior draws. Do not adopt it for static figures where a CI error bar is the accepted convention, because half-eye and rain cloud plots need the reader to understand density.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 1 day 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
The problem: a point estimate hides what you actually know
The standard way to show uncertainty in a plot is an error bar. It is compact, it is familiar, and it communicates one number, the width of an interval, about a distribution that is rarely symmetric and sometimes multimodal.
ggdist is an R package that provides a flexible set of ggplot2 geoms and stats designed especially for visualizing distributions and uncertainty. The claim in the documentation is a specific one about how these two problems relate, and it is the reason the package exists: uncertainty visualization can be unified through the perspective of distribution visualization.
So for frequentist models you visualize confidence distributions or bootstrap distributions, and the vignette named freq-uncertainty-vis covers that case. For Bayesian models you visualize probability distributions, and the tidybayes package, which builds on top of ggdist, covers that case. One idea, two statistical worlds.
The audience is the R user who already lives in ggplot2 and is tired of reaching for a second plotting system to draw a posterior. The topics confirm the position: ggplot2, r-package, uncertainty, uncertainty-visualization, visualization.
The licence is GPL-3.0, the package is on CRAN, the last push was on 2026-10-12, and the published versions are v3.3.3 from 2025-04-23, v3.3.2 from 2024-03-05 and v3.3.1 from 2023-11-30.
Three geom families, each aimed at a different shape of data
The package organises itself into three families, and the naming tells you what to reach for.
The geom_slabinterval() and stat_slabinterval() family, documented in the slabinterval vignette, makes it easy to visualize point summaries and intervals, eye plots, half-eye plots, ridge plots, CCDF bar plots, gradient plots, histograms, and more. This is the family for a distribution with a summary laid over it, which is why it also has cheat sheets published for it as PDF and PNG.
The geom_dotsinterval() and stat_dotsinterval() family, in the dotsinterval vignette, makes it easy to visualize dot plus interval plots, Wilkinson dotplots, beeswarm plots, and quantile dotplots, and combined with half-eyes it produces composite plots like rain cloud plots. So a dotplot here is not just a strip of points, it is a layout that decides where each point goes so the shape of the distribution stays readable.
The geom_lineribbon() and stat_lineribbon() family, in the lineribbon vignette, makes it easy to visualize fit lines with an arbitrary number of uncertainty bands. The word arbitrary matters, because a model with several parameters often produces a family of bands rather than a single ribbon, and this family is built for that.
The three together cover the common cases, and the third is the one people reach for most often. The package description in the repository is simply visualizations of distributions and uncertainty, and that is an honest description of a focused library.
Distribution objects, so the same geom works for analytical and sampled data
The part of the design that makes ggdist more than a set of pretty geoms is that all of its stats also support visualizing analytical distributions and vectorized distribution data types.
Two of those types are named in the documentation. One is distributional objects, from the distributional package, which implements vectors of distributions. The other is posterior::rvar() objects, which is how posterior distributions are represented in the tidybayes and posterior packages.
The practical effect is that the same geom can draw a normal distribution you typed in as a function, a bootstrap sample you computed, and a set of posterior draws you pulled out of a model, without branching in the plotting code. For a Bayesian workflow that matters, because the same figure often needs to show the prior, the posterior and an analytical approximation, and each of those is a different data type until it reaches the geom.
The documentation points at the use for visualizing uncertainty in frequentist models and for visualizing priors in a Bayesian analysis, and the tidybayes vignettes, including tidybayes and tidy-brms, are given as the place to see the geoms in use on real models.
The relationship with tidybayes is worth stating plainly, because it explains the history. The ggdist geoms and stats form a core part of the tidybayes package, and in fact they originally were part of tidybayes. So the split you see now is a separation of concerns: the drawing layer lives in ggdist, and the model integration lives in tidybayes on top of it.
Installing from CRAN, or tracking the development version
The CRAN route is one line:
``` r install.packages("ggdist")
And the development version from GitHub is two:
r install.packages("devtools") devtools::install_github("mjskay/ggdist") ```
The distinction matters for this particular package, because the development branch is where the newer work lands. The documentation for the dotplot layouts refers to the bin and weave layouts, and the weave layout in particular is not something you would find in the 3.3.3 release notes, so anyone who wants the current layout behaviour is installing from GitHub.
That is a general property of an R package that develops its layouts in the open, and it comes with the usual caveat: a GitHub install of an R package pulls the source, and if the package has compiled code you need a working toolchain. The presence of a src/ directory in the repository means there is C++ code to compile.
For the CRAN install, the answer is simpler, and the package is built and checked on the CRAN machines, so the R-CMD-check workflow and the coverage status badges in the repository are the evidence that the published version behaves.
The dependency policy, and why numDeriv and quadprog are in there
The dependency section of the documentation is unusually explicit, and it is worth reading because it tells you what the package values.
The stated aim is that ggdist has minimal additional dependencies beyond those already required by ggplot2. The dependencies fall into three categories, and the structure of that list is the design.
The first category is ggplot2 itself. The second is packages that ggplot2 also depends on, which therefore add no additional dependency cost: rlang, cli, scales, tibble, vctrs, withr, gtable and glue. The third category is packages ggplot2 does not depend on, and here the documentation gives a reason for each one.
distributional is the implementation of distribution vectors that powers much of ggdist, and its only dependency that is not also a ggplot2 dependency is numDeriv, which the package needs anyway. numDeriv is used for calculating Jacobians of scale transformations, and the documentation is candid about why it was added: testing has revealed common situations where stats::numericDeriv() fails but numDeriv does not.
quadprog is used to solve constrained optimization problems during different parts of dotplot layout, particularly to avoid dot overlaps in the bin and weave layouts. Rcpp is used to implement faster dotplot layout. All three are described as widely used by other CRAN packages with no additional dependencies.
That last point is the one to hold on to. The heavy part of this package is the dotplot layout, and the layout is where the constrained optimisation and the compiled code go. A user who never draws a dotplot still pays for the dependencies, which is the cost of a coherent package rather than a minimal one.
Citing, contributing, and where ggdist is the wrong tool
Two things are worth knowing before you put ggdist output in a paper.
The first is the citation, and there are two of them. The method paper is Matthew Kay (2024), ggdist: Visualizations of Distributions and Uncertainty in the Grammar of Graphics, in IEEE Transactions on Visualization and Computer Graphics, 30(1), 414 to 424, with the DOI 10.1109/TVCG.2023.3327195, which is also the paper DOI in the badges. The second is the software citation, Matthew Kay (2025), ggdist: Visualizations of Distributions and Uncertainty, R package version 3.3.3, with a Zenodo DOI of 10.5281/zenodo.3879620. Citing the paper and archiving the version you used are the two halves of making a figure reproducible.
The second is the contribution route. Pull requests should be filed against the dev branch, and issues should come with minimal code to reproduce the problem. The author is candid about the contact channel, saying he is not particularly reliable over email, and that a Bluesky message is more likely to elicit a response.
Where ggdist is the wrong tool is mostly about audience. A half-eye plot or a rain cloud plot is a good way to show a distribution to a reader who knows what a density is, and a poor way to show it to a reader who expects a bar with whiskers. If the venue expects a conventional confidence band, geom_lineribbon() gives you that, and you have not needed the rest of the package.
The other limit is scale. The dotplot layouts do real optimisation to place points, and the compiled code and the R library are there because that work is not free. A plot with a handful of draws does not need it, and a plot with a very large number of draws needs attention to how it is rendered, which is a different problem from the one this package solves.
Editorial conclusion
Adopt ggdist if you work in ggplot2 and need to show distributions or uncertainty rather than a point estimate, and if you want one set of geoms to cover both confidence intervals and posterior draws. Do not adopt it for static figures where a CI error bar is the accepted convention, because half-eye and rain cloud plots need the reader to understand density. Before you use it in a paper, cite both the paper and the package version, and check that your export pipeline can handle the additional rasterisation the dotplot layouts need for large numbers of points.
Frequently asked questions
What is ggdist used for?
It is an R package that provides a flexible set of ggplot2 geoms and stats designed especially for visualizing distributions and uncertainty, for both frequentist and Bayesian workflows. It unifies the two through the perspective of distribution visualization, with confidence or bootstrap distributions for frequentist models and probability distributions for Bayesian ones.
Which geom families does ggdist provide?
The geom_slabinterval() and stat_slabinterval() family for point summaries, intervals, eye plots, half-eye plots, ridge plots, CCDF bar plots, gradient plots and histograms, the geom_dotsinterval() and stat_dotsinterval() family for dot plus interval plots, Wilkinson dotplots, beeswarm plots and quantile dotplots, and the geom_lineribbon() and stat_lineribbon() family for fit lines with an arbitrary number of uncertainty bands.
How do I install ggdist?
From CRAN with install.packages("ggdist"), or the latest development version with install.packages("devtools") followed by devtools::install_github("mjskay/ggdist"). The development branch is where the newer dotplot layouts land, and the package has compiled C++ code in src/, so a GitHub install needs a working toolchain.
What extra dependencies does ggdist add on top of ggplot2?
distributional, numDeriv, quadprog and Rcpp. The documentation explains each: distributional implements distribution vectors, numDeriv computes Jacobians of scale transformations where stats::numericDeriv() fails, quadprog solves constrained optimisation to avoid dot overlaps in dotplot layouts, and Rcpp implements faster dotplot layout. All are widely used CRAN packages with no further dependencies.
How is ggdist related to tidybayes?
The ggdist geoms and stats form a core part of the tidybayes package, and in fact they originally were part of tidybayes. tidybayes now builds on top of ggdist, and its vignettes, including tidybayes and tidy-brms, are the reference examples for visualising uncertainty in Bayesian models.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mjskay-ggdist)Was this useful?