ggfortify: turning statistical model output into ggplot2 plots without writing a plot
Define fortify and autoplot functions to allow ggplot2 to handle some popular R packages.
At a glance
- What is it?
- ggfortify is an R package that defines fortify and autoplot methods for the result objects of dozens of popular modelling packages, so an lm or an Arima fit can be plotted with one call. Its reach is wide and its maintenance is a single maintainer question, and the licence is a custom one rather than a standard open source licence.
- Who is it for?
- ggfortify suits an R user who wants diagnostic and fitted plots from a model object in one call rather than by hand, and it does not suit someone who needs a plot type the package does not cover or a method that returns only a data frame without a plot, because fortify and autoplot are separate contracts and only some classes implement both.
- 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 26 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 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The S3 method that makes ggplot2 accept model objects
ggplot2 has a mechanism where a package can teach it how to draw an object it has never heard of, and ggfortify exists to exploit that mechanism broadly.
The package offers fortify and autoplot functions, and the description says it defines them to allow automatic ggplot2 visualization of the statistical result of popular R packages. The two names are worth separating because they do different jobs. A fortify function turns a model result into a plain data frame that any plotting code can consume. An autoplot function returns a ggplot object, so the result can be tweaked with the usual ggplot2 syntax afterwards.
That split is the core of the design. Writing a fortify method for a class gives you a data frame, which is composable with any grammar of graphics. Writing an autoplot method for the same class gives you a finished plot. Packages that are not on the supported list can still be visualised by writing the fortify half yourself, and the R Journal paper on the package is described in the readme as covering the overall architecture design along with a gallery of visualisations.
The package is a mature one rather than a new idea. It has been on CRAN long enough to have an R Journal paper from 2016, it has a version badge and a download badge, and the repository carries the standard R package layout: a DESCRIPTION file, a NAMESPACE, an R/ directory, man/ pages, tests/, vignettes/ and inst/.
There is also a companion project, autoplotly, which is described as automatically generating interactive visualisations in a plotly.js style based on ggfortify, with the generated visualisations still extendable using ggplot2 syntax while staying interactive. That is a sensible division of labour, since the plotly rendering problem is separate from the data reshaping problem.
The class list is the feature, and it is long
The coverage list in the readme is the clearest statement of what the package actually is: a wide map of the R statistical ecosystem, with a fortify or autoplot method attached to each supported class.
The list runs from base classes upward. It includes base::matrix, base::table with fortify only, and then a long run of modelling packages. Clustering is covered through cluster::clara, cluster::fanny, cluster::pam and cluster::silhouette. Time series work includes changepoint::cpt, forecast::bats, forecast::forecast, forecast::ets, forecast::nnetar, fracdiff::fracdiff, stats::acf, stats::ar, stats::Arima, stats::decomposed.ts, stats::HoltWinters, stats::spec, stats::stl, stats::ts, timeSeries::timeSeries, tseries::irts, vars::varprd, xts::xts and zoo::zooreg.
Regression and classification are covered as well, with glmnet::glmnet, glmnet::cv.glmnet, stats::glm, stats::lm, stats::factanal, stats::kmeans, survival::survfit and its cox and ms variants, ROCR::performance, and MASS::isoMDS, MASS::sammon and stats::cmdscale, the last three marked as inference.
Then there is the spatial group: maps::map, sp::Line, sp::Lines, sp::Polygon, sp::Polygons, sp::SpatialLines, sp::SpatialLinesDataFrame, sp::SpatialPoints, sp::SpatialPointsDataFrame, sp::SpatialPolygons and sp::SpatialPolygonsDataFrame, plus the raster classes RasterBrick, RasterCommon, RasterLayer and RasterStack. Also present are the lfda methods for the linear Fisher discriminant analysis package, splines::basis, and a few more.
Two annotations appear in the list and they carry meaning. base::table supports fortify only, and a handful of entries are marked as inference, which tells you the method is there for a diagnostic view rather than a full plot. The coverage is broad enough that most common modelling workflows are covered, and the class list is the thing to read before assuming a gap.
Helper functions for distributions and time series diagnostics
Beyond the generic methods, the package ships a handful of named helpers that plot things which are not model results in the usual sense.
The list is four entries. ggdistribution plots a PDF or a CDF. ggcpgram plots a cpgram, which is the cumulative periodogram used to look at the period structure of a time series. ggtsdiag plots a tsdiag, which is the diagnostic output of the time series fitting functions. And ggfreqplot generalises monthplot, the seasonal frequency plot.
The naming pattern is deliberate. Where the automatic methods are called autoplot because they attach themselves to a class, these helpers are called gg followed by the name of the thing being plotted, and they are called directly rather than dispatched. That distinction matters in practice: autoplot on a time series fit gives you the standard diagnostic panel, and ggtsdiag is the entry point when you want that panel from something the automatic path does not cover.
The frequency plot generalisation is the one with the clearest reason to exist. monthplot is a base R function with a fixed monthly framing, and a general version that takes the frequency as a parameter covers quarterly, weekly and daily seasonality, which is the kind of extension the vignette set suggests the package is built for.
The readme also links a set of vignettes hosted on CRAN that walk through the areas the package covers: concepts and basics, diagnostics for linear and generalized linear models, time series, PCA with clustering and LFDA and MDS, survival curves, probability distributions, and the autoplotly interactive generation. The probability distribution vignette is the natural place to look for how ggdistribution fits into the rest.
The package therefore has two layers. A wide, mechanical layer that adapts many classes, and a small hand written layer for the plots that do not come out of a model object.
Installation from CRAN or from the GitHub branch
Installation is the ordinary R two ways, and the development route is worth spelling out because it is the one that will get you the current code.
The stable release comes from CRAN.
install.packages('ggfortify')The development version comes from GitHub through the remotes package, and the snippet installs remotes first if it is missing.
if (!require("remotes")) install.packages("remotes")
remotes::install_github('sinhrks/ggfortify')A detail in that snippet is easy to miss and does matter. The install_github call is indented but is not inside braces or a function body, so in a plain interactive session the second line is a separate top level statement rather than a continuation of the if block. It works, because the first line only installs the package and the second line runs regardless, but if you paste it into a script and expect the if to guard the install, the guard does not exist.
The release history explains why the distinction matters. The recent versions are v0.4.24 on 2026-09-30, v0.4.23 on 2026-09-06 and v0.4.22 on 2026-08-20, so there have been three patch releases in six weeks. A package that patches this often is usually reacting to upstream changes in the modelling packages it supports, which means the CRAN version and the GitHub version can behave differently on the same model object.
The repository also carries a NEWS.md file and a cran-comments.md file, which is where you would look for what actually changed between versions. The vignette set is linked from the readme rather than from the package index, so the CRAN vignette pages are the reliable source for the current documentation.
One maintainer, a custom licence and a broad surface to keep in step
The maintenance story is the thing to weigh, and the readme puts it up front in a note. The package has been maintained by @terrytangyuan since 2015, and the note asks people to consider sponsoring that work. There is no second maintainer named and no team structure described, so the sustainability of the project is the sustainability of one person.
The licence is the other thing to check. The repository is recorded as carrying a licence that GitHub cannot classify, and the pointer to the LICENSE file is the only way to know the terms. For a package on CRAN, that is unusual, and it means you should read the file before you bundle ggfortify into a commercial analysis pipeline, redistribute it, or use it in a product. This review does not interpret the terms, and any conclusion about what the licence permits needs advice from someone qualified.
The third factor is the width of the surface. A method for each of roughly seventy classes means a method for each of the packages that own those classes. When forecast changes the structure of a forecast object, or glmnet changes the return of cv.glmnet, or sp reorganises its spatial classes, ggfortify has to follow. The patch release cadence points to exactly that kind of work, and it is the reason the upstream dependencies are part of the risk profile of the package.
The comparison to consider is the tidy data approach, where a model result is converted into a plain data frame and the plotting is left entirely to ggplot2 and whatever extensions you already use. The difference in approach is exactly the design choice. ggfortify gives you a finished plot in one call and a uniform look across model types, at the price of being tied to the shapes those objects had when the methods were written. A tidy approach gives you data you can plot however you like, at the price of doing the plotting yourself.
The other comparison is the interactive route. The autoplotly package described in the readme builds on ggfortify to produce plotly.js visualisations that stay interactive while remaining extendable with ggplot2 syntax. If your requirement is an interactive chart rather than a static one, that is the path, and it is built on the same foundation rather than replacing it.
Editorial conclusion
ggfortify suits an R user who wants diagnostic and fitted plots from a model object in one call rather than by hand, and it does not suit someone who needs a plot type the package does not cover or a method that returns only a data frame without a plot, because fortify and autoplot are separate contracts and only some classes implement both. Before you depend on it, read the LICENSE file, since the repository carries a custom licence that GitHub cannot classify, and check whether your version of the modelling package still returns the class ggfortify recognises, because the release list shows frequent patches against upstream changes.
Frequently asked questions
What is ggfortify and what problem does it solve?
ggfortify defines fortify and autoplot functions so that ggplot2 can automatically visualise the statistical result of popular R packages. fortify turns a result into a plain data frame and autoplot returns a ggplot object you can still modify.
How do I install ggfortify?
Install the stable release from CRAN with install.packages('ggfortify'), or the development version with remotes::install_github('sinhrks/ggfortify') after installing remotes.
Which R packages does ggfortify support?
The coverage list spans base classes such as matrix and table, and results from cluster, changepoint, fGarch, forecast, fracdiff, glmnet, KFAS, lfda, maps, MASS, raster, ROCR, sp, splines, stats, survival, strucchange, timeSeries, tseries, vars, xts and zoo.
What are the helper functions in ggfortify?
There are four: ggdistribution to plot a PDF or CDF, ggcpgram to plot a cpgram, ggtsdiag to plot a tsdiag, and ggfreqplot to generalise monthplot for seasonal frequency plots.
Can ggfortify produce interactive plots?
Not directly. The readme points to the autoplotly package, which automatically generates interactive visualisations in a plotly.js style based on ggfortify, and the generated charts can still be extended with ggplot2 syntax.
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/sinhrks-ggfortify)Was this useful?