The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Publication-ready correlation plots

Alboukadel Kassambara

This is a gallery of finished figures — each with the code that produces it — for the kinds of correlograms that show up in papers. For the argument-by-argument tour of every option, see vignette("ggcorrplot").

Two facts make ggcorrplot well suited to publication work: it takes a correlation matrix you already have (so it never gets between you and your statistics), and it returns a plain ggplot object, so any figure here can be restyled, titled, and combined with +.

library(ggcorrplot)
library(ggplot2)

data(mtcars)
corr <- round(cor(mtcars), 1)
p.mat <- cor_pmat(mtcars)

The clustered correlogram

The workhorse figure: reorder the variables by hierarchical clustering so correlated variables sit together and the block structure is visible, and draw thin white separators between cells.

ggcorrplot(corr, hc.order = TRUE, outline.color = "white")

Lower triangle with coefficients

For a symmetric matrix the two triangles are redundant, so a paper usually shows one, often with the coefficients printed in the cells — a figure that replaces a correlation table.

ggcorrplot(corr, hc.order = TRUE, type = "lower", lab = TRUE, lab_size = 3)

Marking significance

Supply the p-value matrix from cor_pmat() and choose how to convey significance. insig = "blank" drops the non-significant cells; insig = "stars" instead marks the significant ones with */**/*** — a standalone significance map.

# non-significant cells left blank
ggcorrplot(corr, hc.order = TRUE, type = "lower", p.mat = p.mat, insig = "blank")
# significant cells starred
ggcorrplot(corr, p.mat = p.mat, insig = "stars")

The default, insig = "pch", crosses out the non-significant cells with an X instead.

Circles for magnitude

method = "circle" encodes the correlation with the circle’s area, so strong correlations pop out — the familiar corrplot look, drawn in ggplot2.

ggcorrplot(corr, method = "circle", hc.order = TRUE, type = "upper", outline.color = "white")

Size-scaled squares

scale.square = TRUE sizes the squares by the absolute correlation, so magnitude is encoded by both area and color at once — the classic corrplot square look. Near-zero cells shrink to small squares while the strong correlations dominate, which reads well for large matrices and for colorblind viewers.

ggcorrplot(corr, scale.square = TRUE, hc.order = TRUE, outline.color = "white")

corrplot-style boxed cells

cell.grid = TRUE draws a light rectangle around every cell and drops the gridlines that otherwise run through the glyph centers, so each sized glyph sits inside its own box. Combined with scale.square = TRUE (or method = "circle") this is the boxed-cell corrplot signature, drawn in ggplot2. It has no effect on a plain full-tile square heatmap, whose cells already have a border.

# size-scaled squares in boxed cells
ggcorrplot(corr, scale.square = TRUE, cell.grid = TRUE, hc.order = TRUE, outline.color = "white")
# circles in boxed cells
ggcorrplot(corr, method = "circle", cell.grid = TRUE, hc.order = TRUE)

A colorblind-safe palette

preset = "publication" is a one-token beautiful default (white separators + the colorblind-safe RdBu palette). For a specific journal look, set colors and ggtheme yourself.

# one-token publication preset
ggcorrplot(corr, hc.order = TRUE, preset = "publication")
# a custom diverging palette on a minimal theme
ggcorrplot(corr,
  hc.order = TRUE, type = "lower", outline.color = "white",
  ggtheme = theme_minimal, colors = c("#6D9EC1", "white", "#E46726")
)

A clean, edgeless heatmap

A correlogram of solid colored squares with no cell border — the look used in many module–trait and omics papers. method = "square" is a full-tile heatmap; outline.color = NA removes the border. Reverse the default gradient to c("red", "white", "blue") for red-negative / blue-positive, and put the variable names on top with a one-line scale.

ggcorrplot(corr,
  outline.color = NA,
  colors = c("red", "white", "blue"),
  legend.title = "Correlation"
) +
  scale_x_discrete(position = "top")

A rectangular predictor-by-outcome matrix

Correlations are not always a square symmetric matrix. To relate one set of variables to another — say engine/size variables against performance variables — pass a rectangular correlation matrix. Clustering and the triangle options need a square matrix, so use hc.order = FALSE.

rect <- round(cor(
  mtcars[, c("mpg", "hp", "wt", "qsec")],
  mtcars[, c("disp", "drat", "vs", "am", "gear")]
), 1)
ggcorrplot(rect, hc.order = FALSE, lab = TRUE, outline.color = "white")

Going further: it is a ggplot

Because ggcorrplot() returns a ggplot object, anything ggplot2 can do is available. Start from any correlogram and add a title, a clearer legend label, and theme tweaks; then save at print resolution.

The legend label is a ggcorrplot argument (legend.title); the title, subtitle and theme come from ggplot2.

p <- ggcorrplot(corr,
  hc.order = TRUE, type = "lower", outline.color = "white",
  legend.title = "Pearson r"
) +
  labs(
    title = "Correlations among car-design variables",
    subtitle = "mtcars, Pearson correlation"
  ) +
  theme(plot.title = element_text(face = "bold"))
p

ggsave("correlogram.png", p, width = 7, height = 6, dpi = 300)

Session information

sessionInfo()
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.6.1
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib 
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1
#> 
#> locale:
#> [1] C/fr_FR.UTF-8/fr_FR.UTF-8/C/fr_FR.UTF-8/fr_FR.UTF-8
#> 
#> time zone: Europe/Paris
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] ggcorrplot_0.3.0 ggplot2_4.0.3   
#> 
#> loaded via a namespace (and not attached):
#>  [1] gtable_0.3.6       jsonlite_2.0.0     dplyr_1.2.1        compiler_4.5.1    
#>  [5] tidyselect_1.2.1   Rcpp_1.1.1         stringr_1.6.0      jquerylib_0.1.4   
#>  [9] scales_1.4.0       yaml_2.3.12        fastmap_1.2.0      R6_2.6.1          
#> [13] plyr_1.8.9         labeling_0.4.3     generics_0.1.4     knitr_1.51        
#> [17] tibble_3.3.1       bslib_0.10.0       pillar_1.11.1      RColorBrewer_1.1-3
#> [21] rlang_1.2.0        cachem_1.1.0       stringi_1.8.7      xfun_0.57         
#> [25] sass_0.4.10        S7_0.2.1           otel_0.2.0         cli_3.6.6         
#> [29] withr_3.0.2        magrittr_2.0.4     digest_0.6.39      grid_4.5.1        
#> [33] lifecycle_1.0.5    vctrs_0.7.2        evaluate_1.0.5     glue_1.8.0        
#> [37] farver_2.1.2       reshape2_1.4.5     rmarkdown_2.31     tools_4.5.1       
#> [41] pkgconfig_2.0.3    htmltools_0.5.9

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.