├── .Rbuildignore ├── .github └── workflows │ ├── R-CMD-check.yml │ └── test-coverage.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── colorlegend.R ├── colors.R ├── cor-mtest.R ├── corrMatOrder.R ├── corrRect.R ├── corrRect.hclust.R ├── corrplot-package.R ├── corrplot.R └── corrplot.mixed.R ├── README.md ├── codecov.yml ├── corrplot.Rproj ├── inst ├── CITATION └── NEWS ├── man ├── col1.Rd ├── col2.Rd ├── colorlegend.Rd ├── cor.mtest.Rd ├── corrMatOrder.Rd ├── corrRect.Rd ├── corrRect.hclust.Rd ├── corrplot-package.Rd ├── corrplot.Rd └── corrplot.mixed.Rd ├── tests ├── testthat.R └── testthat │ ├── test-colorlegend.R │ ├── test-cor-mtest.R │ ├── test-corrRect.R │ └── test-corrplot.R └── vignettes ├── .DS_Store ├── corrplot-intro.Rmd ├── example-colorlegend.R ├── example-corrMatOrder.R ├── example-corrRect.R ├── example-corrRect.hclust.R ├── example-corrplot.R ├── example-corrplot.mixed.R └── webimg └── rectangles-1.png /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | ^\.lintr$ 5 | ^\.github$ 6 | ^vignettes/webimg 7 | ^codecov\.yml$ 8 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yml: -------------------------------------------------------------------------------- 1 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 2 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | pull_request: 9 | branches: 10 | - main 11 | - master 12 | 13 | name: R-CMD-check 14 | 15 | jobs: 16 | R-CMD-check: 17 | runs-on: ${{ matrix.config.os }} 18 | 19 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | config: 25 | - {os: windows-latest, r: 'release'} 26 | - {os: macOS-latest, r: 'release'} 27 | - {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} 28 | 29 | env: 30 | R_REMOTES_NO_ERRORS_FROM_WARNINGS: true 31 | RSPM: ${{ matrix.config.rspm }} 32 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 33 | 34 | steps: 35 | - uses: actions/checkout@v2 36 | 37 | - uses: r-lib/actions/setup-r@v1 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | 41 | - uses: r-lib/actions/setup-pandoc@v1 42 | 43 | - name: Query dependencies 44 | run: | 45 | install.packages('remotes') 46 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 47 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 48 | shell: Rscript {0} 49 | 50 | - name: Restore R package cache 51 | if: runner.os != 'Windows' 52 | uses: actions/cache@v2 53 | with: 54 | path: ${{ env.R_LIBS_USER }} 55 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 56 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 57 | 58 | - name: Install system dependencies 59 | if: runner.os == 'Linux' 60 | run: | 61 | while read -r cmd 62 | do 63 | eval sudo $cmd 64 | done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') 65 | 66 | - name: Install dependencies 67 | run: | 68 | remotes::install_deps(dependencies = TRUE) 69 | remotes::install_cran("rcmdcheck") 70 | shell: Rscript {0} 71 | 72 | - name: Check 73 | env: 74 | _R_CHECK_CRAN_INCOMING_REMOTE_: false 75 | run: | 76 | options(crayon.enabled = TRUE) 77 | rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 78 | shell: Rscript {0} 79 | 80 | - name: Upload check results 81 | if: failure() 82 | uses: actions/upload-artifact@main 83 | with: 84 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 85 | path: check 86 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | - master 6 | 7 | name: test-coverage 8 | 9 | jobs: 10 | test-coverage: 11 | runs-on: windows-latest 12 | env: 13 | GITHUB_PAT: ${{ secrets.CODECOV_TOKEN }} 14 | # don't treat missing suggested packages as error 15 | _R_CHECK_FORCE_SUGGESTS_: false 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - uses: r-lib/actions/setup-r@v1 20 | 21 | - uses: r-lib/actions/setup-pandoc@v1 22 | 23 | - name: Query dependencies 24 | run: | 25 | install.packages('remotes') 26 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 27 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 28 | shell: Rscript {0} 29 | 30 | - name: Cache R packages 31 | uses: actions/cache@v2 32 | with: 33 | path: ${{ env.R_LIBS_USER }} 34 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 35 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 36 | 37 | - name: Install dependencies 38 | run: | 39 | install.packages(c("remotes")) 40 | remotes::install_deps(dependencies = TRUE) 41 | remotes::install_cran("covr") 42 | shell: Rscript {0} 43 | 44 | - name: Test coverage 45 | run: covr::codecov() 46 | shell: Rscript {0} 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .lintr 5 | vignettes/webimg/ 6 | inst/doc/ 7 | #!vignettes/webimg/rectangles-1.png 8 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: corrplot 2 | Type: Package 3 | Title: Visualization of a Correlation Matrix 4 | Version: 0.95 5 | Date: 2024-10-14 6 | Authors@R: c( 7 | person('Taiyun', 'Wei', email = 'weitaiyun@gmail.com', role = c('cre', 'aut')), 8 | person('Viliam', 'Simko', email = 'viliam.simko@gmail.com', role = 'aut'), 9 | person('Michael', 'Levy', email = 'michael.levy@healthcatalyst.com', role = 'ctb'), 10 | person('Yihui', 'Xie', email = 'xie@yihui.name', role = 'ctb'), 11 | person('Yan', 'Jin', email = 'jyfeather@gmail.com', role = 'ctb'), 12 | person('Jeff', 'Zemla', email = 'zemla@wisc.edu', role = 'ctb'), 13 | person('Moritz', 'Freidank', email = 'freidankm@googlemail.com', role = 'ctb'), 14 | person('Jun', 'Cai', email = 'cai-j12@mails.tsinghua.edu.cn', role = 'ctb'), 15 | person('Tomas', 'Protivinsky', email = 'tomas.protivinsky@gmail.com', role = 'ctb') 16 | ) 17 | Maintainer: Taiyun Wei 18 | Suggests: 19 | seriation, 20 | knitr, 21 | RColorBrewer, 22 | rmarkdown, 23 | magrittr, 24 | prettydoc, 25 | testthat 26 | Description: Provides a visual exploratory tool on correlation matrix that supports automatic variable reordering to help detect hidden patterns among variables. 27 | License: MIT + file LICENSE 28 | URL: https://github.com/taiyun/corrplot 29 | BugReports: https://github.com/taiyun/corrplot/issues 30 | VignetteBuilder: knitr 31 | RoxygenNote: 7.2.1 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2010-2024 2 | COPYRIGHT HOLDER: Capital of Statistics, http://cosx.org/ 3 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(COL1) 4 | export(COL2) 5 | export(colorlegend) 6 | export(cor.mtest) 7 | export(corrMatOrder) 8 | export(corrRect) 9 | export(corrRect.hclust) 10 | export(corrplot) 11 | export(corrplot.mixed) 12 | import(grDevices) 13 | import(graphics) 14 | import(stats) 15 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # corrplot 0.95 2 | 3 | ## Changes 4 | 5 | * Fix #279: Version 0.94 is not assigning significant ocurrences correctly. (thanks, @brenoliisboa and @david-priest) 6 | 7 | 8 | # corrplot 0.94 9 | 10 | ## Changes 11 | 12 | * Fix #275: format correlations with `nsmall = number.digits`. (thanks, @the-mad-statter) 13 | 14 | 15 | # corrplot 0.93 16 | 17 | ## Changes 18 | 19 | * Fix #247: `addgrid.col` and `bg` don't work in mixed plot. (thanks, @ZoomMan91) 20 | * Fix #246: using `insig = "n"` and `p.mat` sometimes causes an error. (thanks, @Sumidu) 21 | * Fix #255: add new parameter `transKeepSign`, whether or not to keep matrix values' sign when transforming non-corr matrix. 22 | 23 | # corrplot 0.92 24 | 25 | ## Changes 26 | 27 | * Fix #228: assigning colors incorrectly when `is.corr = FALSE`. (thanks, @bixiou) 28 | * Fix #232: some functions wrongly marked as pure. 29 | * Fix colorlegend lables alignment when `type = 'lower'`. 30 | * Revise the document. 31 | 32 | # corrplot 0.91 33 | 34 | ## Changes 35 | 36 | * `tl.pos` add a new parameter `'l'` in `corrplot()`. (thanks, @ggordn3r) 37 | * Add new function `COL1()`: Get sequential colors. 38 | * Add new function `COL2()`: Get diverging colors. 39 | 40 | 41 | # corrplot 0.90 42 | 43 | ## Changes 44 | 45 | * Add customizable rectangles to correlation plots in `corrRect()`.(#185, requirements from @douglaswhitaker thanks). 46 | * Remove `clus`; add `index` and `name` parameters in `corrRect()`. 47 | * Add `xName`, `yName` two columns in `corrPos` data frame(e.g. `corrplot(...)$corrPos`). 48 | * Rename parameter `cl.lim` to `col.lim` in `corrplot()`. 49 | * Add `arg` to the `corrplot()` return list. 50 | * Add pipe operator `|>` examples when using corrRect(). 51 | * Set 'seriation' as Suggests package, and add examples in the document. 52 | * Parameter `number.digits` also works on p-value. (thanks, @bassam-abulnoor) 53 | * Revise the document. (thanks, Shuai Huang) 54 | 55 | 56 | # corrplot 0.89 57 | 58 | ## Changes 59 | * Change the return value of corrplot() and corrplot.mixed() from matrix `corr` to `list(corr, corrPos)` 60 | * Fix #177: the top margin is too small when parameter `type` is 'lower' or 'upper'. (thanks, @lijian13) 61 | * Parameter `addCoef.col` works prior to parameter `insig` 62 | * Revise the document 63 | 64 | 65 | 66 | # corrplot 0.88 67 | 68 | ## Changes 69 | * Revise the document 70 | * Remove full_col and fix #152 #157 #165 #166 71 | * Fix #150 in document, it should be the arcus tangens functions. (thanks, @surmann) 72 | * Change vignette engine from 'knitr::knitr' to 'knitr::rmarkdown' 73 | * Use 'prettydoc' package creating vignettes 74 | * Set 'rmarkdown' and 'prettydoc' as Suggests packages 75 | 76 | 77 | # corrplot 0.87 78 | 79 | ## Changes 80 | * Change to the MIT license 81 | * Fix #142: NA issues when cl.lim is supplied. (thanks, @AlexChristensen) 82 | 83 | 84 | # corrplot 0.83 85 | 86 | ## Changes 87 | * CITATION now uses fields from DESCRIPTION 88 | * RColorBrewer is now a suggested package (not required) 89 | 90 | ## New features 91 | * Fixed #99 : A new option insig = 'label_sig' to mark significant correlations. 92 | 93 | # corrplot 0.82 94 | 95 | ## Bug fixes 96 | * Fixed #10: corrplot with type = 'upper' and long colname strings cuts off top labels 97 | * Fixed #19: Color Legend has 0 width when only 1 column is used 98 | * Fixed #70: NA errors when is.corr = F 99 | * Fixed #77: Error when the matrix(corr) contains NA values. 100 | 101 | ## New features 102 | * Fixed #18: title position and pie corrplot background circle.Used existing parameter `outline` to control the border color of pie symbols. 103 | * Fixed #66: `lim.segment` parameter default value. Added default value 'auto' for `lim.segment` parameter 104 | * Fixed #76: corrplot.mixed with black color correlation coefficient.Added two new parameters `lower.col` and `upper.col` 105 | * Fixed #79: Changing aspect ratio for the plot.Added a new parameter `win.asp` which controls the aspect ratio of the plotted matrix. 106 | * Added more examples to the vignette 107 | 108 | # corrplot 0.81 109 | 110 | ## Changes 111 | * Fixed #79: added parameter `win.asp` to control aspect ratio 112 | * Fixed #18: parameter `outline` combined with `method='pie'` controls 113 | the color of the otline circle of each pie. 114 | * updated vignette 115 | 116 | # corrplot 0.80 117 | 118 | ## Changes 119 | * Fixed #70: Enable to plot a matrix with NA when 'is.corr = F' 120 | 121 | # corrplot 0.77 122 | 123 | ## Changes 124 | * Fixed #58: make sure the margin is correct in corrplot.mixed(). 125 | * Revised document. 126 | 127 | # corrplot 0.76 128 | 129 | ## Changes 130 | * In corrplot(), added parameters na.label and na.label.col that define how NA values inside a matrix should be rendered. 131 | * In corrplot(), na.label can now use one or two characters, default is '?' (issue #55) 132 | * Fixed #16: checks for [-1, 1] interval are too strict. 133 | * Fixed #15: error with correlation plot using insig argument when all values are significant. 134 | * Fixed #9: added ward.D and ward.D2 hclust methods (thanks, #jeffzemla) 135 | 136 | # corrplot 0.70 137 | 138 | ## Changes 139 | * In corrplot(), parameter insig add a option 'p-value', now p-values can be conveniently added on the glyph. 140 | * Return value changes, corrplot() now returns a reordered correlation matrix. 141 | 142 | # corrplot 0.66 143 | 144 | ## Changes 145 | * Add html vignette, which was generated from markdown file by knitr. 146 | * In corrplot(), remove parameter 'zoom', add 'is.corr'; now it is more convenient to 147 | visualize non-correlation matrix. Parameter 'addtextlabel' was renamed as 'tl.pos', 148 | and 'addcolorlabel' was renamed as 'cl.pos'. 149 | 150 | # corrplot 0.60 151 | 152 | ## New features 153 | * Now corrplot() can deal with the matrix not in [-1,1] by parameter 'zoom' now. 154 | Warning: please make sure the visualization you take after data zoom is meaningful! 155 | 156 | ## Changes 157 | * Function corr.rect() was renamed as corrRect(). 158 | * Revise document. (THANKS, Tao Gao) 159 | * In function corrplot(), 'order''s choice 'PCA' was precisely renamed as 'AOE'. 160 | and 'FPC' was added for the first principal component order. 161 | * Add function corrMatOrder(), and corrplot.mixed(). 162 | * Remove seldom used functions: corrplot.circle(), corrplot.ellipse(), 163 | corrplot.square(), corrplot.shade(), corrplot.color(), corrplot.number(). 164 | * In corrplot(), remove parameter 'assign.col' and 'cl.range', 165 | add 'zoom', 'cl.lim' and 'addCoefasPercent'. 166 | 167 | # corrplot 0.54 168 | 169 | ## Changes 170 | * Parameter 'tl.cex' in function corrplot() is more sensitive. 171 | 172 | ## Bug fixes 173 | * The issue that too much space adding to the margins (especially using a longer text label 174 | or a larger font size) has been fixed. 175 | * Specifying wrong color to the glyphs has been fixed. 176 | -------------------------------------------------------------------------------- /R/colorlegend.R: -------------------------------------------------------------------------------- 1 | #' Draw color legend. 2 | #' 3 | #' @param colbar Vector, color of colbar. 4 | #' @param labels Vector, numeric or character to be written. 5 | #' @param at Numeric vector (quantile), the position to put labels. See examples 6 | #' for details. 7 | #' @param xlim See in \code{\link{plot}} 8 | #' @param ylim See in \code{\link{plot}} 9 | #' @param vertical Logical, whether the colorlegend is vertical or horizon. 10 | #' @param ratio.colbar The width ratio of colorbar to the total colorlegend 11 | #' (including colorbar, segments and labels). 12 | #' @param lim.segment Vector (quantile) of length 2, the elements should be in 13 | #' [0,1], giving segments coordinates ranges. If the value is NULL or 'auto', 14 | #' then the ranges are derived automatically. 15 | #' @param align Character, alignment type of labels, \code{'l'} means left, 16 | #' \code{'c'} means center and \code{'r'} right. 17 | #' Only valid when \code{vertical} is \code{TRUE}. 18 | #' @param addlabels Logical, whether add text label or not. 19 | #' @param \dots Additional arguments, passed to \code{\link{plot}} 20 | #' 21 | #' @example vignettes/example-colorlegend.R 22 | #' @keywords hplot 23 | #' @author Taiyun Wei 24 | #' @export 25 | colorlegend = function( 26 | colbar, 27 | labels, 28 | at = NULL, 29 | xlim = c(0, 1), 30 | ylim = c(0, 1), 31 | vertical = TRUE, 32 | ratio.colbar = 0.4, 33 | lim.segment = 'auto', # NOTE: NULL treated as 'auto' 34 | align = c('c', 'l', 'r'), 35 | addlabels = TRUE, 36 | ...) 37 | { 38 | 39 | if (is.null(at) && addlabels) { 40 | at = seq(0L, 1L, length = length(labels)) 41 | } 42 | 43 | if (any(is.null(lim.segment)) || any(lim.segment == 'auto')) { 44 | lim.segment = ratio.colbar + c(0, ratio.colbar * .2) 45 | } 46 | 47 | if (any(at < 0L) || any(at > 1L)) { 48 | stop('at should be between 0 and 1') 49 | } 50 | 51 | if (length(lim.segment) != 2) { 52 | stop('lim.segment should be a vector of length 2') 53 | } 54 | 55 | if (any(lim.segment < 0L) || any(lim.segment > 1L)) { 56 | stop('lim.segment should be between 0 and 1') 57 | } 58 | 59 | align = match.arg(align) 60 | xgap = diff(xlim) 61 | ygap = diff(ylim) 62 | len = length(colbar) 63 | rat1 = ratio.colbar 64 | rat2 = lim.segment 65 | 66 | if (vertical) { 67 | 68 | at = at * ygap + ylim[1] 69 | yyy = seq(ylim[1], ylim[2], length = len + 1) 70 | 71 | rect(rep(xlim[1], len), yyy[1:len], 72 | rep(xlim[1] + xgap * rat1, len), yyy[-1], 73 | col = colbar, border = colbar) 74 | rect(xlim[1], ylim[1], xlim[1] + xgap * rat1, ylim[2], border = 'black') 75 | segments(xlim[1] + xgap * rat2[1], at, xlim[1] + xgap * rat2[2], at) 76 | 77 | if (addlabels) { 78 | pos.xlabel = rep(xlim[1] + xgap * max(rat2, rat1), length(at)) 79 | 80 | if(align == 'l') { 81 | text(pos.xlabel, y = at, labels = labels, pos = 4, ...) 82 | } 83 | 84 | if(align == 'r') { 85 | text(xlim[2], y = at, labels = labels, pos = 2, ...) 86 | } 87 | 88 | if(align == 'c') { 89 | text((pos.xlabel + xlim[2]) / 2, y = at, labels = labels, ...) 90 | } 91 | } 92 | } else { 93 | 94 | at = at * xgap + xlim[1] 95 | xxx = seq(xlim[1], xlim[2], length = len + 1) 96 | 97 | rect(xxx[1:len], rep(ylim[2] - rat1 * ygap, len), 98 | xxx[-1], rep(ylim[2], len), 99 | col = colbar, border = colbar) 100 | rect(xlim[1], ylim[2] - rat1 * ygap, xlim[2], ylim[2], border = 'black') 101 | segments(at, ylim[2] - ygap * rat2[1], at, ylim[2] - ygap * rat2[2]) 102 | 103 | if (addlabels) { 104 | pos.ylabel = rep(ylim[2] - ygap * max(rat2, rat1), length(at)) 105 | text(x = at, y = pos.ylabel, labels = labels, pos = 1, ...) 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /R/colors.R: -------------------------------------------------------------------------------- 1 | #' Get diverging colors 2 | #' 3 | #' Get diverging colors from palette theme name and n. The color palettes 4 | #' are from RColorBrewer, but with the middle color changing to '#FFFFFF'(white), 5 | #' thus we can visualize element 0 with white color. 6 | #' Diverging colors are suitable for visualize a matrix which elements are partly positive and 7 | #' partly negative (e.g. correlation matrix in [-1, 1], or [-20, 100]). 8 | #' 9 | #' @param diverging Diverging color Palettes 10 | #' @param n the number of colors (>= 1) to be in the palette. 11 | #' 12 | #' @return A character vector containing color names 13 | #' 14 | #' @seealso Function \code{\link{colorRampPalette}}, package \code{RColorBrewer} 15 | #' 16 | #' @keywords color 17 | #' @example vignettes/example-colorlegend.R 18 | #' @export 19 | 20 | COL2 = function(diverging = c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu'), 21 | n = 200) { 22 | 23 | diverging = match.arg(diverging) 24 | 25 | colors = switch( 26 | diverging, 27 | RdBu = c('#67001F', '#B2182B', '#D6604D', '#F4A582', '#FDDBC7', '#FFFFFF', 28 | '#D1E5F0', '#92C5DE', '#4393C3', '#2166AC', '#053061'), 29 | BrBG = c('#543005', '#8C510A', '#BF812D', '#DFC27D', '#F6E8C3', '#FFFFFF', 30 | '#C7EAE5', '#80CDC1', '#35978F', '#01665E', '#003C30'), 31 | PiYG = c('#8E0152', '#C51B7D', '#DE77AE', '#F1B6DA', '#FDE0EF', '#FFFFFF', 32 | '#E6F5D0', '#B8E186', '#7FBC41', '#4D9221', '#276419'), 33 | PRGn = c('#40004B', '#762A83', '#9970AB', '#C2A5CF', '#E7D4E8', '#FFFFFF', 34 | '#D9F0D3', '#A6DBA0', '#5AAE61', '#1B7837', '#00441B'), 35 | PuOr = c('#7F3B08', '#B35806', '#E08214', '#FDB863', '#FEE0B6', '#FFFFFF', 36 | '#D8DAEB', '#B2ABD2', '#8073AC', '#542788', '#2D004B'), 37 | RdYlBu = c('#A50026', '#D73027', '#F46D43', '#FDAE61', '#FEE090', '#FFFFFF', 38 | '#E0F3F8', '#ABD9E9', '#74ADD1', '#4575B4', '#313695') 39 | ) 40 | 41 | return(colorRampPalette(colors)(n)) 42 | 43 | } 44 | 45 | #' Get sequential colors 46 | #' 47 | #' Get sequential colors from palette theme name and n. The color palettes 48 | #' are from RColorBrewer. Sequential colors are suitable for visualize a non-negative 49 | #' or non-positive matrix (e.g. matrix in [0, 20], or [-100, -10], or [100, 500]). 50 | #' 51 | #' @param sequential Sequential color Palettes 52 | #' @param n the number of colors (>= 1) to be in the palette. 53 | #' 54 | #' @return A character vector containing color names 55 | #' 56 | #' @seealso Function \code{\link{colorRampPalette}}, package \code{RColorBrewer} 57 | #' 58 | #' @keywords color 59 | #' @example vignettes/example-colorlegend.R 60 | #' @export 61 | 62 | 63 | COL1 = function(sequential = c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 64 | 'Greys', 'OrRd', 'YlOrRd', 'YlOrBr', 'YlGn'), 65 | n = 200) { 66 | 67 | sequential = match.arg(sequential) 68 | 69 | colors = switch( 70 | sequential, 71 | Oranges = c('#FFF5EB', '#FEE6CE', '#FDD0A2', '#FDAE6B', '#FD8D3C', '#F16913', 72 | '#D94801', '#A63603', '#7F2704'), 73 | Purples = c('#FCFBFD', '#EFEDF5', '#DADAEB', '#BCBDDC', '#9E9AC8', '#807DBA', 74 | '#6A51A3', '#54278F', '#3F007D'), 75 | Reds = c('#FFF5F0', '#FEE0D2', '#FCBBA1', '#FC9272', '#FB6A4A', '#EF3B2C', 76 | '#CB181D', '#A50F15', '#67000D'), 77 | Blues = c('#F7FBFF', '#DEEBF7', '#C6DBEF', '#9ECAE1', '#6BAED6', '#4292C6', 78 | '#2171B5', '#08519C', '#08306B'), 79 | Greens = c('#F7FCF5', '#E5F5E0', '#C7E9C0', '#A1D99B', '#74C476', '#41AB5D', 80 | '#238B45', '#006D2C', '#00441B'), 81 | Greys = c('#FFFFFF', '#F0F0F0', '#D9D9D9', '#BDBDBD', '#969696', '#737373', 82 | '#525252', '#252525', '#000000'), 83 | OrRd = c('#FFF7EC', '#FEE8C8', '#FDD49E', '#FDBB84', '#FC8D59', '#EF6548', 84 | '#D7301F', '#B30000', '#7F0000'), 85 | YlOrRd = c('#FFFFCC', '#FFEDA0', '#FED976', '#FEB24C', '#FD8D3C', '#FC4E2A', 86 | '#E31A1C', '#BD0026', '#800026'), 87 | YlOrBr = c('#FFFFE5', '#FFF7BC', '#FEE391', '#FEC44F', '#FE9929', '#EC7014', 88 | '#CC4C02', '#993404', '#662506'), 89 | YlGn = c('#FFFFE5', '#F7FCB9', '#D9F0A3', '#ADDD8E', '#78C679', '#41AB5D', 90 | '#238443', '#006837', '#004529') 91 | ) 92 | 93 | return(colorRampPalette(colors)(n)) 94 | 95 | } 96 | -------------------------------------------------------------------------------- /R/cor-mtest.R: -------------------------------------------------------------------------------- 1 | #' Significance test which produces p-values and confidence intervals for each 2 | #' pair of input features. 3 | #' 4 | #' @param mat Input matrix of size \code{NxF}, 5 | #' with \code{N} rows that represent samples 6 | #' and \code{F} columns that represent features. 7 | #' @param \dots Additional arguments passed to function \code{\link{cor.test}}, 8 | #' e.g. \code{conf.level = 0.95}. 9 | #' 10 | #' @return Return a list containing: 11 | #' \item{p}{Square matrix of size \code{FxF} with p-values as cells} 12 | #' \item{lowCI}{Square matrix of size \code{FxF}, each cell represents the 13 | #' \emph{lower part} of a confidence interval} 14 | #' \item{uppCI}{Square matrix of size \code{FxF}, each cell represents the 15 | #' \emph{upper part} of a confidence interval} 16 | #' 17 | #' @seealso Function \code{\link{cor.test}} 18 | #' 19 | #' @keywords p-value confidence significance 20 | #' @export 21 | cor.mtest = function(mat, ...) { 22 | mat = as.matrix(mat) 23 | n = ncol(mat) 24 | p.mat = lowCI.mat = uppCI.mat = matrix(NA, n, n) 25 | diag(p.mat) = 0 26 | diag(lowCI.mat) = diag(uppCI.mat) = 1 27 | for (i in 1:(n - 1)) { 28 | for (j in (i + 1):n) { 29 | 30 | tmp = cor.test(x = mat[, i], y = mat[, j], ...) 31 | p.mat[i, j] = p.mat[j, i] = tmp$p.value 32 | 33 | # only 'pearson' method provides confidence intervals 34 | if (!is.null(tmp$conf.int)) { 35 | lowCI.mat[i, j] = lowCI.mat[j, i] = tmp$conf.int[1] 36 | uppCI.mat[i, j] = uppCI.mat[j, i] = tmp$conf.int[2] 37 | } 38 | } 39 | } 40 | 41 | colnames(p.mat) = rownames(p.mat) = colnames(mat) 42 | colnames(lowCI.mat) = rownames(lowCI.mat) = colnames(mat) 43 | colnames(uppCI.mat) = rownames(uppCI.mat) = colnames(mat) 44 | 45 | list( 46 | p = p.mat, 47 | lowCI = lowCI.mat, 48 | uppCI = uppCI.mat 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /R/corrMatOrder.R: -------------------------------------------------------------------------------- 1 | #' Reorder a correlation matrix. 2 | #' 3 | #' Draw rectangle(s) around the chart of corrrlation matrix based on the number 4 | #' of each cluster's members. 5 | #' 6 | #' @param corr Correlation matrix to reorder. 7 | #' 8 | #' @param order Character, the ordering method for the correlation matrix. 9 | #' \itemize{ 10 | #' \item{\code{'AOE'} for the angular order of the eigenvectors. 11 | #' It is calculated from the order of the angles, \eqn{a_i}: 12 | #' \deqn{ a_i = arctan (e_{i2} / e_{i1}), if e_{i1} > 0} 13 | #' \deqn{ a_i = arctan (e_{i2} / e_{i1}) + \pi, otherwise.} 14 | #' where \eqn{e_1} and \eqn{e_2} are the largest two eigenvalues 15 | #' of matrix \code{corr}. 16 | #' See Michael Friendly (2002) for details.} 17 | #' \item{\code{'FPC'} for the first principal component order.} 18 | #' \item{\code{'hclust'} for hierarchical clustering order.} 19 | #' \item{\code{'alphabet'} for alphabetical order.} 20 | #' } 21 | #' 22 | #' @param hclust.method Character, the agglomeration method to be used when 23 | #' \code{order} is \code{hclust}. This should be one of \code{'ward'}, 24 | #' \code{'ward.D'}, \code{'ward.D2'}, \code{'single'}, \code{'complete'}, 25 | #' \code{'average'}, \code{'mcquitty'}, \code{'median'} or \code{'centroid'}. 26 | #' 27 | #' @return Returns a single permutation vector. 28 | #' 29 | #' @seealso Package \code{seriation} offers more methods to reorder matrices, 30 | #' such as ARSA, BBURCG, BBWRCG, MDS, TSP, Chen and so forth. 31 | #' 32 | #' @example vignettes/example-corrMatOrder.R 33 | #' @author Taiyun Wei 34 | #' @keywords hplot 35 | #' @export 36 | corrMatOrder = function( 37 | corr, 38 | order = c('AOE', 'FPC', 'hclust', 'alphabet'), 39 | hclust.method = c('complete', 'ward', 'ward.D', 'ward.D2', 'single', 40 | 'average', 'mcquitty', 'median', 'centroid')) 41 | { 42 | 43 | order = match.arg(order) 44 | hclust.method = match.arg(hclust.method) 45 | 46 | switch(order, 47 | AOE = reorder_using_aoe(corr), 48 | FPC = reorder_using_fpc(corr), 49 | hclust = reorder_using_hclust(corr, hclust.method), 50 | alphabet = sort(rownames(corr)) 51 | ) 52 | } 53 | 54 | #' Reorder the variables using the angular order of the eigenvectors. 55 | #' @noRd 56 | reorder_using_aoe = function(corr) { 57 | x.eigen = eigen(corr)$vectors[, 1:2] 58 | e1 = x.eigen[, 1] 59 | e2 = x.eigen[, 2] 60 | alpha = ifelse(e1 > 0, atan(e2 / e1), atan(e2 / e1) + pi) 61 | order(alpha) # returned vector 62 | } 63 | 64 | #' Reorder the variables using the first principal component. 65 | #' @noRd 66 | reorder_using_fpc = function(corr) { 67 | x.eigen = eigen(corr)$vectors[, 1:2] 68 | e1 = x.eigen[, 1] 69 | order(e1) # returned vector 70 | } 71 | 72 | #' Reorder the variables using hclust (Hierarchical Clustering). 73 | #' @noRd 74 | reorder_using_hclust = function(corr, hclust.method) { 75 | hc = hclust(as.dist(1 - corr), method = hclust.method) 76 | order.dendrogram(as.dendrogram(hc)) # returned vector 77 | } 78 | -------------------------------------------------------------------------------- /R/corrRect.R: -------------------------------------------------------------------------------- 1 | #' Draw rectangle(s) on the correlation matrix graph. 2 | #' 3 | #' Draw rectangle(s) after the correlation matrix plotted. SUGGESTION: It's more convenient 4 | #' to draw rectangle(s) by using pipe operator `|>` since R 4.1.0. 5 | #' 6 | #' \code{corrRect} needs one of \code{index}, \code{name} and \code{namesMat} inputted. 7 | #' While \code{corrRect.hclust} can get the members in each cluster 8 | #' based on hierarchical clustering (\code{\link{hclust}}). 9 | #' 10 | #' @param corrRes List of the \code{corrplot()} returns. 11 | #' @param index Vector, variable index of diag rect \code{c(Rect1from, Rect2from, 12 | #' Rect3from, ..., RectNto)} on the correlation matrix graph. 13 | #' It works when the colnames are the same as rownames, or both of them is NULL. 14 | #' It needs \code{corrRes} inputted. 15 | #' @param name Vector, variable name of diag rect \code{c(Rect1from, Rect2from, 16 | #' Rect3from, ..., RectNto)} on the correlation matrix graph. 17 | #' OIt works when the colnames are the same as rownames. 18 | #' It needs \code{corrRes} inputted. 19 | #' @param namesMat 4-length character vector or 4-columns character matrix, 20 | #' represents the names of xleft, ybottom, xright, ytop correspondingly. 21 | #' It needs \code{corrRes} inputted. 22 | #' @param col Color of rectangles. 23 | #' @param lwd Line width of rectangles. 24 | #' @param \dots Additional arguments passing to function \code{rect()}. 25 | #' 26 | #' @return (Invisibly) returns input parameter \code{corrRes}, 27 | #' usually \code{list(corr, corrTrans, arg)}. 28 | #' 29 | #' @example vignettes/example-corrRect.R 30 | #' @keywords hplot 31 | #' @author Taiyun Wei 32 | #' @export 33 | corrRect = function(corrRes = NULL, index = NULL, name = NULL, namesMat = NULL, 34 | col = 'black', lwd = 2, ...) 35 | { 36 | 37 | if((as.integer(!is.null(index)) + as.integer(!is.null(name)) + 38 | as.integer(!is.null(namesMat))) > 1) { 39 | stop('You should just input one of index, name and namesMat!') 40 | } 41 | 42 | if(is.null(corrRes)|!is.list(corrRes)) { 43 | stop('List \'corrRes\' must be inputted!') 44 | } 45 | 46 | corr = corrRes$corr 47 | corrPos = corrRes$corrPos 48 | type = corrRes$arg$type 49 | 50 | cName = colnames(corr) 51 | rName = rownames(corr) 52 | 53 | if(!is.null(name)) { 54 | 55 | if(any(cName != rName)) { 56 | stop('colnames and rownames must be same when index or name is inputted!') 57 | } 58 | 59 | 60 | if(!all(name %in% cName)) { 61 | stop('Non-existent name found!') 62 | } 63 | 64 | index = unlist(lapply(name, function(n) which(cName==n))) 65 | } 66 | 67 | 68 | 69 | if(!is.null(index)) { 70 | 71 | if(any(cName != rName)) { 72 | stop('colnames and rownames must be same when index or name is inputted!') 73 | } 74 | 75 | 76 | n = length(index) 77 | index[-n] = index[-n] - 1 78 | 79 | x1 = index[-n] + 0.5 80 | y1 = nrow(corr) - index[-n] + 0.5 81 | x2 = index[-1] + 0.5 82 | y2 = nrow(corr) - index[-1] + 0.5 83 | St = S = cbind(c(x1, x1, x2, x2), c(y1, y1, y2, y2), 84 | c(x2, x1, x2, x1), c(y1, y2, y1, y2)) 85 | St[, 2] = abs(St[, 2] - nrow(corr) - 1) 86 | St[, 4] = abs(St[, 4] - nrow(corr) - 1) 87 | 88 | if(type=='upper') { 89 | i = which((St[, 1] - St[, 2]) > -0.1 & (St[, 3] - St[, 4]) > -0.1) 90 | S = S[i, ] 91 | } 92 | 93 | if(type=='lower') { 94 | i = which((St[, 2] - St[, 1]) > -0.1 & (St[, 4] - St[, 3]) > -0.1) 95 | S = S[i, ] 96 | } 97 | 98 | segments(S[, 1], S[, 2], S[, 3], S[, 4], col = col, lwd = lwd, ...) 99 | } 100 | 101 | if(!is.null(namesMat)) { 102 | 103 | if(is.vector(namesMat)) { 104 | namesMat = matrix(namesMat, ncol = 4, nrow = 1) 105 | } 106 | 107 | xy1 = getCharXY(namesMat[, 1:2, drop=FALSE], corrPos) 108 | xy2 = getCharXY(namesMat[, 3:4, drop=FALSE], corrPos) 109 | 110 | xy = cbind(xy1, xy2) 111 | 112 | x1 = apply(xy[, c(1, 3), drop=FALSE], 1, min) - 0.5 113 | y1 = apply(xy[, c(2, 4), drop=FALSE], 1, min) - 0.5 114 | x2 = apply(xy[, c(1, 3), drop=FALSE], 1, max) + 0.5 115 | y2 = apply(xy[, c(2, 4), drop=FALSE], 1, max) + 0.5 116 | 117 | rect(x1, y1, x2, y2, border = col, lwd = lwd, ...) 118 | } 119 | 120 | invisible(corrRes) 121 | 122 | } 123 | 124 | 125 | #' @noRd 126 | getCharXY = function(x, dat) { 127 | 128 | res = apply(x, 1, function(n, d=dat) d[d[, 1]==n[1]&d[, 2]==n[2], 3:4]) 129 | 130 | f = which(unlist(lapply(res, nrow))==0) 131 | if(length(f) > 0) { 132 | error = paste(toString(unique(x[f, ])), 'paired X-Y names were not found!') 133 | stop(error) 134 | } 135 | 136 | return(matrix(unlist(res), byrow = TRUE, ncol = 2)) 137 | } 138 | -------------------------------------------------------------------------------- /R/corrRect.hclust.R: -------------------------------------------------------------------------------- 1 | #' Draw rectangles on the correlation matrix graph. 2 | #' 3 | #' Draw rectangles on the correlation matrix graph based on hierarchical cluster 4 | #' (\code{\link{hclust}}). 5 | #' 6 | #' @param corr Correlation matrix for function \code{corrRect.hclust}. It use 7 | #' \code{1-corr} as dist in hierarchical clustering (\code{\link{hclust}}). 8 | #' 9 | #' @param k Integer, the number of rectangles drawn on the graph according to 10 | #' the hierarchical cluster, for function \code{corrRect.hclust}. 11 | #' 12 | #' @param col Color of rectangles. 13 | #' @param lwd Line width of rectangles. 14 | #' 15 | #' @param method Character, the agglomeration method to be used for hierarchical 16 | #' clustering (\code{\link{hclust}}). This should be (an unambiguous 17 | #' abbreviation of) one of \code{'ward'}, \code{'ward.D'}, \code{'ward.D2'}, 18 | #' \code{'single'}, \code{'complete'}, \code{'average'}, \code{'mcquitty'}, 19 | #' \code{'median'} or \code{'centroid'}. 20 | #' 21 | #' @example vignettes/example-corrRect.hclust.R 22 | #' @keywords hplot 23 | #' @author Taiyun Wei 24 | #' @export 25 | corrRect.hclust = function( 26 | corr, 27 | k = 2, 28 | col = 'black', 29 | lwd = 2, 30 | method = c('complete', 'ward', 'ward.D', 'ward.D2', 'single', 'average', 31 | 'mcquitty', 'median', 'centroid')) 32 | { 33 | 34 | n = nrow(corr) 35 | method = match.arg(method) 36 | tree = hclust(as.dist(1 - corr), method = method) 37 | hc = cutree(tree, k = k) 38 | clustab = table(hc)[unique(hc[tree$order])] 39 | cu = c(0, cumsum(clustab)) 40 | 41 | rect(cu[-(k + 1)] + 0.5, 42 | n - cu[-(k + 1)] + 0.5, 43 | cu[-1] + 0.5, 44 | n - cu[-1] + 0.5, 45 | border = col, lwd = lwd) 46 | } 47 | -------------------------------------------------------------------------------- /R/corrplot-package.R: -------------------------------------------------------------------------------- 1 | #' @docType package 2 | #' @name corrplot-package 3 | #' 4 | #' @title 5 | #' Visualization of a correlation matrix 6 | #' 7 | #' @description 8 | #' The corrplot package is a graphical display of a correlation matrix, 9 | #' confidence interval or general matrix. It also contains some algorithms to do 10 | #' matrix reordering. In addition, corrplot is good at details, including 11 | #' choosing color, text labels, color labels, layout, etc. 12 | #' 13 | #' @author Taiyun Wei (weitaiyun@@gmail.com) 14 | #' @author Viliam Simko (viliam.simko@@gmail.com) 15 | #' 16 | #' Maintainer: Taiyun Wei (weitaiyun@@gmail.com) 17 | #' 18 | #' @references 19 | #' Michael Friendly (2002). 20 | #' \emph{Corrgrams: Exploratory displays for correlation matrices}. 21 | #' The American Statistician, 56, 316--324. 22 | #' 23 | #' D.J. Murdoch, E.D. Chow (1996). 24 | #' \emph{A graphical display of large correlation matrices}. 25 | #' The American Statistician, 50, 178--180. 26 | #' 27 | #' @seealso 28 | #' The \code{plotcorr} function in the \code{ellipse} package and 29 | #' \code{corrgram} function in the \code{corrgram} package has some 30 | #' similarities. 31 | #' 32 | #' @keywords hplot 33 | #' @keywords correlation 34 | #' @keywords correlogram 35 | #' @keywords feature selection 36 | #' @keywords dimensionality reduction 37 | NULL 38 | 39 | .onAttach <- function(libname, pkgname) { 40 | # just to show a startup message 41 | message <- paste('corrplot', utils::packageVersion('corrplot'), 'loaded') 42 | packageStartupMessage(message, appendLF = TRUE) 43 | } 44 | -------------------------------------------------------------------------------- /R/corrplot.R: -------------------------------------------------------------------------------- 1 | #' A visualization of a correlation matrix. 2 | #' 3 | #' A graphical display of a correlation matrix, confidence interval. The details 4 | #' are paid great attention to. It can also visualize a general matrix by 5 | #' setting \code{is.corr = FALSE}. 6 | #' 7 | #' @param corr The correlation matrix to visualize, must be square if 8 | #' \code{order} is not \code{'original'}. For general matrix, please using 9 | #' \code{is.corr = FALSE} to convert. 10 | #' 11 | #' @param method Character, the visualization method of correlation matrix to be 12 | #' used. Currently, it supports seven methods, named \code{'circle'} 13 | #' (default), \code{'square'}, \code{'ellipse'}, \code{'number'}, 14 | #' \code{'pie'}, \code{'shade'} and \code{'color'}. See examples for details. 15 | #' 16 | #' The areas of circles or squares show the absolute value of corresponding 17 | #' correlation coefficients. Method \code{'pie'} and \code{'shade'} came from 18 | #' Michael Friendly's job (with some adjustment about the shade added on), and 19 | #' \code{'ellipse'} came from D.J. Murdoch and E.D. Chow's job, see in section 20 | #' References. 21 | #' 22 | #' @param type Character, \code{'full'} (default), \code{'upper'} or 23 | #' \code{'lower'}, display full matrix, lower triangular or upper triangular 24 | #' matrix. 25 | #' 26 | #' 27 | #' @param col Vector, the colors of glyphs. They are distributed uniformly in 28 | #' \code{col.lim} interval. 29 | #' If \code{is.corr} is \code{TRUE}, the default value will be \code{COL2('RdBu', 200)}. 30 | #' If \code{is.corr} is \code{FALSE} and \code{corr} is a non-negative or non-positive matrix, 31 | #' the default value will be \code{COL1('YlOrBr', 200)}; 32 | #' otherwise (elements are partly positive and partly negative), 33 | #' the default value will be \code{COL2('RdBu', 200)}. 34 | #' 35 | #' @param col.lim The limits \code{(x1, x2)} interval for assigning color by 36 | #' \code{col}. If \code{NULL}, 37 | #' \code{col.lim} will be \code{c(-1, 1)} when \code{is.corr} is \code{TRUE}, 38 | #' \code{col.lim} will be \code{c(min(corr), max(corr))} when \code{is.corr} 39 | #' is \code{FALSE} 40 | #' 41 | #' NOTICE: if you set \code{col.lim} when \code{is.corr} is \code{TRUE}, the assigning colors 42 | #' are still distributed uniformly in [-1, 1], it only affect the display 43 | #' on color-legend. 44 | #' 45 | #' @param is.corr Logical, whether the input matrix is a correlation matrix or 46 | #' not. We can visualize the non-correlation matrix by setting 47 | #' \code{is.corr = FALSE}. 48 | #' 49 | #' 50 | #' @param bg The background color. 51 | #' 52 | #' @param title Character, title of the graph. 53 | #' 54 | #' 55 | #' @param add Logical, if \code{TRUE}, the graph is added to an existing plot, 56 | #' otherwise a new plot will be created. 57 | #' 58 | #' @param diag Logical, whether display the correlation coefficients on the 59 | #' principal diagonal. 60 | #' 61 | #' @param outline Logical or character, whether plot outline of circles, square 62 | #' and ellipse, or the color of these glyphs. For pie, this represents the 63 | #' color of the circle outlining the pie. If \code{outline} is \code{TRUE}, 64 | #' the default value is \code{'black'}. 65 | #' 66 | #' @param mar See \code{\link{par}}. 67 | #' 68 | #' @param addgrid.col The color of the grid. If \code{NA}, don't add grid. If 69 | #' \code{NULL} the default value is chosen. The default value depends on 70 | #' \code{method}, if \code{method} is \code{color} or \code{shade}, the color 71 | #' of the grid is \code{NA}, that is, not draw grid; otherwise \code{'grey'}. 72 | #' 73 | #' @param addCoef.col Color of coefficients added on the graph. If \code{NULL} 74 | #' (default), add no coefficients. 75 | #' 76 | #' @param addCoefasPercent Logic, whether translate coefficients into percentage 77 | #' style for spacesaving. 78 | #' 79 | #' @param order Character, the ordering method of the correlation matrix. 80 | #' \itemize{ 81 | #' \item{\code{'original'} for original order (default).} 82 | #' \item{\code{'AOE'} for the angular order of the eigenvectors.} 83 | #' \item{\code{'FPC'} for the first principal component order.} 84 | #' \item{\code{'hclust'} for the hierarchical clustering order.} 85 | #' \item{\code{'alphabet'} for alphabetical order.} 86 | #' } 87 | #' 88 | #' See function \code{\link{corrMatOrder}} for details. 89 | #' 90 | #' @param hclust.method Character, the agglomeration method to be used when 91 | #' \code{order} is \code{\link{hclust}}. This should be one of \code{'ward'}, 92 | #' \code{'ward.D'}, \code{'ward.D2'}, \code{'single'}, \code{'complete'}, 93 | #' \code{'average'}, \code{'mcquitty'}, \code{'median'} or \code{'centroid'}. 94 | #' 95 | #' @param addrect Integer, the number of rectangles draws on the graph according 96 | #' to the hierarchical cluster, only valid when \code{order} is \code{hclust}. 97 | #' If \code{NULL} (default), then add no rectangles. 98 | #' 99 | #' @param rect.col Color for rectangle border(s), only valid when \code{addrect} 100 | #' is equal or greater than 1. 101 | #' 102 | #' @param rect.lwd Numeric, line width for borders for rectangle border(s), only 103 | #' valid when \code{addrect} is equal or greater than 1. 104 | #' 105 | #' 106 | #' @param tl.pos Character or logical, position of text labels. If character, it 107 | #' must be one of \code{'lt'}, \code{'ld'}, \code{'td'}, \code{'d'} or 108 | #' \code{'n'}. \code{'lt'}(default if \code{type=='full'}) means left and top, 109 | #' \code{'ld'}(default if \code{type=='lower'}) means left and diagonal, 110 | #' \code{'td'}(default if \code{type=='upper'}) means top and diagonal(near), 111 | #' \code{'l'} means left, 112 | #' \code{'d'} means diagonal, \code{'n'} means don't add text-label. 113 | #' 114 | #' @param tl.cex Numeric, for the size of text label (variable names). 115 | #' 116 | #' @param tl.col The color of text label. 117 | #' 118 | #' @param tl.offset Numeric, for text label, see \code{\link{text}}. 119 | #' 120 | #' @param tl.srt Numeric, for text label string rotation in degrees, see 121 | #' \code{\link{text}}. 122 | #' 123 | #' @param cl.pos Character or logical, position of color-legend; If character, 124 | #' it must be one of \code{'r'} (default if \code{type=='upper'} or 125 | #' \code{'full'}), \code{'b'} (default if \code{type=='lower'}) or \code{'n'}, 126 | #' \code{'n'} means don't draw color-legend. 127 | #' 128 | #' @param cl.length Integer, the number of number-text in color-legend, passed to 129 | #' \code{\link{colorlegend}}. If \code{NULL}, \code{cl.length} is 130 | #' \code{length(col) + 1} when \code{length(col) <=20}; \code{cl.length} is 11 131 | #' when \code{length(col) > 20} 132 | #' 133 | #' @param cl.cex Numeric, text size of number-label in color-legend, passed to 134 | #' \code{\link{colorlegend}}. 135 | #' 136 | #' @param cl.ratio Numeric, to justify the width of color-legend, 0.1~0.2 is 137 | #' suggested. 138 | #' 139 | #' @param cl.align.text Character, \code{'l'}, \code{'c'} (default) or 140 | #' \code{'r'}, for number-label in color-legend, \code{'l'} means left, 141 | #' \code{'c'} means center, and \code{'r'} means right. 142 | #' 143 | #' @param cl.offset Numeric, for number-label in color-legend, see 144 | #' \code{\link{text}}. 145 | #' 146 | #' @param number.cex The \code{cex} parameter to send to the call to \code{text} 147 | #' when writing the correlation coefficients into the plot. 148 | #' 149 | #' @param number.font the \code{font} parameter to send to the call to 150 | #' \code{text} when writing the correlation coefficients into the plot. 151 | #' 152 | #' @param number.digits indicating the number of decimal digits to be 153 | #' added into the plot. Non-negative integer or NULL, default NULL. 154 | #' 155 | #' @param addshade Character for shade style, \code{'negative'}, 156 | #' \code{'positive'} or \code{'all'}, only valid when \code{method} is 157 | #' \code{'shade'}. If \code{'all'}, all correlation coefficients' glyph will 158 | #' be shaded; if \code{'positive'}, only the positive will be shaded; if 159 | #' \code{'negative'}, only the negative will be shaded. Note: the angle of 160 | #' shade line is different, 45 degrees for positive and 135 degrees for 161 | #' negative. 162 | #' 163 | #' @param shade.lwd Numeric, the line width of shade. 164 | #' 165 | #' @param shade.col The color of shade line. 166 | #' 167 | #' @param transKeepSign Logical, whether or not to keep matrix values' sign when 168 | #' transforming non-corr matrix for plotting. 169 | #' Only valid when \code{is.corr = FALSE}. The default value is \code{TRUE}. 170 | #' 171 | #' NOTE: If \code{FALSE},the non-corr matrix will be 172 | #' 173 | #' @param p.mat Matrix of p-value, if \code{NULL}, parameter \code{sig.level}, 174 | #' \code{insig}, \code{pch}, \code{pch.col}, \code{pch.cex} are invalid. 175 | #' 176 | #' @param sig.level Significant level, if the p-value in \code{p-mat} is bigger 177 | #' than \code{sig.level}, then the corresponding correlation coefficient is 178 | #' regarded as insignificant. If \code{insig} is \code{'label_sig'}, this may 179 | #' be an increasing vector of significance levels, in which case \code{pch} 180 | #' will be used once for the highest p-value interval and multiple times 181 | #' (e.g. '*', '**', '***') for each lower p-value interval. 182 | #' 183 | #' @param insig Character, specialized insignificant correlation coefficients, 184 | #' \code{'pch'} (default), \code{'p-value'}, \code{'blank'}, \code{'n'}, or 185 | #' \code{'label_sig'}. If \code{'blank'}, wipe away the corresponding glyphs; 186 | #' if \code{'p-value'}, add p-values the corresponding glyphs; 187 | #' if \code{'pch'}, add characters (see \code{pch} for details) on 188 | #' corresponding glyphs; if \code{'n'}, don't take any measures; if 189 | #' \code{'label_sig'}, mark significant correlations with pch 190 | #' (see \code{sig.level}). 191 | #' 192 | #' @param pch Add character on the glyphs of insignificant correlation 193 | #' coefficients(only valid when \code{insig} is \code{'pch'}). See 194 | #' \code{\link{par}}. 195 | #' 196 | #' @param pch.col The color of pch (only valid when \code{insig} is 197 | #' \code{'pch'}). 198 | #' 199 | #' @param pch.cex The cex of pch (only valid when \code{insig} is \code{'pch'}). 200 | #' 201 | #' @param plotCI Character, method of ploting confidence interval. If 202 | #' \code{'n'}, don't plot confidence interval. If 'rect', plot rectangles 203 | #' whose upper side means upper bound and lower side means lower bound, 204 | #' respectively. If 'circle', first plot a circle with the bigger absolute 205 | #' bound, and then plot the smaller. Warning: if the two bounds are the same 206 | #' sign, the smaller circle will be wiped away, thus forming a ring. Method 207 | #' 'square' is similar to 'circle'. 208 | #' 209 | #' @param lowCI.mat Matrix of the lower bound of confidence interval. 210 | #' 211 | #' @param uppCI.mat Matrix of the upper bound of confidence interval. 212 | #' 213 | #' @param na.label Label to be used for rendering \code{NA} cells. Default is 214 | #' \code{'?'}. If 'square', then the cell is rendered as a square with the 215 | #' \code{na.label.col} color. 216 | #' 217 | #' @param na.label.col Color used for rendering \code{NA} cells. Default is 218 | #' \code{'black'}. 219 | #' 220 | #' @param win.asp Aspect ration for the whole plot. Value other than 1 is 221 | #' currently compatible only with methods 'circle' and 'square'. 222 | #' 223 | #' @param \dots Additional arguments passing to function \code{text} for drawing 224 | #' text label. 225 | #' 226 | #' @return (Invisibly) returns a \code{list(corr, corrTrans, arg)}. 227 | #' \code{corr} is a reordered correlation matrix for plotting. 228 | #' \code{corrPos} is a data frame with \code{xName, yName, x, y, corr} and 229 | #' \code{p.value}(if p.mat is not NULL) 230 | #' column, which x and y are the position on the correlation matrix plot. 231 | #' \code{arg} is a list of some corrplot() input parameters' value. 232 | #' Now \code{type} is in. 233 | #' 234 | #' @details \code{corrplot} function offers flexible ways to visualize 235 | #' correlation matrix, lower and upper bound of confidence interval matrix. 236 | #' 237 | #' @references 238 | #' Michael Friendly (2002). 239 | #' \emph{Corrgrams: Exploratory displays for correlation matrices}. 240 | #' The American Statistician, 56, 316--324. 241 | #' 242 | #' D.J. Murdoch, E.D. Chow (1996). 243 | #' \emph{A graphical display of large correlation matrices}. 244 | #' The American Statistician, 50, 178--180. 245 | #' 246 | #' @author Taiyun Wei (weitaiyun@@gmail.com) 247 | #' @author Viliam Simko (viliam.simko@@gmail.com) 248 | #' @author Michael Levy (michael.levy@@healthcatalyst.com) 249 | #' 250 | #' @note \code{Cairo} and \code{cairoDevice} packages is strongly recommended to 251 | #' produce high-quality PNG, JPEG, TIFF bitmap files, especially for that 252 | #' \code{method} \code{circle}, \code{ellipse}. 253 | #' 254 | #' @note Row- and column names of the input matrix are used as labels rendered 255 | #' in the corrplot. Plothmath expressions will be used if the name is prefixed 256 | #' by one of the following characters: \code{:}, \code{=} or \code{$}. 257 | #' For example \code{':alpha + beta'}. 258 | #' 259 | #' @seealso Function \code{plotcorr} in the \code{ellipse} package and 260 | #' \code{corrgram} in the \code{corrgram} package have some similarities. 261 | #' 262 | #' Package \code{seriation} offered more methods to reorder matrices, such as 263 | #' ARSA, BBURCG, BBWRCG, MDS, TSP, Chen and so forth. 264 | #' 265 | #' @example vignettes/example-corrplot.R 266 | #' @import graphics grDevices stats 267 | #' @export 268 | corrplot = function(corr, 269 | method = c('circle', 'square', 'ellipse', 'number', 'shade', 'color', 'pie'), 270 | type = c('full', 'lower', 'upper'), col = NULL, col.lim = NULL, is.corr = TRUE, 271 | bg = 'white', title = '', add = FALSE, diag = TRUE, outline = FALSE, 272 | mar = c(0, 0, 0, 0), 273 | 274 | addgrid.col = NULL, addCoef.col = NULL, addCoefasPercent = FALSE, 275 | 276 | order = c('original', 'AOE', 'FPC', 'hclust', 'alphabet'), 277 | hclust.method = c('complete', 'ward', 'ward.D', 'ward.D2', 'single', 278 | 'average', 'mcquitty', 'median', 'centroid'), 279 | addrect = NULL, rect.col = 'black', rect.lwd = 2, 280 | 281 | tl.pos = NULL, tl.cex = 1, 282 | tl.col = 'red', tl.offset = 0.4, tl.srt = 90, 283 | 284 | cl.pos = NULL, cl.length = NULL, cl.cex = 0.8, 285 | cl.ratio = 0.15, cl.align.text = 'c', cl.offset = 0.5, 286 | 287 | number.cex = 1, number.font = 2, number.digits = NULL, 288 | 289 | addshade = c('negative', 'positive', 'all'), 290 | shade.lwd = 1, shade.col = 'white', 291 | 292 | transKeepSign = TRUE, 293 | 294 | p.mat = NULL, sig.level = 0.05, 295 | insig = c('pch', 'p-value', 'blank', 'n', 'label_sig'), 296 | pch = 4, pch.col = 'black', pch.cex = 3, 297 | 298 | plotCI = c('n', 'square', 'circle', 'rect'), 299 | lowCI.mat = NULL, uppCI.mat = NULL, 300 | na.label = '?', na.label.col = 'black', 301 | win.asp = 1, 302 | ...) 303 | { 304 | 305 | # checking multi-option input parameters 306 | method = match.arg(method) 307 | type = match.arg(type) 308 | order = match.arg(order) 309 | hclust.method = match.arg(hclust.method) 310 | addshade = match.arg(addshade) 311 | insig = match.arg(insig) 312 | plotCI = match.arg(plotCI) 313 | 314 | 315 | # rescale symbols within the corrplot based on win.asp parameter 316 | if (win.asp != 1 && !(method %in% c('circle', 'square'))) { 317 | stop('Parameter \'win.asp\' is supported only for circle and square methods.') 318 | } 319 | asp_rescale_factor = min(1, win.asp) / max(1, win.asp) 320 | stopifnot(asp_rescale_factor >= 0 && asp_rescale_factor <= 1) 321 | 322 | if (!is.matrix(corr) && !is.data.frame(corr)) { 323 | stop('Need a matrix or data frame!') 324 | } 325 | 326 | # select grid color automatically if not specified 327 | if (is.null(addgrid.col)) { 328 | addgrid.col = switch(method, color = NA, shade = NA, 'grey') 329 | } 330 | 331 | if(!is.corr & !transKeepSign & method %in% c('circle', 'square', 'ellipse', 'shade', 'pie')) { 332 | stop("method should not be in c('circle', 'square', 'ellipse', 'shade', 'pie') when transKeepSign = FALSE") 333 | } 334 | 335 | # Issue #142 336 | # checks for all values that are not missing 337 | if (any(corr[!is.na(corr)] < col.lim[1]) || any(corr[!is.na(corr)] > col.lim[2])) { 338 | stop('color limits should cover matrix') 339 | } 340 | 341 | 342 | if (is.null(col.lim)) { 343 | if (is.corr) { 344 | # if the matrix is expected to be a correlation matrix 345 | # it MUST be within the interval [-1,1] 346 | col.lim = c(-1, 1) 347 | } else { 348 | # Issue #91 349 | # if not a correlation matrix and the diagonal is hidden, 350 | # we need to compute limits from all cells except the diagonal 351 | 352 | if(!diag) { 353 | diag(corr) = NA 354 | } 355 | 356 | col.lim = c(min(corr, na.rm = TRUE), max(corr, na.rm = TRUE)) 357 | } 358 | } 359 | 360 | # if the mat have both negative and positive values, it is a SpecialCorr 361 | SpecialCorr = 0 362 | 363 | if(is.corr) { 364 | # check the interval if expecting a correlation matrix 365 | # otherwise, the values can be any number 366 | if (min(corr, na.rm = TRUE) < -1 - .Machine$double.eps ^ 0.75 || 367 | max(corr, na.rm = TRUE) > 1 + .Machine$double.eps ^ 0.75) { 368 | stop('The matrix is not in [-1, 1]!') 369 | } 370 | 371 | 372 | SpecialCorr = 1 373 | 374 | if(col.lim[1] < -1 | col.lim[2] > 1) { 375 | stop('col.lim should be within the interval [-1, 1]') 376 | } 377 | } 378 | 379 | 380 | intercept = 0 381 | zoom = 1 382 | 383 | if (!is.corr) { 384 | 385 | c_max = max(corr, na.rm = TRUE) 386 | c_min = min(corr, na.rm = TRUE) 387 | 388 | if((col.lim[1] > c_min) | (col.lim[2] < c_max)) 389 | { 390 | stop('Wrong color: matrix should be in col.lim interval!') 391 | } 392 | 393 | if(diff(col.lim)/(c_max - c_min)> 2) { 394 | warning('col.lim interval too wide, please set a suitable value') 395 | } 396 | 397 | # all negative or positive or NOT transkeepSign, trans to [0, 1] 398 | if (c_max <= 0 | c_min>=0 | !transKeepSign) { 399 | intercept = - col.lim[1] 400 | zoom = 1 / (diff(col.lim)) 401 | 402 | #if(col.lim[1] * col.lim[2] < 0) { 403 | # warning('col.lim interval not suitable to the matrix') 404 | #} 405 | 406 | } 407 | 408 | 409 | # mixed negative and positive, remain its sign, e.g. [-0.8, 1] or [-1, 0.7] 410 | else { 411 | 412 | # expression from the original code as a sanity check 413 | stopifnot(c_max * c_min < 0) 414 | # newly derived expression which covers the single remaining case 415 | stopifnot(c_min < 0 && c_max > 0) 416 | 417 | 418 | 419 | intercept = 0 420 | zoom = 1 / max(abs(col.lim)) 421 | SpecialCorr = 1 422 | } 423 | 424 | corr = (intercept + corr) * zoom 425 | } 426 | 427 | 428 | 429 | 430 | col.lim2 = (intercept + col.lim) * zoom 431 | int = intercept * zoom 432 | 433 | 434 | 435 | if (is.null(col) & is.corr) { 436 | col = COL2('RdBu', 200) 437 | } 438 | 439 | if (is.null(col) & !is.corr) { 440 | if(col.lim[1] * col.lim[2] < 0) { 441 | col = COL2('RdBu', 200) 442 | } else { 443 | col = COL1('YlOrBr', 200) 444 | } 445 | 446 | } 447 | 448 | n = nrow(corr) 449 | m = ncol(corr) 450 | min.nm = min(n, m) 451 | ord = 1:min.nm 452 | 453 | if (order != 'original') { 454 | ord = corrMatOrder(corr, order = order, hclust.method = hclust.method) 455 | corr = corr[ord, ord] 456 | 457 | if (!is.null(p.mat)) { 458 | p.mat = p.mat[ord, ord] 459 | } 460 | } 461 | 462 | ## set up variable names 463 | if (is.null(rownames(corr))) { 464 | rownames(corr) = 1:n 465 | } 466 | if (is.null(colnames(corr))) { 467 | colnames(corr) = 1:m 468 | } 469 | 470 | # assigns Inf to cells in the matrix depending on the type paramter 471 | apply_mat_filter = function(mat) { 472 | x = matrix(1:n * m, nrow = n, ncol = m) 473 | switch(type, 474 | upper = mat[row(x) > col(x)] <- Inf, 475 | lower = mat[row(x) < col(x)] <- Inf 476 | ) 477 | 478 | if (!diag) { 479 | diag(mat) = Inf 480 | } 481 | return(mat) 482 | } 483 | 484 | # retrieves coordinates of cells to be rendered 485 | getPos.Dat = function(mat) { 486 | tmp = apply_mat_filter(mat) 487 | Dat = tmp[is.finite(tmp)] 488 | ind = which(is.finite(tmp), arr.ind = TRUE) 489 | Pos = ind 490 | Pos[, 1] = ind[, 2] 491 | Pos[, 2] = -ind[, 1] + 1 + n 492 | 493 | PosName = ind 494 | PosName[, 1] = colnames(mat)[ind[, 2]] 495 | PosName[, 2] = rownames(mat)[ind[, 1]] 496 | return(list(Pos, Dat, PosName)) 497 | } 498 | 499 | # retrieves coordinates of NA cells 500 | # we use this for rending NA cells differently 501 | getPos.NAs = function(mat) { 502 | tmp = apply_mat_filter(mat) 503 | ind = which(is.na(tmp), arr.ind = TRUE) 504 | Pos = ind 505 | Pos[, 1] = ind[, 2] 506 | Pos[, 2] = -ind[, 1] + 1 + n 507 | return(Pos) 508 | } 509 | 510 | testTemp = getPos.Dat(corr) 511 | 512 | Pos = getPos.Dat(corr)[[1]] 513 | PosName = getPos.Dat(corr)[[3]] 514 | 515 | # decide whether NA labels are going to be rendered or whether we ignore them 516 | if (any(is.na(corr)) && is.character(na.label)) { 517 | PosNA = getPos.NAs(corr) 518 | } else { 519 | # explicitly set to NULL to indicate that NA labels are not going to be 520 | # rendered 521 | PosNA = NULL 522 | } 523 | 524 | AllCoords = rbind(Pos, PosNA) 525 | 526 | # rows 527 | n2 = max(AllCoords[, 2]) 528 | n1 = min(AllCoords[, 2]) 529 | 530 | nn = n2 - n1 531 | 532 | # columns 533 | m2 = max(AllCoords[, 1]) 534 | m1 = min(AllCoords[, 1]) 535 | 536 | # Issue #19: legend color bar width 0 when using just one column matrix 537 | # also discussed here: http://stackoverflow.com/questions/34638555/ 538 | mm = max(1, m2 - m1) 539 | 540 | # Issue #20: support plotmath expressions in rownames and colnames 541 | expand_expression = function(s) { 542 | ifelse(grepl('^[:=$]', s), parse(text = substring(s, 2)), s) 543 | } 544 | 545 | newrownames = sapply( 546 | rownames(corr)[(n + 1 - n2):(n + 1 - n1)], expand_expression) 547 | 548 | newcolnames = sapply( 549 | colnames(corr)[m1:m2], expand_expression) 550 | 551 | DAT = getPos.Dat(corr)[[2]] 552 | len.DAT = length(DAT) 553 | 554 | rm(expand_expression) # making sure the function is only used here 555 | 556 | 557 | ## assign colors 558 | assign.color = function(dat = DAT, color = col, isSpecialCorr = SpecialCorr) { 559 | 560 | if(isSpecialCorr) { 561 | newcorr = (dat + 1) / 2 562 | } else { 563 | newcorr = dat 564 | } 565 | 566 | newcorr[newcorr <= 0] = 0 567 | newcorr[newcorr >= 1] = 1 - 1e-16 568 | color[floor(newcorr * length(color)) + 1] # new color returned 569 | } 570 | 571 | col.fill = assign.color() 572 | 573 | isFALSE = function(x) identical(x, FALSE) 574 | isTRUE = function(x) identical(x, TRUE) 575 | 576 | if (isFALSE(tl.pos)) { 577 | tl.pos = 'n' 578 | } 579 | 580 | if (is.null(tl.pos) || isTRUE(tl.pos)) { 581 | tl.pos = switch(type, full = 'lt', lower = 'ld', upper = 'td') 582 | } 583 | 584 | if (isFALSE(cl.pos)) { 585 | cl.pos = 'n' 586 | } 587 | 588 | if (is.null(cl.pos) || isTRUE(cl.pos)) { 589 | cl.pos = switch(type, full = 'r', lower = 'b', upper = 'r') 590 | } 591 | 592 | if (isFALSE(outline)) { 593 | col.border = col.fill 594 | } else if (isTRUE(outline)) { 595 | col.border = 'black' 596 | } else if (is.character(outline)) { 597 | col.border = outline 598 | } else { 599 | stop('Unsupported value type for parameter outline') 600 | } 601 | 602 | # restore this parameter when exiting the corrplot function in any way 603 | oldpar = par(mar = mar, bg = par()$bg) 604 | on.exit(par(oldpar), add = TRUE) 605 | 606 | ## calculate label-text width approximately 607 | if (!add) { 608 | plot.new() 609 | 610 | # Issue #10: code from Sebastien Rochette (github user @statnmap) 611 | xlabwidth = max(strwidth(newrownames, cex = tl.cex)) 612 | ylabwidth = max(strwidth(newcolnames, cex = tl.cex)) 613 | laboffset = strwidth('W', cex = tl.cex) * tl.offset 614 | 615 | # Issue #10 616 | for (i in 1:50) { 617 | xlim = c( 618 | m1 - 0.5 - laboffset - 619 | xlabwidth * (grepl('l', tl.pos) | grepl('d', tl.pos)), 620 | m2 + 0.5 + mm * cl.ratio * (cl.pos == 'r') + 621 | xlabwidth * abs(cos(tl.srt * pi / 180)) * grepl('d', tl.pos) 622 | ) #+ c(-0.35, 0.15) 623 | 624 | ylim = c( 625 | n1 - 0.5 - nn * cl.ratio * (cl.pos == 'b') - laboffset, 626 | n2 + 0.5 + laboffset + 627 | ylabwidth * abs(sin(tl.srt * pi / 180)) * grepl('t', tl.pos) + 628 | ylabwidth * abs(sin(tl.srt * pi / 180)) * (type=='lower') * grepl('d', tl.pos) 629 | ) #+ c(-0.15, 0) 630 | 631 | plot.window(xlim, ylim, asp = 1, xaxs = 'i', yaxs = 'i') 632 | 633 | x.tmp = max(strwidth(newrownames, cex = tl.cex)) 634 | y.tmp = max(strwidth(newcolnames, cex = tl.cex)) 635 | 636 | laboffset.tmp = strwidth('W', cex = tl.cex) * tl.offset 637 | if (max(x.tmp - xlabwidth, 638 | y.tmp - ylabwidth, 639 | laboffset.tmp - laboffset) < 1e-03) { 640 | break 641 | } 642 | 643 | xlabwidth = x.tmp 644 | ylabwidth = y.tmp 645 | 646 | laboffset = laboffset.tmp 647 | 648 | if (i == 50) { 649 | warning(c('Not been able to calculate text margin, ', 650 | 'please try again with a clean new empty window using ', 651 | '{plot.new(); dev.off()} or reduce tl.cex')) 652 | } 653 | } 654 | 655 | if (.Platform$OS.type == 'windows') { 656 | grDevices::windows.options(width = 7, 657 | height = 7 * diff(ylim) / diff(xlim)) 658 | } 659 | 660 | xlim = xlim + diff(xlim) * 0.01 * c(-1, 1) 661 | ylim = ylim + diff(ylim) * 0.01 * c(-1, 1) 662 | 663 | plot.window(xlim = xlim, ylim = ylim, 664 | asp = win.asp, xlab = '', ylab = '', xaxs = 'i', yaxs = 'i') 665 | } 666 | 667 | ## for: add = TRUE 668 | laboffset = strwidth('W', cex = tl.cex) * tl.offset 669 | 670 | ## background for the cells 671 | symbols(Pos, add = TRUE, inches = FALSE, 672 | rectangles = matrix(1, len.DAT, 2), bg = bg, fg = bg) 673 | 674 | ## circle 675 | if (method == 'circle' && plotCI == 'n') { 676 | symbols(Pos, add = TRUE, inches = FALSE, 677 | circles = asp_rescale_factor * 0.9 * abs(DAT) ^ 0.5 / 2, 678 | fg = col.border, bg = col.fill) 679 | } 680 | 681 | ## ellipse 682 | if (method == 'ellipse' && plotCI == 'n') { 683 | ell.dat = function(rho, length = 99) { 684 | k = seq(0, 2 * pi, length = length) 685 | x = cos(k + acos(rho) / 2) / 2 686 | y = cos(k - acos(rho) / 2) / 2 687 | cbind(rbind(x, y), c(NA, NA)) 688 | } 689 | 690 | ELL.dat = lapply(DAT, ell.dat) 691 | ELL.dat2 = 0.85 * matrix(unlist(ELL.dat), ncol = 2, byrow = TRUE) 692 | ELL.dat2 = ELL.dat2 + Pos[rep(1: length(DAT), each = 100), ] 693 | polygon(ELL.dat2, border = col.border, col = col.fill) 694 | } 695 | 696 | ## number 697 | if (is.null(number.digits)) { 698 | number.digits = switch(addCoefasPercent + 1, 2, 0) 699 | } 700 | 701 | stopifnot(number.digits %% 1 == 0) # is whole number 702 | stopifnot(number.digits >= 0) # is non-negative number 703 | 704 | if (method == 'number' && plotCI == 'n') { 705 | x = (DAT - int) * ifelse(addCoefasPercent, 100, 1) / zoom 706 | text(Pos[, 1], Pos[, 2], font = number.font, col = col.fill, 707 | labels = format(round(x, number.digits), nsmall = number.digits), 708 | cex = number.cex) 709 | } 710 | 711 | # Issue #55: Support for multiple characters when rendering NAs 712 | NA_LABEL_MAX_CHARS = 2 713 | 714 | # renders NA cells 715 | if (is.matrix(PosNA) && nrow(PosNA) > 0) { 716 | 717 | stopifnot(is.matrix(PosNA)) # sanity check 718 | 719 | if (na.label == 'square') { 720 | symbols(PosNA, add = TRUE, inches = FALSE, 721 | squares = rep(1, nrow(PosNA)), 722 | bg = na.label.col, fg = na.label.col) 723 | } else if (nchar(na.label) %in% 1:NA_LABEL_MAX_CHARS) { 724 | symbols(PosNA, add = TRUE, inches = FALSE, 725 | squares = rep(1, nrow(PosNA)), fg = bg, bg = bg) 726 | text(PosNA[, 1], PosNA[, 2], font = number.font, 727 | col = na.label.col, 728 | labels = na.label, cex = number.cex, ...) 729 | } else { 730 | stop(paste('Maximum number of characters for NA label is:', 731 | NA_LABEL_MAX_CHARS)) 732 | } 733 | } 734 | 735 | ## pie 736 | if (method == 'pie' && plotCI == 'n') { 737 | 738 | # Issue #18: Corrplot background circle 739 | symbols(Pos, add = TRUE, inches = FALSE, 740 | circles = rep(0.5, len.DAT) * 0.85, fg = col.border) 741 | 742 | pie.dat = function(theta, length = 100) { 743 | k = seq(pi / 2, pi / 2 - theta, length = 0.5 * length * abs(theta) / pi) 744 | x = c(0, cos(k) / 2, 0) 745 | y = c(0, sin(k) / 2, 0) 746 | cbind(rbind(x, y), c(NA, NA)) # pie.dat returned 747 | } 748 | 749 | PIE.dat = lapply(DAT * 2 * pi, pie.dat) 750 | len.pie = unlist(lapply(PIE.dat, length)) / 2 751 | PIE.dat2 = 0.85 * matrix(unlist(PIE.dat), ncol = 2, byrow = TRUE) 752 | PIE.dat2 = PIE.dat2 + Pos[rep(1:length(DAT), len.pie), ] 753 | polygon(PIE.dat2, border = 'black', col = col.fill) 754 | } 755 | 756 | ## shade 757 | if (method == 'shade' && plotCI == 'n') { 758 | symbols(Pos, add = TRUE, inches = FALSE, squares = rep(1, len.DAT), 759 | bg = col.fill, fg = addgrid.col) 760 | 761 | shade.dat = function(w) { 762 | x = w[1] 763 | y = w[2] 764 | rho = w[3] 765 | x1 = x - 0.5 766 | x2 = x + 0.5 767 | y1 = y - 0.5 768 | y2 = y + 0.5 769 | dat = NA 770 | 771 | if ((addshade == 'positive' || addshade == 'all') && rho > 0) { 772 | dat = cbind(c(x1, x1, x), c(y, y1, y1), 773 | c(x, x2, x2), c(y2, y2, y)) 774 | } 775 | 776 | if ((addshade == 'negative' || addshade == 'all') && rho < 0) { 777 | dat = cbind(c(x1, x1, x), c(y, y2, y2), 778 | c(x, x2, x2), c(y1, y1, y)) 779 | } 780 | 781 | return(t(dat)) 782 | } 783 | 784 | pos_corr = rbind(cbind(Pos, DAT)) 785 | pos_corr2 = split(pos_corr, 1: nrow(pos_corr)) 786 | 787 | SHADE.dat = matrix(na.omit(unlist(lapply(pos_corr2, shade.dat))), 788 | byrow = TRUE, ncol = 4) 789 | 790 | segments(SHADE.dat[, 1], SHADE.dat[, 2], SHADE.dat[, 3], 791 | SHADE.dat[, 4], col = shade.col, lwd = shade.lwd) 792 | } 793 | 794 | ## square 795 | if (method == 'square' && plotCI == 'n') { 796 | draw_method_square(Pos, DAT, asp_rescale_factor, col.border, col.fill) 797 | } 798 | 799 | ## color 800 | if (method == 'color' && plotCI == 'n') { 801 | draw_method_color(Pos, col.border, col.fill) 802 | } 803 | 804 | ## add grid 805 | draw_grid(AllCoords, addgrid.col) 806 | 807 | if (plotCI != 'n') { 808 | 809 | if (is.null(lowCI.mat) || is.null(uppCI.mat)) { 810 | stop('Need lowCI.mat and uppCI.mat!') 811 | } 812 | 813 | if (order != 'original') { 814 | lowCI.mat = lowCI.mat[ord, ord] 815 | uppCI.mat = uppCI.mat[ord, ord] 816 | } 817 | 818 | pos.lowNew = getPos.Dat(lowCI.mat)[[1]] 819 | lowNew = getPos.Dat(lowCI.mat)[[2]] 820 | pos.uppNew = getPos.Dat(uppCI.mat)[[1]] 821 | uppNew = getPos.Dat(uppCI.mat)[[2]] 822 | 823 | k1 = (abs(uppNew) > abs(lowNew)) 824 | bigabs = uppNew 825 | bigabs[which(!k1)] = lowNew[!k1] 826 | smallabs = lowNew 827 | smallabs[which(!k1)] = uppNew[!k1] 828 | sig = sign(uppNew * lowNew) 829 | 830 | color_bigabs = col[ceiling((bigabs + 1) * length(col) / 2)] 831 | color_smallabs = col[ceiling((smallabs + 1) * length(col) / 2)] 832 | 833 | if (plotCI == 'circle') { 834 | 835 | symbols(pos.uppNew[, 1], pos.uppNew[, 2], 836 | add = TRUE, inches = FALSE, 837 | circles = 0.95 * abs(bigabs) ^ 0.5 / 2, 838 | bg = ifelse(sig > 0, col.fill, color_bigabs), 839 | fg = ifelse(sig > 0, col.fill, color_bigabs) 840 | ) 841 | 842 | symbols(pos.lowNew[, 1], pos.lowNew[, 2], 843 | add = TRUE, inches = FALSE, 844 | circles = 0.95 * abs(smallabs) ^ 0.5 / 2, 845 | bg = ifelse(sig > 0, bg, color_smallabs), 846 | fg = ifelse(sig > 0, col.fill, color_smallabs)) 847 | } 848 | 849 | if (plotCI == 'square') { 850 | symbols(pos.uppNew[, 1], pos.uppNew[, 2], 851 | add = TRUE, inches = FALSE, 852 | squares = abs(bigabs) ^ 0.5, 853 | bg = ifelse(sig > 0, col.fill, color_bigabs), 854 | fg = ifelse(sig > 0, col.fill, color_bigabs)) 855 | 856 | symbols(pos.lowNew[, 1], pos.lowNew[, 2], 857 | add = TRUE, inches = FALSE, 858 | squares = abs(smallabs) ^ 0.5, 859 | bg = ifelse(sig > 0, bg, color_smallabs), 860 | fg = ifelse(sig > 0, col.fill, color_smallabs)) 861 | } 862 | 863 | if (plotCI == 'rect') { 864 | rect.width = 0.25 865 | rect(pos.uppNew[, 1] - rect.width, pos.uppNew[, 2] + smallabs / 2, 866 | pos.uppNew[, 1] + rect.width, pos.uppNew[, 2] + bigabs / 2, 867 | col = col.fill, border = col.fill) 868 | segments(pos.lowNew[, 1] - rect.width, pos.lowNew[, 2] + DAT / 2, 869 | pos.lowNew[, 1] + rect.width, pos.lowNew[, 2] + DAT / 2, 870 | col = 'black', lwd = 1) 871 | segments(pos.uppNew[, 1] - rect.width, pos.uppNew[, 2] + uppNew / 2, 872 | pos.uppNew[, 1] + rect.width, pos.uppNew[, 2] + uppNew / 2, 873 | col = 'black', lwd = 1) 874 | segments(pos.lowNew[, 1] - rect.width, pos.lowNew[, 2] + lowNew / 2, 875 | pos.lowNew[, 1] + rect.width, pos.lowNew[, 2] + lowNew / 2, 876 | col = 'black', lwd = 1) 877 | segments(pos.lowNew[, 1] - 0.5, pos.lowNew[, 2], 878 | pos.lowNew[, 1] + 0.5, pos.lowNew[, 2], col = 'grey70', lty = 3) 879 | } 880 | } 881 | 882 | 883 | ## add numbers 884 | if (!is.null(addCoef.col) && method != 'number') { 885 | text(Pos[, 1], Pos[, 2], col = addCoef.col, 886 | labels = format( 887 | round( 888 | (DAT - int) * ifelse(addCoefasPercent, 100, 1) / zoom, 889 | number.digits 890 | ), 891 | nsmall = number.digits 892 | ), 893 | cex = number.cex, font = number.font) 894 | } 895 | 896 | 897 | if (!is.null(p.mat)) { 898 | pos.pNew = getPos.Dat(p.mat)[[1]] 899 | pNew = getPos.Dat(p.mat)[[2]] 900 | } 901 | 902 | 903 | if (!is.null(p.mat) && insig != 'n') { 904 | 905 | if(!is.null(rownames(p.mat)) | !is.null(rownames(p.mat))) { 906 | if(!all(colnames(p.mat)==colnames(corr)) | 907 | !all(rownames(p.mat)==rownames(corr))) { 908 | warning('p.mat and corr may be not paired, their rownames and colnames are not totally same!') 909 | } 910 | } 911 | 912 | if (insig == 'label_sig') { 913 | 914 | # Unless another character is specified, mark sig with * 915 | if (!is.character(pch)) 916 | pch = '*' 917 | 918 | place_points = function(sig.locs, point) { 919 | text(pos.pNew[, 1][sig.locs], pos.pNew[, 2][sig.locs], 920 | labels = point, col = pch.col, cex = pch.cex, lwd = 2) 921 | } 922 | 923 | if (length(sig.level) == 1) { 924 | place_points(sig.locs = which(pNew < sig.level), point = pch) 925 | 926 | } else { 927 | l = length(sig.level) 928 | for (i in seq_along(sig.level)) { 929 | iter = l + 1 - i 930 | pchTmp = paste(rep(pch, i), collapse = '') 931 | if (i == length(sig.level)) { 932 | locs = which(pNew < sig.level[iter]) 933 | if (length(locs)) { 934 | place_points(sig.locs = locs, point = pchTmp) 935 | } 936 | } else { 937 | locs = which(pNew < sig.level[iter] & pNew > sig.level[iter - 1]) 938 | if (length(locs)) { 939 | place_points(sig.locs = locs, point = pchTmp) 940 | } 941 | } 942 | } 943 | 944 | } 945 | 946 | } else { 947 | 948 | ind.p = which(pNew > sig.level) 949 | p_inSig = length(ind.p) > 0 950 | 951 | if (insig == 'pch' && p_inSig) { 952 | points(pos.pNew[, 1][ind.p], pos.pNew[, 2][ind.p], 953 | pch = pch, col = pch.col, cex = pch.cex, lwd = 2) 954 | } 955 | 956 | if (insig == 'p-value' && p_inSig) { 957 | text(pos.pNew[, 1][ind.p], pos.pNew[, 2][ind.p], 958 | round(pNew[ind.p], number.digits), col = pch.col) 959 | } 960 | 961 | if (insig == 'blank' && p_inSig) { 962 | symbols(pos.pNew[, 1][ind.p], pos.pNew[, 2][ind.p], inches = FALSE, 963 | squares = rep(1, length(pos.pNew[, 1][ind.p])), 964 | fg = addgrid.col, bg = bg, add = TRUE) 965 | } 966 | } 967 | } 968 | 969 | 970 | ### color legend 971 | if (cl.pos != 'n') { 972 | colRange = assign.color(dat = col.lim2) 973 | 974 | 975 | ind1 = which(col == colRange[1]) 976 | ind2 = which(col == colRange[2]) 977 | colbar = col[ind1:ind2] 978 | 979 | if (is.null(cl.length)) { 980 | cl.length = ifelse(length(colbar) > 20, 11, length(colbar) + 1) 981 | } 982 | 983 | labels = seq(col.lim[1], col.lim[2], length = cl.length) 984 | 985 | if (cl.pos == 'r') { 986 | vertical = TRUE 987 | xlim = c(m2 + 0.5 + mm * 0.02, m2 + 0.5 + mm * cl.ratio) 988 | ylim = c(n1 - 0.5, n2 + 0.5) 989 | } 990 | 991 | if (cl.pos == 'b') { 992 | vertical = FALSE 993 | xlim = c(m1 - 0.5, m2 + 0.5) 994 | ylim = c(n1 - 0.5 - nn * cl.ratio, n1 - 0.5 - nn * 0.02) 995 | } 996 | 997 | colorlegend(colbar = colbar, labels = round(labels, 2), 998 | offset = cl.offset, ratio.colbar = 0.3, cex = cl.cex, 999 | xlim = xlim, ylim = ylim, vertical = vertical, 1000 | align = cl.align.text) 1001 | } 1002 | 1003 | ## add variable names and title 1004 | if (tl.pos != 'n') { 1005 | pos.xlabel = cbind(m1:m2, n2 + 0.5 + laboffset) 1006 | pos.ylabel = cbind(m1 - 0.5, n2:n1) 1007 | 1008 | if (tl.pos == 'td') { 1009 | if (type != 'upper') { 1010 | stop('type should be \'upper\' if tl.pos is \'dt\'.') 1011 | } 1012 | pos.ylabel = cbind(m1:(m1 + nn) - 0.5, n2:n1) 1013 | } 1014 | 1015 | if (tl.pos == 'ld') { 1016 | if (type != 'lower') { 1017 | stop('type should be \'lower\' if tl.pos is \'ld\'.') 1018 | } 1019 | pos.xlabel = cbind(m1:m2, n2:(n2 - mm) + 0.5 + laboffset) 1020 | } 1021 | 1022 | if (tl.pos == 'd') { 1023 | pos.ylabel = cbind(m1:(m1 + nn) - 0.5, n2:n1) 1024 | pos.ylabel = pos.ylabel[1:min(n, m), ] 1025 | 1026 | symbols(pos.ylabel[, 1] + 0.5, pos.ylabel[, 2], add = TRUE, 1027 | bg = bg, fg = addgrid.col, 1028 | inches = FALSE, squares = rep(1, length(pos.ylabel[, 1]))) 1029 | 1030 | text(pos.ylabel[, 1] + 0.5, pos.ylabel[, 2], newcolnames[1:min(n, m)], 1031 | col = tl.col, cex = tl.cex, ...) 1032 | 1033 | } else { 1034 | 1035 | if(tl.pos != 'l') { 1036 | text(pos.xlabel[, 1], pos.xlabel[, 2], newcolnames, srt = tl.srt, 1037 | adj = ifelse(tl.srt == 0, c(0.5, 0), c(0, 0)), 1038 | col = tl.col, cex = tl.cex, offset = tl.offset, ...) 1039 | } 1040 | 1041 | text(pos.ylabel[, 1], pos.ylabel[, 2], newrownames, 1042 | col = tl.col, cex = tl.cex, pos = 2, offset = tl.offset, ...) 1043 | } 1044 | } 1045 | 1046 | title(title, ...) 1047 | 1048 | 1049 | 1050 | ## add grid, in case of the grid is ate when 'diag=FALSE' 1051 | if (type == 'full' && plotCI == 'n' && !is.null(addgrid.col)) { 1052 | rect(m1 - 0.5, n1 - 0.5, m2 + 0.5, n2 + 0.5, border = addgrid.col) 1053 | } 1054 | 1055 | ## draws rectangles, call function corrRect.hclust 1056 | if (!is.null(addrect) && order == 'hclust' && type == 'full') { 1057 | corrRect.hclust(corr, k = addrect, method = hclust.method, 1058 | col = rect.col, lwd = rect.lwd) 1059 | } 1060 | 1061 | corrPos = data.frame(PosName, Pos, DAT) 1062 | colnames(corrPos) = c('xName', 'yName', 'x', 'y', 'corr') 1063 | if(!is.null(p.mat)) { 1064 | corrPos = cbind(corrPos, pNew) 1065 | colnames(corrPos)[6] = c('p.value') 1066 | } 1067 | corrPos = corrPos[order(corrPos[, 3], -corrPos[, 4]), ] 1068 | rownames(corrPos) = NULL 1069 | 1070 | 1071 | res = list(corr = corr, corrPos = corrPos, arg = list(type = type)) 1072 | 1073 | invisible(res) # reordered correlation matrix, and Position 1074 | } 1075 | 1076 | 1077 | #' @noRd 1078 | draw_method_square = function(coords, values, asp_rescale_factor, fg, bg) { 1079 | symbols(coords, add = TRUE, inches = FALSE, 1080 | squares = asp_rescale_factor * abs(values) ^ 0.5, 1081 | bg = bg, fg = fg) 1082 | } 1083 | 1084 | 1085 | #' @noRd 1086 | draw_method_color = function(coords, fg, bg) { 1087 | symbols(coords, squares = rep(1, nrow(coords)), fg = fg, bg = bg, 1088 | add = TRUE, inches = FALSE) 1089 | } 1090 | 1091 | 1092 | #' @noRd 1093 | draw_grid = function(coords, fg) { 1094 | symbols(coords, add = TRUE, inches = FALSE, fg = fg, bg = NA, 1095 | rectangles = matrix(1, nrow = nrow(coords), ncol = 2)) 1096 | } 1097 | -------------------------------------------------------------------------------- /R/corrplot.mixed.R: -------------------------------------------------------------------------------- 1 | #' Using mixed methods to visualize a correlation matrix. 2 | #' 3 | #' @param corr Matrix, the correlation matrix to visualize. 4 | #' @param lower Character, the visualization method for the lower triangular 5 | #' correlation matrix. 6 | #' @param upper Character, the visualization method for the upper triangular 7 | #' correlation matrix. 8 | #' @param tl.pos Character, \code{'lt'}, \code{'d'} or \code{'n'}, giving 9 | #' position of text labels, \code{'lt'} means left and top, \code{'d'} means 10 | #' diagonal. If \code{'n'}, add no textlabel. 11 | #' @param diag Character, for specifying the glyph on the principal diagonal. It 12 | #' is one of \code{'n'} (default, draw nothing), \code{'l'} (draw the glyphs 13 | #' of lower triangular) or \code{'u'} (draw the glyphs of upper triangular). 14 | #' @param bg The background color. 15 | #' @param addgrid.col See the \code{addgrid.col} parameter in the function 16 | #' \code{\link{corrplot}} 17 | #' @param lower.col Passed as \code{col} parameter to the lower matrix. 18 | #' @param upper.col Passed as \code{col} parameter to the upper matrix. 19 | #' @param plotCI See the \code{plotCI} parameter in the function 20 | #' \code{\link{corrplot}} 21 | #' @param mar See \code{\link{par}}. 22 | #' @param \dots Additional arguments for corrplot's wrappers 23 | #' 24 | #' @author Taiyun Wei 25 | #' @example vignettes/example-corrplot.mixed.R 26 | #' @export 27 | corrplot.mixed = function( 28 | corr, 29 | lower = 'number', 30 | upper = 'circle', 31 | tl.pos = c('d', 'lt', 'n'), 32 | diag = c('n', 'l', 'u'), 33 | bg = 'white', 34 | addgrid.col = 'grey', 35 | lower.col = NULL, 36 | upper.col = NULL, 37 | plotCI = c('n', 'square', 'circle', 'rect'), 38 | mar = c(0, 0, 0, 0), 39 | ...) 40 | { 41 | 42 | tl.pos = match.arg(tl.pos) 43 | diag = match.arg(diag) 44 | plotCI = match.arg(plotCI) 45 | n = nrow(corr) 46 | 47 | # fixes issue #21 48 | # some methods are not compatible with plotCI='rect' 49 | adjust_plotCI = function(plotCI, method) { 50 | if (plotCI != 'rect' || method %in% c('circle', 'square')) { 51 | return(plotCI) 52 | } 53 | return('n') 54 | } 55 | 56 | plotCI_lower = adjust_plotCI(plotCI, lower) 57 | plotCI_upper = adjust_plotCI(plotCI, upper) 58 | 59 | # fixed issue #102 60 | # restore this parameter when exiting the corrplot.mixed function in any way 61 | oldpar = par(mar = mar, bg = par()$bg) 62 | on.exit(par(oldpar), add = TRUE) 63 | 64 | corrplot(corr, type = 'upper', method = upper, diag = TRUE, 65 | tl.pos = tl.pos, plotCI = plotCI_upper, 66 | bg = bg, addgrid.col = addgrid.col, 67 | col = upper.col, mar = mar, ...) -> res1 68 | 69 | corrplot(corr, add = TRUE, type = 'lower', method = lower, 70 | diag = (diag == 'l'), 71 | bg = bg, addgrid.col = addgrid.col, 72 | tl.pos = 'n', cl.pos = 'n', plotCI = plotCI_lower, 73 | col = lower.col, mar = mar, ...) -> res2 74 | 75 | if (diag == 'n' && tl.pos != 'd') { 76 | # draw empty rectangles over the diagonal to 'clean' it graphically 77 | symbols(1:n, n:1, add = TRUE, bg = bg, fg = addgrid.col, 78 | inches = FALSE, squares = rep(1, n)) 79 | } 80 | 81 | corr = res1$corr 82 | corrPos = rbind(res1$corrPos, res2$corrPos) 83 | corrPos = corrPos[order(corrPos[, 1], corrPos[, 2]), ] 84 | 85 | 86 | res = list(corr=corr, corrPos=corrPos) 87 | 88 | invisible(res) 89 | } 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![R-CMD-check](https://github.com/taiyun/corrplot/workflows/R-CMD-check/badge.svg)](https://github.com/taiyun/corrplot/actions) 2 | [![codecov.io](https://codecov.io/github/taiyun/corrplot/coverage.svg?branch=master)](https://app.codecov.io/github/taiyun/corrplot?branch=master) 3 | [![CRAN Status](https://www.r-pkg.org/badges/version/corrplot)](https://cran.r-project.org/package=corrplot) 4 | [![CRAN Downloads](https://cranlogs.r-pkg.org/badges/corrplot)](https://www.r-pkg.org/pkg/corrplot) 5 | 6 | ## Summary 7 | 8 | R package **corrplot** provides a visual exploratory tool on correlation matrix that 9 | supports automatic variable reordering to help detect hidden patterns among variables. 10 | 11 | corrplot is very easy to use and provides a rich array of plotting options in 12 | visualization method, graphic layout, color, legend, text labels, etc. 13 | It also provides p-values and confidence intervals to help users determine the 14 | statistical significance of the correlations. 15 | 16 | For examples, see its 17 | [online vignette](https://taiyun.github.io/corrplot/). 18 | 19 | 20 | This package is licensed under the MIT license, and available on CRAN: 21 | . 22 | 23 | 24 | 25 | ## Basic example 26 | 27 | ```r 28 | library(corrplot) 29 | M = cor(mtcars) 30 | corrplot(M, order = 'hclust', addrect = 2) 31 | ``` 32 | ![Basic example](https://raw.githubusercontent.com/taiyun/corrplot/master/vignettes/webimg/rectangles-1.png) 33 | 34 | ## Download and Install 35 | 36 | To download the release version of the package on CRAN, type the following at the R command line: 37 | 38 | ```r 39 | install.packages('corrplot') 40 | ``` 41 | 42 | To download the development version of the package, type the following at the R command line: 43 | 44 | ```r 45 | devtools::install_github('taiyun/corrplot', build_vignettes = TRUE) 46 | ``` 47 | 48 | ## How to cite 49 | 50 | To cite `corrplot` properly, call the R built-in command 51 | `citation('corrplot')` as follows: 52 | 53 | ```r 54 | citation('corrplot') 55 | ``` 56 | 57 | ## Reporting bugs and other issues 58 | 59 | If you encounter a clear bug, please file a minimal reproducible example on 60 | [github](https://github.com/taiyun/corrplot/issues). 61 | 62 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: false 6 | patch: false 7 | -------------------------------------------------------------------------------- /corrplot.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | YEAR <- strftime(meta$Date, '%Y') 2 | 3 | # all roles, see also http://www.loc.gov/marc/relators/relaterm.html 4 | ALL <- eval(parse(text = meta$`Authors@R`)) 5 | 6 | # authors only 7 | AUTHORS <- ALL[sapply(ALL$role, function(x) 'aut' %in% x)] 8 | AUTHORS <- paste(AUTHORS$given, AUTHORS$family, collapse = ' and ') 9 | 10 | bibentry('Manual', 11 | key = paste0(meta$Package, YEAR), 12 | title = sprintf('R package \'%s\': %s', meta$Package, meta$Title), 13 | author = AUTHORS, 14 | year = YEAR, 15 | note = sprintf('(Version %s)', meta$Version), 16 | url = meta$URL, 17 | 18 | mheader = sprintf('To cite %s in publications use:', meta$Package), 19 | 20 | textVersion = sprintf( 21 | '%s (%s). R package \'%s\': %s (Version %s). Available from %s', 22 | AUTHORS, YEAR, meta$Package, meta$Title, meta$Version, meta$URL 23 | ) 24 | ) 25 | -------------------------------------------------------------------------------- /inst/NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taiyun/corrplot/62532f700e6c9d04b93ffbf0bf56e264b0e0368e/inst/NEWS -------------------------------------------------------------------------------- /man/col1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/colors.R 3 | \name{COL1} 4 | \alias{COL1} 5 | \title{Get sequential colors} 6 | \usage{ 7 | COL1( 8 | sequential = c("Oranges", "Purples", "Reds", "Blues", "Greens", "Greys", "OrRd", 9 | "YlOrRd", "YlOrBr", "YlGn"), 10 | n = 200 11 | ) 12 | } 13 | \arguments{ 14 | \item{sequential}{Sequential color Palettes} 15 | 16 | \item{n}{the number of colors (>= 1) to be in the palette.} 17 | } 18 | \value{ 19 | A character vector containing color names 20 | } 21 | \description{ 22 | Get sequential colors from palette theme name and n. The color palettes 23 | are from RColorBrewer. Sequential colors are suitable for visualize a non-negative 24 | or non-positive matrix (e.g. matrix in [0, 20], or [-100, -10], or [100, 500]). 25 | } 26 | \examples{ 27 | ## diverging colors 28 | par(mar = c(0, 0, 0, 0) + 0.1) 29 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 30 | 31 | col = c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 32 | 33 | for(i in 1:length(col)) { 34 | colorlegend(COL2(col[i]), -10:10/10, align = 'l', cex = 0.8, xlim = c(0, 1), 35 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 36 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2, cex = 0.8) 37 | } 38 | 39 | 40 | 41 | ## sequential colors 42 | par(mar = c(0, 0, 0, 0) + 0.1) 43 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 44 | 45 | col = c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 46 | 'YlOrRd', 'YlOrBr', 'YlGn') 47 | 48 | for(i in 1:length(col)) { 49 | colorlegend(COL1(col[i]), 0:10, align = 'l', cex = 0.8, xlim = c(0, 1), 50 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 51 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2) 52 | } 53 | 54 | 55 | 56 | ## other examples to show colorlegend function 57 | par(mar = rep(0, 4)) 58 | plot(0, xlim = c(0, 6), ylim = c(-0.5, 1.2), type = 'n') 59 | 60 | colorlegend(rainbow(100), 0:9) 61 | 62 | colorlegend(heat.colors(100), LETTERS[1:12], xlim = c(1, 2)) 63 | 64 | colorlegend(terrain.colors(100), 0:9, ratio.colbar = 0.6, 65 | lim.segment = c(0, 0.6), xlim = c(2, 3), align = 'l') 66 | 67 | colorlegend(topo.colors(100), 0:9, lim.segment = c(0, 0.6), 68 | xlim = c(3, 4), align = 'l', offset = 0) 69 | 70 | colorlegend(cm.colors(100), 1:5, xlim = c(4, 5)) 71 | 72 | colorlegend(sample(rainbow(12)), labels = LETTERS[1:12], 73 | at = seq(0.05, 0.95, len = 12), xlim = c(5, 6), align = 'r') 74 | 75 | colorlegend(colbar = grey(1:100 / 100), 1:10, col = 'red', align = 'l', 76 | xlim = c(0, 6), ylim = c(-0.5, -0.1), vertical = FALSE) 77 | 78 | colorlegend(sample(rainbow(12)), 79 | labels = LETTERS[1:12], at = seq(0.05, 0.95, len = 12), 80 | xlim = c(0, 6), ylim = c(1.1, 1.2), vertical = FALSE) 81 | } 82 | \seealso{ 83 | Function \code{\link{colorRampPalette}}, package \code{RColorBrewer} 84 | } 85 | \keyword{color} 86 | -------------------------------------------------------------------------------- /man/col2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/colors.R 3 | \name{COL2} 4 | \alias{COL2} 5 | \title{Get diverging colors} 6 | \usage{ 7 | COL2(diverging = c("RdBu", "BrBG", "PiYG", "PRGn", "PuOr", "RdYlBu"), n = 200) 8 | } 9 | \arguments{ 10 | \item{diverging}{Diverging color Palettes} 11 | 12 | \item{n}{the number of colors (>= 1) to be in the palette.} 13 | } 14 | \value{ 15 | A character vector containing color names 16 | } 17 | \description{ 18 | Get diverging colors from palette theme name and n. The color palettes 19 | are from RColorBrewer, but with the middle color changing to '#FFFFFF'(white), 20 | thus we can visualize element 0 with white color. 21 | Diverging colors are suitable for visualize a matrix which elements are partly positive and 22 | partly negative (e.g. correlation matrix in [-1, 1], or [-20, 100]). 23 | } 24 | \examples{ 25 | ## diverging colors 26 | par(mar = c(0, 0, 0, 0) + 0.1) 27 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 28 | 29 | col = c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 30 | 31 | for(i in 1:length(col)) { 32 | colorlegend(COL2(col[i]), -10:10/10, align = 'l', cex = 0.8, xlim = c(0, 1), 33 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 34 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2, cex = 0.8) 35 | } 36 | 37 | 38 | 39 | ## sequential colors 40 | par(mar = c(0, 0, 0, 0) + 0.1) 41 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 42 | 43 | col = c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 44 | 'YlOrRd', 'YlOrBr', 'YlGn') 45 | 46 | for(i in 1:length(col)) { 47 | colorlegend(COL1(col[i]), 0:10, align = 'l', cex = 0.8, xlim = c(0, 1), 48 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 49 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2) 50 | } 51 | 52 | 53 | 54 | ## other examples to show colorlegend function 55 | par(mar = rep(0, 4)) 56 | plot(0, xlim = c(0, 6), ylim = c(-0.5, 1.2), type = 'n') 57 | 58 | colorlegend(rainbow(100), 0:9) 59 | 60 | colorlegend(heat.colors(100), LETTERS[1:12], xlim = c(1, 2)) 61 | 62 | colorlegend(terrain.colors(100), 0:9, ratio.colbar = 0.6, 63 | lim.segment = c(0, 0.6), xlim = c(2, 3), align = 'l') 64 | 65 | colorlegend(topo.colors(100), 0:9, lim.segment = c(0, 0.6), 66 | xlim = c(3, 4), align = 'l', offset = 0) 67 | 68 | colorlegend(cm.colors(100), 1:5, xlim = c(4, 5)) 69 | 70 | colorlegend(sample(rainbow(12)), labels = LETTERS[1:12], 71 | at = seq(0.05, 0.95, len = 12), xlim = c(5, 6), align = 'r') 72 | 73 | colorlegend(colbar = grey(1:100 / 100), 1:10, col = 'red', align = 'l', 74 | xlim = c(0, 6), ylim = c(-0.5, -0.1), vertical = FALSE) 75 | 76 | colorlegend(sample(rainbow(12)), 77 | labels = LETTERS[1:12], at = seq(0.05, 0.95, len = 12), 78 | xlim = c(0, 6), ylim = c(1.1, 1.2), vertical = FALSE) 79 | } 80 | \seealso{ 81 | Function \code{\link{colorRampPalette}}, package \code{RColorBrewer} 82 | } 83 | \keyword{color} 84 | -------------------------------------------------------------------------------- /man/colorlegend.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/colorlegend.R 3 | \name{colorlegend} 4 | \alias{colorlegend} 5 | \title{Draw color legend.} 6 | \usage{ 7 | colorlegend( 8 | colbar, 9 | labels, 10 | at = NULL, 11 | xlim = c(0, 1), 12 | ylim = c(0, 1), 13 | vertical = TRUE, 14 | ratio.colbar = 0.4, 15 | lim.segment = "auto", 16 | align = c("c", "l", "r"), 17 | addlabels = TRUE, 18 | ... 19 | ) 20 | } 21 | \arguments{ 22 | \item{colbar}{Vector, color of colbar.} 23 | 24 | \item{labels}{Vector, numeric or character to be written.} 25 | 26 | \item{at}{Numeric vector (quantile), the position to put labels. See examples 27 | for details.} 28 | 29 | \item{xlim}{See in \code{\link{plot}}} 30 | 31 | \item{ylim}{See in \code{\link{plot}}} 32 | 33 | \item{vertical}{Logical, whether the colorlegend is vertical or horizon.} 34 | 35 | \item{ratio.colbar}{The width ratio of colorbar to the total colorlegend 36 | (including colorbar, segments and labels).} 37 | 38 | \item{lim.segment}{Vector (quantile) of length 2, the elements should be in 39 | [0,1], giving segments coordinates ranges. If the value is NULL or 'auto', 40 | then the ranges are derived automatically.} 41 | 42 | \item{align}{Character, alignment type of labels, \code{'l'} means left, 43 | \code{'c'} means center and \code{'r'} right. 44 | Only valid when \code{vertical} is \code{TRUE}.} 45 | 46 | \item{addlabels}{Logical, whether add text label or not.} 47 | 48 | \item{\dots}{Additional arguments, passed to \code{\link{plot}}} 49 | } 50 | \description{ 51 | Draw color legend. 52 | } 53 | \examples{ 54 | ## diverging colors 55 | par(mar = c(0, 0, 0, 0) + 0.1) 56 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 57 | 58 | col = c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 59 | 60 | for(i in 1:length(col)) { 61 | colorlegend(COL2(col[i]), -10:10/10, align = 'l', cex = 0.8, xlim = c(0, 1), 62 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 63 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2, cex = 0.8) 64 | } 65 | 66 | 67 | 68 | ## sequential colors 69 | par(mar = c(0, 0, 0, 0) + 0.1) 70 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 71 | 72 | col = c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 73 | 'YlOrRd', 'YlOrBr', 'YlGn') 74 | 75 | for(i in 1:length(col)) { 76 | colorlegend(COL1(col[i]), 0:10, align = 'l', cex = 0.8, xlim = c(0, 1), 77 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 78 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2) 79 | } 80 | 81 | 82 | 83 | ## other examples to show colorlegend function 84 | par(mar = rep(0, 4)) 85 | plot(0, xlim = c(0, 6), ylim = c(-0.5, 1.2), type = 'n') 86 | 87 | colorlegend(rainbow(100), 0:9) 88 | 89 | colorlegend(heat.colors(100), LETTERS[1:12], xlim = c(1, 2)) 90 | 91 | colorlegend(terrain.colors(100), 0:9, ratio.colbar = 0.6, 92 | lim.segment = c(0, 0.6), xlim = c(2, 3), align = 'l') 93 | 94 | colorlegend(topo.colors(100), 0:9, lim.segment = c(0, 0.6), 95 | xlim = c(3, 4), align = 'l', offset = 0) 96 | 97 | colorlegend(cm.colors(100), 1:5, xlim = c(4, 5)) 98 | 99 | colorlegend(sample(rainbow(12)), labels = LETTERS[1:12], 100 | at = seq(0.05, 0.95, len = 12), xlim = c(5, 6), align = 'r') 101 | 102 | colorlegend(colbar = grey(1:100 / 100), 1:10, col = 'red', align = 'l', 103 | xlim = c(0, 6), ylim = c(-0.5, -0.1), vertical = FALSE) 104 | 105 | colorlegend(sample(rainbow(12)), 106 | labels = LETTERS[1:12], at = seq(0.05, 0.95, len = 12), 107 | xlim = c(0, 6), ylim = c(1.1, 1.2), vertical = FALSE) 108 | } 109 | \author{ 110 | Taiyun Wei 111 | } 112 | \keyword{hplot} 113 | -------------------------------------------------------------------------------- /man/cor.mtest.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cor-mtest.R 3 | \name{cor.mtest} 4 | \alias{cor.mtest} 5 | \title{Significance test which produces p-values and confidence intervals for each 6 | pair of input features.} 7 | \usage{ 8 | cor.mtest(mat, ...) 9 | } 10 | \arguments{ 11 | \item{mat}{Input matrix of size \code{NxF}, 12 | with \code{N} rows that represent samples 13 | and \code{F} columns that represent features.} 14 | 15 | \item{\dots}{Additional arguments passed to function \code{\link{cor.test}}, 16 | e.g. \code{conf.level = 0.95}.} 17 | } 18 | \value{ 19 | Return a list containing: 20 | \item{p}{Square matrix of size \code{FxF} with p-values as cells} 21 | \item{lowCI}{Square matrix of size \code{FxF}, each cell represents the 22 | \emph{lower part} of a confidence interval} 23 | \item{uppCI}{Square matrix of size \code{FxF}, each cell represents the 24 | \emph{upper part} of a confidence interval} 25 | } 26 | \description{ 27 | Significance test which produces p-values and confidence intervals for each 28 | pair of input features. 29 | } 30 | \seealso{ 31 | Function \code{\link{cor.test}} 32 | } 33 | \keyword{confidence} 34 | \keyword{p-value} 35 | \keyword{significance} 36 | -------------------------------------------------------------------------------- /man/corrMatOrder.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/corrMatOrder.R 3 | \name{corrMatOrder} 4 | \alias{corrMatOrder} 5 | \title{Reorder a correlation matrix.} 6 | \usage{ 7 | corrMatOrder( 8 | corr, 9 | order = c("AOE", "FPC", "hclust", "alphabet"), 10 | hclust.method = c("complete", "ward", "ward.D", "ward.D2", "single", "average", 11 | "mcquitty", "median", "centroid") 12 | ) 13 | } 14 | \arguments{ 15 | \item{corr}{Correlation matrix to reorder.} 16 | 17 | \item{order}{Character, the ordering method for the correlation matrix. 18 | \itemize{ 19 | \item{\code{'AOE'} for the angular order of the eigenvectors. 20 | It is calculated from the order of the angles, \eqn{a_i}: 21 | \deqn{ a_i = arctan (e_{i2} / e_{i1}), if e_{i1} > 0} 22 | \deqn{ a_i = arctan (e_{i2} / e_{i1}) + \pi, otherwise.} 23 | where \eqn{e_1} and \eqn{e_2} are the largest two eigenvalues 24 | of matrix \code{corr}. 25 | See Michael Friendly (2002) for details.} 26 | \item{\code{'FPC'} for the first principal component order.} 27 | \item{\code{'hclust'} for hierarchical clustering order.} 28 | \item{\code{'alphabet'} for alphabetical order.} 29 | }} 30 | 31 | \item{hclust.method}{Character, the agglomeration method to be used when 32 | \code{order} is \code{hclust}. This should be one of \code{'ward'}, 33 | \code{'ward.D'}, \code{'ward.D2'}, \code{'single'}, \code{'complete'}, 34 | \code{'average'}, \code{'mcquitty'}, \code{'median'} or \code{'centroid'}.} 35 | } 36 | \value{ 37 | Returns a single permutation vector. 38 | } 39 | \description{ 40 | Draw rectangle(s) around the chart of corrrlation matrix based on the number 41 | of each cluster's members. 42 | } 43 | \examples{ 44 | M = cor(mtcars) 45 | 46 | (order.AOE = corrMatOrder(M, order = 'AOE')) 47 | (order.FPC = corrMatOrder(M, order = 'FPC')) 48 | (order.hc = corrMatOrder(M, order = 'hclust')) 49 | (order.hc2 = corrMatOrder(M, order = 'hclust', hclust.method = 'ward.D')) 50 | 51 | M.AOE = M[order.AOE, order.AOE] 52 | M.FPC = M[order.FPC, order.FPC] 53 | M.hc = M[order.hc, order.hc] 54 | M.hc2 = M[order.hc2, order.hc2] 55 | 56 | 57 | 58 | par(ask = TRUE) 59 | corrplot(M) 60 | corrplot(M.AOE) 61 | corrplot(M.FPC) 62 | corrplot(M.hc) 63 | 64 | corrplot(M.hc) 65 | corrRect.hclust(corr = M.hc, k = 2) 66 | 67 | corrplot(M.hc) 68 | corrRect.hclust(corr = M.hc, k = 3) 69 | 70 | corrplot(M.hc2) 71 | corrRect.hclust(M.hc2, k = 2, method = 'ward.D') 72 | } 73 | \seealso{ 74 | Package \code{seriation} offers more methods to reorder matrices, 75 | such as ARSA, BBURCG, BBWRCG, MDS, TSP, Chen and so forth. 76 | } 77 | \author{ 78 | Taiyun Wei 79 | } 80 | \keyword{hplot} 81 | -------------------------------------------------------------------------------- /man/corrRect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/corrRect.R 3 | \name{corrRect} 4 | \alias{corrRect} 5 | \title{Draw rectangle(s) on the correlation matrix graph.} 6 | \usage{ 7 | corrRect( 8 | corrRes = NULL, 9 | index = NULL, 10 | name = NULL, 11 | namesMat = NULL, 12 | col = "black", 13 | lwd = 2, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{corrRes}{List of the \code{corrplot()} returns.} 19 | 20 | \item{index}{Vector, variable index of diag rect \code{c(Rect1from, Rect2from, 21 | Rect3from, ..., RectNto)} on the correlation matrix graph. 22 | It works when the colnames are the same as rownames, or both of them is NULL. 23 | It needs \code{corrRes} inputted.} 24 | 25 | \item{name}{Vector, variable name of diag rect \code{c(Rect1from, Rect2from, 26 | Rect3from, ..., RectNto)} on the correlation matrix graph. 27 | OIt works when the colnames are the same as rownames. 28 | It needs \code{corrRes} inputted.} 29 | 30 | \item{namesMat}{4-length character vector or 4-columns character matrix, 31 | represents the names of xleft, ybottom, xright, ytop correspondingly. 32 | It needs \code{corrRes} inputted.} 33 | 34 | \item{col}{Color of rectangles.} 35 | 36 | \item{lwd}{Line width of rectangles.} 37 | 38 | \item{\dots}{Additional arguments passing to function \code{rect()}.} 39 | } 40 | \value{ 41 | (Invisibly) returns input parameter \code{corrRes}, 42 | usually \code{list(corr, corrTrans, arg)}. 43 | } 44 | \description{ 45 | Draw rectangle(s) after the correlation matrix plotted. SUGGESTION: It's more convenient 46 | to draw rectangle(s) by using pipe operator `|>` since R 4.1.0. 47 | } 48 | \details{ 49 | \code{corrRect} needs one of \code{index}, \code{name} and \code{namesMat} inputted. 50 | While \code{corrRect.hclust} can get the members in each cluster 51 | based on hierarchical clustering (\code{\link{hclust}}). 52 | } 53 | \examples{ 54 | data(mtcars) 55 | M = cor(mtcars) 56 | 57 | r = rbind(c('gear', 'wt', 'qsec', 'carb'), 58 | c('wt', 'gear', 'carb', 'qsec')) 59 | corrplot(M, order = 'AOE') -> p 60 | corrRect(p, namesMat = r) 61 | 62 | # same as using pipe operator `|>` if R version >= 4.1.0: 63 | # corrplot(M, order = 'AOE') |> corrRect(namesMat = r) 64 | 65 | 66 | 67 | r = c('gear', 'carb', 'qsec', 'wt') 68 | corrplot(M, order = 'AOE', type='lower') -> p 69 | corrRect(p, namesMat = r) 70 | 71 | # same as using pipe operator `|>` if R version >= 4.1.0: 72 | # corrplot(M, order = 'AOE', type='lower') |> corrRect(namesMat = r) 73 | 74 | 75 | 76 | corrplot(M, order = 'hclust', type = 'upper') -> p 77 | corrRect(p, index = c(1, 6, 11)) 78 | 79 | # same as using pipe operator `|>` if R version >= 4.1.0: 80 | # corrplot(M, order = 'AOE', type='lower') |> corrRect(index = c(1, 6, 11)) 81 | 82 | 83 | 84 | corrplot(M, order = 'hclust') -> p 85 | corrRect(p, name = c('carb', 'qsec', 'gear')) 86 | 87 | # same as using pipe operator `|>` if R version >= 4.1.0: 88 | # corrplot(M, order = 'hclust') |> corrRect(name = c('carb', 'qsec', 'gear')) 89 | 90 | 91 | 92 | 93 | (order.hc = corrMatOrder(M, order = 'hclust')) 94 | (order.hc2 = corrMatOrder(M, order = 'hclust', hclust.method = 'ward.D')) 95 | M.hc = M[order.hc, order.hc] 96 | M.hc2 = M[order.hc2, order.hc2] 97 | 98 | par(ask = TRUE) 99 | 100 | # same as: corrplot(M, order = 'hclust', addrect = 2) 101 | corrplot(M.hc) 102 | corrRect.hclust(corr = M.hc, k = 2) 103 | 104 | # same as: corrplot(M, order = 'hclust', addrect = 3) 105 | corrplot(M.hc) 106 | corrRect.hclust(corr = M.hc, k = 3) 107 | 108 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D', addrect = 2) 109 | corrplot(M.hc2) 110 | corrRect.hclust(M.hc2, k = 2, method = 'ward.D') 111 | 112 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D', addrect = 3) 113 | corrplot(M.hc2) 114 | corrRect.hclust(M.hc2, k = 3, method = 'ward.D') 115 | 116 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D', addrect = 4) 117 | corrplot(M.hc2) 118 | corrRect.hclust(M.hc2, k = 4, method = 'ward.D') 119 | } 120 | \author{ 121 | Taiyun Wei 122 | } 123 | \keyword{hplot} 124 | -------------------------------------------------------------------------------- /man/corrRect.hclust.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/corrRect.hclust.R 3 | \name{corrRect.hclust} 4 | \alias{corrRect.hclust} 5 | \title{Draw rectangles on the correlation matrix graph.} 6 | \usage{ 7 | corrRect.hclust( 8 | corr, 9 | k = 2, 10 | col = "black", 11 | lwd = 2, 12 | method = c("complete", "ward", "ward.D", "ward.D2", "single", "average", "mcquitty", 13 | "median", "centroid") 14 | ) 15 | } 16 | \arguments{ 17 | \item{corr}{Correlation matrix for function \code{corrRect.hclust}. It use 18 | \code{1-corr} as dist in hierarchical clustering (\code{\link{hclust}}).} 19 | 20 | \item{k}{Integer, the number of rectangles drawn on the graph according to 21 | the hierarchical cluster, for function \code{corrRect.hclust}.} 22 | 23 | \item{col}{Color of rectangles.} 24 | 25 | \item{lwd}{Line width of rectangles.} 26 | 27 | \item{method}{Character, the agglomeration method to be used for hierarchical 28 | clustering (\code{\link{hclust}}). This should be (an unambiguous 29 | abbreviation of) one of \code{'ward'}, \code{'ward.D'}, \code{'ward.D2'}, 30 | \code{'single'}, \code{'complete'}, \code{'average'}, \code{'mcquitty'}, 31 | \code{'median'} or \code{'centroid'}.} 32 | } 33 | \description{ 34 | Draw rectangles on the correlation matrix graph based on hierarchical cluster 35 | (\code{\link{hclust}}). 36 | } 37 | \examples{ 38 | data(mtcars) 39 | M = cor(mtcars) 40 | corrplot(M, order = 'FPC') -> p 41 | corrRect(p, index = c(1, 6, 11)) 42 | 43 | if(getRversion() >= '4.1.0') { 44 | corrplot(M, order = 'FPC') |> corrRect(index = c(1, 6, 11)) 45 | } 46 | 47 | (order.hc = corrMatOrder(M, order = 'hclust')) 48 | (order.hc2 = corrMatOrder(M, order = 'hclust', hclust.method = 'ward.D2')) 49 | M.hc = M[order.hc, order.hc] 50 | M.hc2 = M[order.hc2, order.hc2] 51 | 52 | par(ask = TRUE) 53 | 54 | # same as: corrplot(M, order = 'hclust', addrect = 2) 55 | corrplot(M.hc) 56 | corrRect.hclust(corr = M.hc, k = 2) 57 | 58 | # same as: corrplot(M, order = 'hclust', addrect = 3) 59 | corrplot(M.hc) 60 | corrRect.hclust(corr = M.hc, k = 3) 61 | 62 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 2) 63 | corrplot(M.hc2) 64 | corrRect.hclust(M.hc2, k = 2, method = 'ward.D2') 65 | 66 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 3) 67 | corrplot(M.hc2) 68 | corrRect.hclust(M.hc2, k = 3, method = 'ward.D2') 69 | 70 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 4) 71 | corrplot(M.hc2) 72 | corrRect.hclust(M.hc2, k = 4, method = 'ward.D2') 73 | } 74 | \author{ 75 | Taiyun Wei 76 | } 77 | \keyword{hplot} 78 | -------------------------------------------------------------------------------- /man/corrplot-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/corrplot-package.R 3 | \docType{package} 4 | \name{corrplot-package} 5 | \alias{corrplot-package} 6 | \title{Visualization of a correlation matrix} 7 | \description{ 8 | The corrplot package is a graphical display of a correlation matrix, 9 | confidence interval or general matrix. It also contains some algorithms to do 10 | matrix reordering. In addition, corrplot is good at details, including 11 | choosing color, text labels, color labels, layout, etc. 12 | } 13 | \references{ 14 | Michael Friendly (2002). 15 | \emph{Corrgrams: Exploratory displays for correlation matrices}. 16 | The American Statistician, 56, 316--324. 17 | 18 | D.J. Murdoch, E.D. Chow (1996). 19 | \emph{A graphical display of large correlation matrices}. 20 | The American Statistician, 50, 178--180. 21 | } 22 | \seealso{ 23 | The \code{plotcorr} function in the \code{ellipse} package and 24 | \code{corrgram} function in the \code{corrgram} package has some 25 | similarities. 26 | } 27 | \author{ 28 | Taiyun Wei (weitaiyun@gmail.com) 29 | 30 | Viliam Simko (viliam.simko@gmail.com) 31 | 32 | Maintainer: Taiyun Wei (weitaiyun@gmail.com) 33 | } 34 | \keyword{correlation} 35 | \keyword{correlogram} 36 | \keyword{dimensionality} 37 | \keyword{feature} 38 | \keyword{hplot} 39 | \keyword{reduction} 40 | \keyword{selection} 41 | -------------------------------------------------------------------------------- /man/corrplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/corrplot.R 3 | \name{corrplot} 4 | \alias{corrplot} 5 | \title{A visualization of a correlation matrix.} 6 | \usage{ 7 | corrplot( 8 | corr, 9 | method = c("circle", "square", "ellipse", "number", "shade", "color", "pie"), 10 | type = c("full", "lower", "upper"), 11 | col = NULL, 12 | col.lim = NULL, 13 | is.corr = TRUE, 14 | bg = "white", 15 | title = "", 16 | add = FALSE, 17 | diag = TRUE, 18 | outline = FALSE, 19 | mar = c(0, 0, 0, 0), 20 | addgrid.col = NULL, 21 | addCoef.col = NULL, 22 | addCoefasPercent = FALSE, 23 | order = c("original", "AOE", "FPC", "hclust", "alphabet"), 24 | hclust.method = c("complete", "ward", "ward.D", "ward.D2", "single", "average", 25 | "mcquitty", "median", "centroid"), 26 | addrect = NULL, 27 | rect.col = "black", 28 | rect.lwd = 2, 29 | tl.pos = NULL, 30 | tl.cex = 1, 31 | tl.col = "red", 32 | tl.offset = 0.4, 33 | tl.srt = 90, 34 | cl.pos = NULL, 35 | cl.length = NULL, 36 | cl.cex = 0.8, 37 | cl.ratio = 0.15, 38 | cl.align.text = "c", 39 | cl.offset = 0.5, 40 | number.cex = 1, 41 | number.font = 2, 42 | number.digits = NULL, 43 | addshade = c("negative", "positive", "all"), 44 | shade.lwd = 1, 45 | shade.col = "white", 46 | transKeepSign = TRUE, 47 | p.mat = NULL, 48 | sig.level = 0.05, 49 | insig = c("pch", "p-value", "blank", "n", "label_sig"), 50 | pch = 4, 51 | pch.col = "black", 52 | pch.cex = 3, 53 | plotCI = c("n", "square", "circle", "rect"), 54 | lowCI.mat = NULL, 55 | uppCI.mat = NULL, 56 | na.label = "?", 57 | na.label.col = "black", 58 | win.asp = 1, 59 | ... 60 | ) 61 | } 62 | \arguments{ 63 | \item{corr}{The correlation matrix to visualize, must be square if 64 | \code{order} is not \code{'original'}. For general matrix, please using 65 | \code{is.corr = FALSE} to convert.} 66 | 67 | \item{method}{Character, the visualization method of correlation matrix to be 68 | used. Currently, it supports seven methods, named \code{'circle'} 69 | (default), \code{'square'}, \code{'ellipse'}, \code{'number'}, 70 | \code{'pie'}, \code{'shade'} and \code{'color'}. See examples for details. 71 | 72 | The areas of circles or squares show the absolute value of corresponding 73 | correlation coefficients. Method \code{'pie'} and \code{'shade'} came from 74 | Michael Friendly's job (with some adjustment about the shade added on), and 75 | \code{'ellipse'} came from D.J. Murdoch and E.D. Chow's job, see in section 76 | References.} 77 | 78 | \item{type}{Character, \code{'full'} (default), \code{'upper'} or 79 | \code{'lower'}, display full matrix, lower triangular or upper triangular 80 | matrix.} 81 | 82 | \item{col}{Vector, the colors of glyphs. They are distributed uniformly in 83 | \code{col.lim} interval. 84 | If \code{is.corr} is \code{TRUE}, the default value will be \code{COL2('RdBu', 200)}. 85 | If \code{is.corr} is \code{FALSE} and \code{corr} is a non-negative or non-positive matrix, 86 | the default value will be \code{COL1('YlOrBr', 200)}; 87 | otherwise (elements are partly positive and partly negative), 88 | the default value will be \code{COL2('RdBu', 200)}.} 89 | 90 | \item{col.lim}{The limits \code{(x1, x2)} interval for assigning color by 91 | \code{col}. If \code{NULL}, 92 | \code{col.lim} will be \code{c(-1, 1)} when \code{is.corr} is \code{TRUE}, 93 | \code{col.lim} will be \code{c(min(corr), max(corr))} when \code{is.corr} 94 | is \code{FALSE} 95 | 96 | NOTICE: if you set \code{col.lim} when \code{is.corr} is \code{TRUE}, the assigning colors 97 | are still distributed uniformly in [-1, 1], it only affect the display 98 | on color-legend.} 99 | 100 | \item{is.corr}{Logical, whether the input matrix is a correlation matrix or 101 | not. We can visualize the non-correlation matrix by setting 102 | \code{is.corr = FALSE}.} 103 | 104 | \item{bg}{The background color.} 105 | 106 | \item{title}{Character, title of the graph.} 107 | 108 | \item{add}{Logical, if \code{TRUE}, the graph is added to an existing plot, 109 | otherwise a new plot will be created.} 110 | 111 | \item{diag}{Logical, whether display the correlation coefficients on the 112 | principal diagonal.} 113 | 114 | \item{outline}{Logical or character, whether plot outline of circles, square 115 | and ellipse, or the color of these glyphs. For pie, this represents the 116 | color of the circle outlining the pie. If \code{outline} is \code{TRUE}, 117 | the default value is \code{'black'}.} 118 | 119 | \item{mar}{See \code{\link{par}}.} 120 | 121 | \item{addgrid.col}{The color of the grid. If \code{NA}, don't add grid. If 122 | \code{NULL} the default value is chosen. The default value depends on 123 | \code{method}, if \code{method} is \code{color} or \code{shade}, the color 124 | of the grid is \code{NA}, that is, not draw grid; otherwise \code{'grey'}.} 125 | 126 | \item{addCoef.col}{Color of coefficients added on the graph. If \code{NULL} 127 | (default), add no coefficients.} 128 | 129 | \item{addCoefasPercent}{Logic, whether translate coefficients into percentage 130 | style for spacesaving.} 131 | 132 | \item{order}{Character, the ordering method of the correlation matrix. 133 | \itemize{ 134 | \item{\code{'original'} for original order (default).} 135 | \item{\code{'AOE'} for the angular order of the eigenvectors.} 136 | \item{\code{'FPC'} for the first principal component order.} 137 | \item{\code{'hclust'} for the hierarchical clustering order.} 138 | \item{\code{'alphabet'} for alphabetical order.} 139 | } 140 | 141 | See function \code{\link{corrMatOrder}} for details.} 142 | 143 | \item{hclust.method}{Character, the agglomeration method to be used when 144 | \code{order} is \code{\link{hclust}}. This should be one of \code{'ward'}, 145 | \code{'ward.D'}, \code{'ward.D2'}, \code{'single'}, \code{'complete'}, 146 | \code{'average'}, \code{'mcquitty'}, \code{'median'} or \code{'centroid'}.} 147 | 148 | \item{addrect}{Integer, the number of rectangles draws on the graph according 149 | to the hierarchical cluster, only valid when \code{order} is \code{hclust}. 150 | If \code{NULL} (default), then add no rectangles.} 151 | 152 | \item{rect.col}{Color for rectangle border(s), only valid when \code{addrect} 153 | is equal or greater than 1.} 154 | 155 | \item{rect.lwd}{Numeric, line width for borders for rectangle border(s), only 156 | valid when \code{addrect} is equal or greater than 1.} 157 | 158 | \item{tl.pos}{Character or logical, position of text labels. If character, it 159 | must be one of \code{'lt'}, \code{'ld'}, \code{'td'}, \code{'d'} or 160 | \code{'n'}. \code{'lt'}(default if \code{type=='full'}) means left and top, 161 | \code{'ld'}(default if \code{type=='lower'}) means left and diagonal, 162 | \code{'td'}(default if \code{type=='upper'}) means top and diagonal(near), 163 | \code{'l'} means left, 164 | \code{'d'} means diagonal, \code{'n'} means don't add text-label.} 165 | 166 | \item{tl.cex}{Numeric, for the size of text label (variable names).} 167 | 168 | \item{tl.col}{The color of text label.} 169 | 170 | \item{tl.offset}{Numeric, for text label, see \code{\link{text}}.} 171 | 172 | \item{tl.srt}{Numeric, for text label string rotation in degrees, see 173 | \code{\link{text}}.} 174 | 175 | \item{cl.pos}{Character or logical, position of color-legend; If character, 176 | it must be one of \code{'r'} (default if \code{type=='upper'} or 177 | \code{'full'}), \code{'b'} (default if \code{type=='lower'}) or \code{'n'}, 178 | \code{'n'} means don't draw color-legend.} 179 | 180 | \item{cl.length}{Integer, the number of number-text in color-legend, passed to 181 | \code{\link{colorlegend}}. If \code{NULL}, \code{cl.length} is 182 | \code{length(col) + 1} when \code{length(col) <=20}; \code{cl.length} is 11 183 | when \code{length(col) > 20}} 184 | 185 | \item{cl.cex}{Numeric, text size of number-label in color-legend, passed to 186 | \code{\link{colorlegend}}.} 187 | 188 | \item{cl.ratio}{Numeric, to justify the width of color-legend, 0.1~0.2 is 189 | suggested.} 190 | 191 | \item{cl.align.text}{Character, \code{'l'}, \code{'c'} (default) or 192 | \code{'r'}, for number-label in color-legend, \code{'l'} means left, 193 | \code{'c'} means center, and \code{'r'} means right.} 194 | 195 | \item{cl.offset}{Numeric, for number-label in color-legend, see 196 | \code{\link{text}}.} 197 | 198 | \item{number.cex}{The \code{cex} parameter to send to the call to \code{text} 199 | when writing the correlation coefficients into the plot.} 200 | 201 | \item{number.font}{the \code{font} parameter to send to the call to 202 | \code{text} when writing the correlation coefficients into the plot.} 203 | 204 | \item{number.digits}{indicating the number of decimal digits to be 205 | added into the plot. Non-negative integer or NULL, default NULL.} 206 | 207 | \item{addshade}{Character for shade style, \code{'negative'}, 208 | \code{'positive'} or \code{'all'}, only valid when \code{method} is 209 | \code{'shade'}. If \code{'all'}, all correlation coefficients' glyph will 210 | be shaded; if \code{'positive'}, only the positive will be shaded; if 211 | \code{'negative'}, only the negative will be shaded. Note: the angle of 212 | shade line is different, 45 degrees for positive and 135 degrees for 213 | negative.} 214 | 215 | \item{shade.lwd}{Numeric, the line width of shade.} 216 | 217 | \item{shade.col}{The color of shade line.} 218 | 219 | \item{transKeepSign}{Logical, whether or not to keep matrix values' sign when 220 | transforming non-corr matrix for plotting. 221 | Only valid when \code{is.corr = FALSE}. The default value is \code{TRUE}. 222 | 223 | NOTE: If \code{FALSE},the non-corr matrix will be} 224 | 225 | \item{p.mat}{Matrix of p-value, if \code{NULL}, parameter \code{sig.level}, 226 | \code{insig}, \code{pch}, \code{pch.col}, \code{pch.cex} are invalid.} 227 | 228 | \item{sig.level}{Significant level, if the p-value in \code{p-mat} is bigger 229 | than \code{sig.level}, then the corresponding correlation coefficient is 230 | regarded as insignificant. If \code{insig} is \code{'label_sig'}, this may 231 | be an increasing vector of significance levels, in which case \code{pch} 232 | will be used once for the highest p-value interval and multiple times 233 | (e.g. '*', '**', '***') for each lower p-value interval.} 234 | 235 | \item{insig}{Character, specialized insignificant correlation coefficients, 236 | \code{'pch'} (default), \code{'p-value'}, \code{'blank'}, \code{'n'}, or 237 | \code{'label_sig'}. If \code{'blank'}, wipe away the corresponding glyphs; 238 | if \code{'p-value'}, add p-values the corresponding glyphs; 239 | if \code{'pch'}, add characters (see \code{pch} for details) on 240 | corresponding glyphs; if \code{'n'}, don't take any measures; if 241 | \code{'label_sig'}, mark significant correlations with pch 242 | (see \code{sig.level}).} 243 | 244 | \item{pch}{Add character on the glyphs of insignificant correlation 245 | coefficients(only valid when \code{insig} is \code{'pch'}). See 246 | \code{\link{par}}.} 247 | 248 | \item{pch.col}{The color of pch (only valid when \code{insig} is 249 | \code{'pch'}).} 250 | 251 | \item{pch.cex}{The cex of pch (only valid when \code{insig} is \code{'pch'}).} 252 | 253 | \item{plotCI}{Character, method of ploting confidence interval. If 254 | \code{'n'}, don't plot confidence interval. If 'rect', plot rectangles 255 | whose upper side means upper bound and lower side means lower bound, 256 | respectively. If 'circle', first plot a circle with the bigger absolute 257 | bound, and then plot the smaller. Warning: if the two bounds are the same 258 | sign, the smaller circle will be wiped away, thus forming a ring. Method 259 | 'square' is similar to 'circle'.} 260 | 261 | \item{lowCI.mat}{Matrix of the lower bound of confidence interval.} 262 | 263 | \item{uppCI.mat}{Matrix of the upper bound of confidence interval.} 264 | 265 | \item{na.label}{Label to be used for rendering \code{NA} cells. Default is 266 | \code{'?'}. If 'square', then the cell is rendered as a square with the 267 | \code{na.label.col} color.} 268 | 269 | \item{na.label.col}{Color used for rendering \code{NA} cells. Default is 270 | \code{'black'}.} 271 | 272 | \item{win.asp}{Aspect ration for the whole plot. Value other than 1 is 273 | currently compatible only with methods 'circle' and 'square'.} 274 | 275 | \item{\dots}{Additional arguments passing to function \code{text} for drawing 276 | text label.} 277 | } 278 | \value{ 279 | (Invisibly) returns a \code{list(corr, corrTrans, arg)}. 280 | \code{corr} is a reordered correlation matrix for plotting. 281 | \code{corrPos} is a data frame with \code{xName, yName, x, y, corr} and 282 | \code{p.value}(if p.mat is not NULL) 283 | column, which x and y are the position on the correlation matrix plot. 284 | \code{arg} is a list of some corrplot() input parameters' value. 285 | Now \code{type} is in. 286 | } 287 | \description{ 288 | A graphical display of a correlation matrix, confidence interval. The details 289 | are paid great attention to. It can also visualize a general matrix by 290 | setting \code{is.corr = FALSE}. 291 | } 292 | \details{ 293 | \code{corrplot} function offers flexible ways to visualize 294 | correlation matrix, lower and upper bound of confidence interval matrix. 295 | } 296 | \note{ 297 | \code{Cairo} and \code{cairoDevice} packages is strongly recommended to 298 | produce high-quality PNG, JPEG, TIFF bitmap files, especially for that 299 | \code{method} \code{circle}, \code{ellipse}. 300 | 301 | Row- and column names of the input matrix are used as labels rendered 302 | in the corrplot. Plothmath expressions will be used if the name is prefixed 303 | by one of the following characters: \code{:}, \code{=} or \code{$}. 304 | For example \code{':alpha + beta'}. 305 | } 306 | \examples{ 307 | data(mtcars) 308 | M = cor(mtcars) 309 | set.seed(0) 310 | 311 | ## different color series 312 | ## COL2: Get diverging colors 313 | ## c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 314 | ## COL1: Get sequential colors 315 | ## c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 'YlOrRd', 'YlOrBr', 'YlGn') 316 | 317 | wb = c('white', 'black') 318 | 319 | par(ask = TRUE) 320 | 321 | ## different color scale and methods to display corr-matrix 322 | corrplot(M, method = 'number', col = 'black', cl.pos = 'n') 323 | corrplot(M, method = 'number') 324 | corrplot(M) 325 | corrplot(M, order = 'AOE') 326 | corrplot(M, order = 'AOE', addCoef.col = 'grey') 327 | 328 | corrplot(M, order = 'AOE', cl.length = 21, addCoef.col = 'grey') 329 | corrplot(M, order = 'AOE', col = COL2(n=10), addCoef.col = 'grey') 330 | 331 | corrplot(M, order = 'AOE', col = COL2('PiYG')) 332 | corrplot(M, order = 'AOE', col = COL2('PRGn'), addCoef.col = 'grey') 333 | corrplot(M, order = 'AOE', col = COL2('PuOr', 20), cl.length = 21, addCoef.col = 'grey') 334 | corrplot(M, order = 'AOE', col = COL2('PuOr', 10), addCoef.col = 'grey') 335 | 336 | corrplot(M, order = 'AOE', col = COL2('RdYlBu', 100)) 337 | corrplot(M, order = 'AOE', col = COL2('RdYlBu', 10)) 338 | 339 | 340 | corrplot(M, method = 'color', col = COL2(n=20), cl.length = 21, order = 'AOE', 341 | addCoef.col = 'grey') 342 | corrplot(M, method = 'square', col = COL2(n=200), order = 'AOE') 343 | corrplot(M, method = 'ellipse', col = COL2(n=200), order = 'AOE') 344 | corrplot(M, method = 'shade', col = COL2(n=20), order = 'AOE') 345 | corrplot(M, method = 'pie', order = 'AOE') 346 | 347 | ## col = wb 348 | corrplot(M, col = wb, order = 'AOE', outline = TRUE, cl.pos = 'n') 349 | 350 | ## like Chinese wiqi, suit for either on screen or white-black print. 351 | corrplot(M, col = wb, bg = 'gold2', order = 'AOE', cl.pos = 'n') 352 | 353 | 354 | ## mixed methods: It's more efficient if using function 'corrplot.mixed' 355 | ## circle + ellipse 356 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'd') 357 | corrplot(M, add = TRUE, type = 'lower', method = 'ellipse', order = 'AOE', 358 | diag = FALSE, tl.pos = 'n', cl.pos = 'n') 359 | 360 | ## circle + square 361 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'd') 362 | corrplot(M, add = TRUE, type = 'lower', method = 'square', order = 'AOE', 363 | diag = FALSE, tl.pos = 'n', cl.pos = 'n') 364 | 365 | ## circle + colorful number 366 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'd') 367 | corrplot(M, add = TRUE, type = 'lower', method = 'number', order = 'AOE', 368 | diag = FALSE, tl.pos = 'n', cl.pos = 'n') 369 | 370 | ## circle + black number 371 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'tp') 372 | corrplot(M, add = TRUE, type = 'lower', method = 'number', order = 'AOE', 373 | col = 'black', diag = FALSE, tl.pos = 'n', cl.pos = 'n') 374 | 375 | 376 | ## order is hclust and draw rectangles 377 | corrplot(M, order = 'hclust') 378 | corrplot(M, order = 'hclust', addrect = 2) 379 | corrplot(M, order = 'hclust', addrect = 3, rect.col = 'red') 380 | corrplot(M, order = 'hclust', addrect = 4, rect.col = 'blue') 381 | corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 4) 382 | 383 | ## visualize a matrix in [0, 1] 384 | corrplot(abs(M), order = 'AOE', col.lim = c(0, 1)) 385 | corrplot(abs(M), order = 'AOE', is.corr = FALSE, col.lim = c(0, 1)) 386 | 387 | 388 | # when is.corr=TRUE, col.lim only affect the color legend 389 | # If you change it, the color is still assigned on [-1, 1] 390 | corrplot(M/2) 391 | corrplot(M/2, col.lim = c(-0.5, 0.5)) 392 | 393 | # when is.corr=FALSE, col.lim is also used to assign colors 394 | # if the matrix have both positive and negative values 395 | # the matrix transformation keep every values positive and negative 396 | corrplot(M*2, is.corr = FALSE, col.lim = c(-2, 2)) 397 | corrplot(M*2, is.corr = FALSE, col.lim = c(-2, 2) * 2) 398 | corrplot(M*2, is.corr = FALSE, col.lim = c(-2, 2) * 4) 399 | 400 | ## 0.5~0.6 401 | corrplot(abs(M)/10+0.5, col = COL1('Greens', 10)) 402 | corrplot(abs(M)/10+0.5, is.corr = FALSE, col.lim = c(0.5, 0.6), col = COL1('YlGn', 10)) 403 | 404 | 405 | ## visualize a matrix in [-100, 100] 406 | ran = round(matrix(runif(225, -100, 100), 15)) 407 | corrplot(ran, is.corr = FALSE) 408 | corrplot(ran, is.corr = FALSE, col.lim = c(-100, 100)) 409 | 410 | ## visualize a matrix in [100, 300] 411 | ran2 = ran + 200 412 | 413 | # bad color, not suitable for a matrix in [100, 300] 414 | corrplot(ran2, is.corr = FALSE, col.lim = c(100, 300), col = COL2(, 100)) 415 | 416 | # good color 417 | corrplot(ran2, is.corr = FALSE, col.lim = c(100, 300), col = COL1(, 100)) 418 | 419 | 420 | ## text-labels and plot type 421 | corrplot(M, order = 'AOE', tl.srt = 45) 422 | corrplot(M, order = 'AOE', tl.srt = 60) 423 | corrplot(M, order = 'AOE', tl.pos = 'd', cl.pos = 'n') 424 | corrplot(M, order = 'AOE', diag = FALSE, tl.pos = 'd') 425 | corrplot(M, order = 'AOE', type = 'upper') 426 | corrplot(M, order = 'AOE', type = 'upper', diag = FALSE) 427 | corrplot(M, order = 'AOE', type = 'lower', cl.pos = 'b') 428 | corrplot(M, order = 'AOE', type = 'lower', cl.pos = 'b', diag = FALSE) 429 | 430 | 431 | 432 | #### color-legend 433 | corrplot(M, order = 'AOE', cl.ratio = 0.2, cl.align = 'l') 434 | corrplot(M, order = 'AOE', cl.ratio = 0.2, cl.align = 'c') 435 | corrplot(M, order = 'AOE', cl.ratio = 0.2, cl.align = 'r') 436 | corrplot(M, order = 'AOE', cl.pos = 'b') 437 | corrplot(M, order = 'AOE', cl.pos = 'b', tl.pos = 'd') 438 | corrplot(M, order = 'AOE', cl.pos = 'n') 439 | 440 | 441 | ## deal with missing Values 442 | M2 = M 443 | diag(M2) = NA 444 | corrplot(M2) 445 | corrplot(M2, na.label = 'o') 446 | corrplot(M2, na.label = 'NA') 447 | 448 | 449 | ##the input matrix is not square 450 | corrplot(M[1:8, ]) 451 | corrplot(M[, 1:8]) 452 | 453 | testRes = cor.mtest(mtcars, conf.level = 0.95) 454 | 455 | ## specialized the insignificant value according to the significant level 456 | corrplot(M, p.mat = testRes$p, sig.level = 0.05, order = 'hclust', addrect = 2) 457 | 458 | ## leave blank on no significant coefficient 459 | corrplot(M, p.mat = testRes$p, method = 'circle', type = 'lower', insig ='blank', 460 | addCoef.col ='black', number.cex = 0.8, order = 'AOE', diag = FALSE) 461 | 462 | ## add p-values on no significant coefficients 463 | corrplot(M, p.mat = testRes$p, insig = 'p-value') 464 | 465 | ## add all p-values 466 | corrplot(M, p.mat = testRes$p, insig = 'p-value', sig.level = -1) 467 | 468 | ## add significant level stars 469 | corrplot(M, p.mat = testRes$p, method = 'color', diag = FALSE, type = 'upper', 470 | sig.level = c(0.001, 0.01, 0.05), pch.cex = 0.9, 471 | insig = 'label_sig', pch.col = 'grey20', order = 'AOE') 472 | 473 | ## add significant level stars and cluster rectangles 474 | corrplot(M, p.mat = testRes$p, tl.pos = 'd', order = 'hclust', addrect = 2, 475 | insig = 'label_sig', sig.level = c(0.001, 0.01, 0.05), 476 | pch.cex = 0.9, pch.col = 'grey20') 477 | 478 | # Visualize confidence interval 479 | corrplot(M, lowCI = testRes$lowCI, uppCI = testRes$uppCI, order = 'hclust', 480 | tl.pos = 'd', rect.col = 'navy', plotC = 'rect', cl.pos = 'n') 481 | 482 | # Visualize confidence interval and cross the significant coefficients 483 | corrplot(M, p.mat = testRes$p, lowCI = testRes$lowCI, uppCI = testRes$uppCI, 484 | addrect = 3, rect.col = 'navy', plotC = 'rect', cl.pos = 'n') 485 | 486 | 487 | 488 | res1 = cor.mtest(mtcars, conf.level = 0.95) 489 | res2 = cor.mtest(mtcars, conf.level = 0.99) 490 | 491 | 492 | ## plot confidence interval(0.95), 'circle' method 493 | corrplot(M, low = res1$uppCI, upp = res1$uppCI, 494 | plotCI = 'circle', addg = 'grey20', cl.pos = 'n') 495 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 496 | plotCI = 'circle', addg = 'grey20', cl.pos = 'n') 497 | corrplot(M, low = res1$lowCI, upp = res1$uppCI, 498 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', 499 | plotCI = 'circle', cl.pos = 'n', pch.col = 'red') 500 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 501 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', 502 | plotCI = 'circle', cl.pos = 'n', pch.col = 'red') 503 | 504 | ## plot confidence interval(0.95), 'square' method 505 | corrplot(M, low = res1$lowCI, upp = res1$uppCI, 506 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', 507 | plotCI = 'square', addg = NULL, cl.pos = 'n') 508 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 509 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', pch.col = 'red', 510 | plotCI = 'square', addg = NULL, cl.pos = 'n') 511 | 512 | ## plot confidence interval0.95, 0.95, 0.99, 'rect' method 513 | corrplot(M, low = res1$lowCI, upp = res1$uppCI, order = 'hclust', 514 | rect.col = 'navy', plotCI = 'rect', cl.pos = 'n') 515 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 516 | order = 'hclust', pch.col = 'red', sig.level = 0.05, addrect = 3, 517 | rect.col = 'navy', plotCI = 'rect', cl.pos = 'n') 518 | corrplot(M, p.mat = res2$p, low = res2$lowCI, upp = res2$uppCI, 519 | order = 'hclust', pch.col = 'red', sig.level = 0.01, addrect = 3, 520 | rect.col = 'navy', plotCI = 'rect', cl.pos = 'n') 521 | 522 | 523 | ## an animation of changing confidence interval in different significance level 524 | ## begin.animaton 525 | par(ask = FALSE) 526 | for (i in seq(0.1, 0, -0.005)) { 527 | tmp = cor.mtest(mtcars, conf.level = 1 - i) 528 | corrplot(M, p.mat = tmp$p, low = tmp$lowCI, upp = tmp$uppCI, order = 'hclust', 529 | pch.col = 'red', sig.level = i, plotCI = 'rect', cl.pos = 'n', 530 | mar = c(0, 0, 1, 0), 531 | title = substitute(alpha == x, 532 | list(x = format(i, digits = 3, nsmall = 3)))) 533 | Sys.sleep(0.15) 534 | } 535 | ## end.animaton 536 | } 537 | \references{ 538 | Michael Friendly (2002). 539 | \emph{Corrgrams: Exploratory displays for correlation matrices}. 540 | The American Statistician, 56, 316--324. 541 | 542 | D.J. Murdoch, E.D. Chow (1996). 543 | \emph{A graphical display of large correlation matrices}. 544 | The American Statistician, 50, 178--180. 545 | } 546 | \seealso{ 547 | Function \code{plotcorr} in the \code{ellipse} package and 548 | \code{corrgram} in the \code{corrgram} package have some similarities. 549 | 550 | Package \code{seriation} offered more methods to reorder matrices, such as 551 | ARSA, BBURCG, BBWRCG, MDS, TSP, Chen and so forth. 552 | } 553 | \author{ 554 | Taiyun Wei (weitaiyun@gmail.com) 555 | 556 | Viliam Simko (viliam.simko@gmail.com) 557 | 558 | Michael Levy (michael.levy@healthcatalyst.com) 559 | } 560 | -------------------------------------------------------------------------------- /man/corrplot.mixed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/corrplot.mixed.R 3 | \name{corrplot.mixed} 4 | \alias{corrplot.mixed} 5 | \title{Using mixed methods to visualize a correlation matrix.} 6 | \usage{ 7 | corrplot.mixed( 8 | corr, 9 | lower = "number", 10 | upper = "circle", 11 | tl.pos = c("d", "lt", "n"), 12 | diag = c("n", "l", "u"), 13 | bg = "white", 14 | addgrid.col = "grey", 15 | lower.col = NULL, 16 | upper.col = NULL, 17 | plotCI = c("n", "square", "circle", "rect"), 18 | mar = c(0, 0, 0, 0), 19 | ... 20 | ) 21 | } 22 | \arguments{ 23 | \item{corr}{Matrix, the correlation matrix to visualize.} 24 | 25 | \item{lower}{Character, the visualization method for the lower triangular 26 | correlation matrix.} 27 | 28 | \item{upper}{Character, the visualization method for the upper triangular 29 | correlation matrix.} 30 | 31 | \item{tl.pos}{Character, \code{'lt'}, \code{'d'} or \code{'n'}, giving 32 | position of text labels, \code{'lt'} means left and top, \code{'d'} means 33 | diagonal. If \code{'n'}, add no textlabel.} 34 | 35 | \item{diag}{Character, for specifying the glyph on the principal diagonal. It 36 | is one of \code{'n'} (default, draw nothing), \code{'l'} (draw the glyphs 37 | of lower triangular) or \code{'u'} (draw the glyphs of upper triangular).} 38 | 39 | \item{bg}{The background color.} 40 | 41 | \item{addgrid.col}{See the \code{addgrid.col} parameter in the function 42 | \code{\link{corrplot}}} 43 | 44 | \item{lower.col}{Passed as \code{col} parameter to the lower matrix.} 45 | 46 | \item{upper.col}{Passed as \code{col} parameter to the upper matrix.} 47 | 48 | \item{plotCI}{See the \code{plotCI} parameter in the function 49 | \code{\link{corrplot}}} 50 | 51 | \item{mar}{See \code{\link{par}}.} 52 | 53 | \item{\dots}{Additional arguments for corrplot's wrappers} 54 | } 55 | \description{ 56 | Using mixed methods to visualize a correlation matrix. 57 | } 58 | \examples{ 59 | M = cor(mtcars) 60 | ord = corrMatOrder(M, order = 'AOE') 61 | M2 = M[ord, ord] 62 | 63 | 64 | corrplot.mixed(M2) 65 | corrplot.mixed(M2, lower = 'ellipse', upper = 'circle') 66 | corrplot.mixed(M2, lower = 'square', upper = 'circle') 67 | corrplot.mixed(M2, lower = 'shade', upper = 'circle') 68 | corrplot.mixed(M2, tl.pos = 'lt') 69 | corrplot.mixed(M2, tl.pos = 'lt', diag = 'u') 70 | corrplot.mixed(M2, tl.pos = 'lt', diag = 'l') 71 | corrplot.mixed(M2, tl.pos = 'n') 72 | } 73 | \author{ 74 | Taiyun Wei 75 | } 76 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(corrplot) 3 | 4 | test_check('corrplot') 5 | -------------------------------------------------------------------------------- /tests/testthat/test-colorlegend.R: -------------------------------------------------------------------------------- 1 | context('Color legend') 2 | 3 | # suppress generating any PDFs 4 | pdf(NULL) 5 | 6 | test_that('Basic usage of colorlegend', { 7 | plot(0, type = 'n') 8 | colorlegend(rainbow(100), 0:9, align = 'r') 9 | colorlegend(rainbow(100), 0:9, align = 'l', vertical = FALSE) 10 | colorlegend(rainbow(100), 0:9, align = 'r', vertical = FALSE) 11 | }) 12 | 13 | test_that('Calling colorlegend without first calling plot should fail', { 14 | if (length(dev.list()) != 0) { 15 | dev.off() 16 | pdf(NULL) 17 | } 18 | expect_error(colorlegend(rainbow(100), 0:9), 19 | regexp = 'plot.new has not been called yet') 20 | }) 21 | 22 | test_that('Issues #64, #66: lim.segment in function colorlegend()', { 23 | plot(0, type = 'n') 24 | 25 | expect_error(colorlegend(rainbow(100), 0:9, lim.segment = 1), 26 | regexp = 'should be a vector of length 2') 27 | 28 | expect_error(colorlegend(rainbow(100), 0:9, lim.segment = c(1, 2, 3)), 29 | regexp = 'should be a vector of length 2') 30 | 31 | # lim.segment[1] >= 0 32 | expect_error(colorlegend(rainbow(100), 0:9, lim.segment = c(-0.1, 0)), 33 | regexp = 'should be between 0 and 1') 34 | 35 | # lim.segment[2] <= 1 36 | expect_error(colorlegend(rainbow(100), 0:9, lim.segment = c(0, 1.1)), 37 | regexp = 'should be between 0 and 1') 38 | 39 | # automatic lim.segment 40 | expect_silent(colorlegend(rainbow(100), 0:9, lim.segment = NULL)) 41 | 42 | # Issue #66: more intuitive value for automatic lim.segment 43 | expect_silent(colorlegend(rainbow(100), 0:9, lim.segment = 'auto')) 44 | expect_error(colorlegend(rainbow(100), 0:9, lim.segment = 'otherstring'), 45 | regexp = 'should be a vector of length 2') 46 | 47 | colorlegend(rainbow(100), 0:9, lim.segment = c(0, 1), align ='l') 48 | }) 49 | 50 | test_that('Parameter `at` should be between 0 and 1', { 51 | plot(0, type = 'n') 52 | 53 | expect_error(colorlegend(rainbow(100), 0:2, at = c(-1, 0.5, 0.8)), 54 | regexp = 'should be between 0 and 1') 55 | 56 | expect_silent(colorlegend(rainbow(100), 0:2, at = c(0, 0.5, 0.8))) 57 | }) 58 | -------------------------------------------------------------------------------- /tests/testthat/test-cor-mtest.R: -------------------------------------------------------------------------------- 1 | context('cor.mtest - significance test and confidence intervals') 2 | 3 | test_that('Basic usage of cor.mtest', { 4 | 5 | res1 = cor.mtest(mtcars) 6 | 7 | expect_true(is.list(res1)) 8 | expect_true(is.matrix(res1$p)) 9 | expect_true(is.matrix(res1$lowCI)) 10 | expect_true(is.matrix(res1$uppCI)) 11 | 12 | expect_equal(dim(res1$p), c(11, 11)) 13 | 14 | expect_equal(dim(res1$p), dim(res1$lowCI)) 15 | expect_equal(dim(res1$p), dim(res1$uppCI)) 16 | 17 | }) 18 | 19 | test_that('Additional params', { 20 | expect_silent(cor.mtest(mtcars, conf.level = 0.95)) 21 | expect_silent(cor.mtest(mtcars, method = 'spearman', exact = FALSE)) 22 | 23 | # unknown parameters are silently ignored 24 | expect_silent(cor.mtest(mtcars, dummy = 'dummy')) 25 | }) 26 | -------------------------------------------------------------------------------- /tests/testthat/test-corrRect.R: -------------------------------------------------------------------------------- 1 | context('Adding Correlation Rectangles') 2 | 3 | # Tests ========== 4 | test_that('Testing running', { 5 | M = cor(mtcars) 6 | r = rbind(c('gear', 'wt', 'qsec', 'carb'), 7 | c('wt', 'qsec', 'carb', 'gear')) 8 | i = c(1, 5, 11) 9 | expect_silent(corrRect(corrplot(M, type = 'upper'), i)) 10 | expect_silent(corrRect(corrplot(M, type = 'lower'), i)) 11 | expect_silent(corrRect(corrplot(M), namesMat = c('gear', 'wt', 'qsec', 'carb'))) 12 | expect_silent(corrRect(corrplot(M), namesMat = r)) 13 | }) 14 | 15 | 16 | 17 | test_that('Testing error', { 18 | M = cor(mtcars) 19 | r = rbind(c('gear', 'wt', 'qsec', 'carb'), 20 | c('wt', 'qsec', 'carb', 'gear')) 21 | corrplot(M, method = 'circle', order = 'AOE', diag = TRUE, type='upper') -> p 22 | expect_error(corrRect(namesMat = r, corrRes = p)) 23 | }) 24 | 25 | test_that('pipe operator', { 26 | if(getRversion() >= '4.1.0') { 27 | M = cor(mtcars) 28 | r = c('gear', 'wt', 'qsec', 'carb') 29 | corrplot(M, method = 'circle', order = 'AOE') |> corrRect(name = r) 30 | } 31 | }) 32 | 33 | 34 | test_that('You should just input one of index, name and namesMat!', { 35 | M = cor(mtcars) 36 | expect_error(corrRect(corrplot(M), index = c(1, 5, 11), name = c('gear', 'wt')), 37 | regexp = 'You should just input one of index, name and namesMat!') 38 | }) 39 | 40 | 41 | test_that('List \'corrRes\' must be inputted!', { 42 | M = cor(mtcars) 43 | corrplot(M) 44 | expect_error(corrRect(), regexp = 'List \'corrRes\' must be inputted!') 45 | }) 46 | 47 | 48 | 49 | test_that('Non-existent name found!', { 50 | M = cor(mtcars) 51 | expect_error(corrRect(corrplot(M), name = c('carb', 'gearssss')), 52 | regexp = 'Non-existent name found!') 53 | }) 54 | 55 | 56 | test_that('colnames and rownames must be same when index or name is inputted!', { 57 | M = cor(mtcars) 58 | expect_error(corrRect(corrplot(M[1:3, 4:6]), name = c('mpg', 'carb')), 59 | regexp = 'colnames and rownames must be same when index or name is inputted!') 60 | 61 | expect_error(corrRect(corrplot(M[1:3, 4:6]), index = c(1, 5, 11)), 62 | regexp = 'colnames and rownames must be same when index or name is inputted!') 63 | }) 64 | -------------------------------------------------------------------------------- /tests/testthat/test-corrplot.R: -------------------------------------------------------------------------------- 1 | context('Visualization of a correlation matrix') 2 | 3 | # Tests ========== 4 | 5 | test_that('Testing `cl.pos` parameter', { 6 | M = cor(mtcars) 7 | expect_silent(corrplot(M, cl.pos = TRUE, diag = FALSE)) 8 | expect_silent(corrplot(M, cl.pos = FALSE)) 9 | expect_silent(corrplot(M, cl.pos = 'r')) 10 | expect_silent(corrplot(M, method = 'shade', addshade = 'all', cl.pos = 'b')) 11 | }) 12 | 13 | test_that('Testing `tl.pos` parameter', { 14 | M = cor(mtcars) 15 | expect_silent(corrplot(M, tl.pos = TRUE)) 16 | expect_silent(corrplot(M, tl.pos = FALSE)) 17 | expect_silent(corrplot(M, tl.pos = 'd')) 18 | expect_silent(corrplot(M, tl.pos = 'n')) 19 | expect_silent(corrplot(M, tl.pos = 'lt')) 20 | expect_silent(corrplot(M, tl.pos = 'ld', type = 'lower')) 21 | expect_silent(corrplot(M, tl.pos = 'td', type = 'upper')) 22 | }) 23 | 24 | 25 | test_that('Testing `col.lim` parameter', { 26 | M = cor(mtcars) 27 | expect_silent(corrplot(M, col.lim = c(-1, 1))) 28 | expect_error(corrplot(M, col.lim = c(0, 1)), 29 | regexp = 'color limits should cover matrix') 30 | expect_error(corrplot(M, col.lim = c(-1, 2)), 31 | regexp = 'col.lim should be within the interval') 32 | }) 33 | 34 | test_that('Testing `tl.pos` parameter', { 35 | M = cor(mtcars) 36 | expect_silent(corrplot(M, tl.pos = 'td', type = 'upper')) 37 | expect_error(corrplot(M, tl.pos = 'td', type = 'lower'), 38 | regexp = 'type should be') 39 | expect_silent(corrplot(M, tl.pos = 'ld', type = 'lower')) 40 | expect_error(corrplot(M, tl.pos = 'ld', type = 'upper'), 41 | regexp = 'type should be') 42 | }) 43 | 44 | test_that('Testing `corrRect` function', { 45 | M = cor(mtcars) 46 | corrplot(M, method = 'circle', order = 'FPC') 47 | expect_error(corrRect(c(5, 6))) 48 | }) 49 | 50 | test_that('Testing `outline` parameter', { 51 | M = cor(mtcars) 52 | expect_silent(corrplot(M, outline = FALSE)) 53 | expect_silent(corrplot(M, outline = TRUE)) 54 | expect_silent(corrplot(M, outline = 'white')) 55 | 56 | for (unsupported in list(42, NA, NULL)) { 57 | expect_error(corrplot(M, outline = unsupported), 58 | regexp = 'Unsupported value type for parameter outline') 59 | } 60 | 61 | expect_error(corrplot(M, outline = ''), 62 | regexp = 'invalid color name') 63 | 64 | }) 65 | 66 | test_that('Issue #7: Enable to plot a matrix with NA', { 67 | M = cor(mtcars) 68 | diag(M) = NA 69 | expect_equal(corrplot(M)$corr, M) 70 | }) 71 | 72 | 73 | 74 | test_that('Issue #20: plotmath expressions in rownames / colnames', { 75 | M = cor(mtcars)[1:5, 1:5] 76 | colnames(M) = c('alpha', 'beta', ':alpha+beta', ': a[0]', '=a[beta]') 77 | rownames(M) = c('alpha', 'beta', NA, '$a[0]', '$ a[beta]') 78 | corrplot(M) 79 | }) 80 | 81 | test_that('Issue #20: using dollar sign in plotmath expressions', { 82 | M = cor(mtcars) 83 | rownames(M)[1] = ' $' 84 | corrplot(M) 85 | }) 86 | 87 | test_that('Issue #21: plotCI=rect incompatible with some methods', { 88 | M = cor(mtcars) 89 | L = M - 0.1 90 | U = M + 0.1 91 | expect_equal(corrplot.mixed(M, lower = 'circle', upper = 'number', 92 | lowCI = L, uppCI = U, plotCI = 'rect')$corr, M) 93 | }) 94 | 95 | test_that('Issue #43: Return value should be the same as corrplot function', { 96 | M = cor(mtcars) 97 | expect_equal(corrplot.mixed(M)$corr, corrplot(M)$corr) 98 | }) 99 | 100 | test_that('Should only work with matrix or dataframe', { 101 | expect_error(corrplot('some string'), regexp = 'matrix or data frame') 102 | expect_error(corrplot(42), regexp = 'matrix or data frame') 103 | }) 104 | 105 | test_that('Non-correlation matrix', { 106 | M = matrix(runif(100, 0, 10), nrow = 10) 107 | expect_error(corrplot(M), regexp = 'The matrix is not in') 108 | expect_true(is.matrix(corrplot(M, is.corr = FALSE)$corr)) 109 | expect_true(is.data.frame(corrplot(M, is.corr = FALSE)$corrPos)) 110 | }) 111 | 112 | test_that('Try different ordering', { 113 | M = cor(mtcars) 114 | 115 | expect_true(identical(M, corrplot(M)$corr)) 116 | expect_false(identical(M, corrplot(M, order = 'AOE'))) 117 | expect_false(identical(M, corrplot(M, order = 'FPC'))) 118 | expect_false(identical(M, corrplot(M, order = 'hclust'))) 119 | expect_false(identical(M, corrplot(M, order = 'alphabet'))) 120 | 121 | expect_silent(corrplot(M, addrect = 2, order = 'hclust', type = 'full')) 122 | }) 123 | 124 | test_that('Plot without a grid should not crash', { 125 | # TODO: currently, we cannot test how the rendered grid looks like 126 | # we can only check whether it does not crash 127 | M = cor(mtcars) 128 | 129 | # without grid 130 | expect_silent(corrplot(M, addgrid.col = NA)) 131 | 132 | # white grid 133 | expect_silent(corrplot(M, addgrid.col = NULL, method = 'color')) 134 | expect_silent(corrplot(M, addgrid.col = NULL, method = 'shade')) 135 | 136 | # grey grid 137 | expect_silent(corrplot(M, addgrid.col = NULL, method = 'circle')) 138 | }) 139 | 140 | test_that('Issue #46: Rendering NA values', { 141 | 142 | M = cor(mtcars) 143 | diag(M) = NA 144 | M[4, 2] = NA 145 | 146 | # default label for NAs 147 | expect_silent(corrplot(M)) 148 | 149 | # black square instead of the label 150 | expect_silent(corrplot(M, na.label = 'square', na.label.col = 'black')) 151 | 152 | # large matrix 153 | M = matrix(runif(10000, 0.5, 1), nrow = 100) 154 | M[40:50, 30:70] = 0 155 | diag(M) = NA 156 | expect_silent(corrplot(M, method = 'color', cl.pos = 'n', tl.pos = 'n', 157 | na.label = 'square', addgrid.col = NA)) 158 | }) 159 | 160 | test_that('Issue #55: Support for multiple characters when rendering NAs', { 161 | M = cor(mtcars) 162 | diag(M) = NA 163 | 164 | # label with 2 chars should work 165 | expect_silent(corrplot(M, na.label = 'NA')) 166 | 167 | expect_error(corrplot(M, na.label = 'ABC'), 168 | regexp = 'Maximum number of characters for NA label is: 2') 169 | 170 | }) 171 | 172 | test_that('Using `number.digits` parameter', { 173 | M = cor(mtcars) 174 | 175 | expect_silent(corrplot(M, number.digits = 0)) 176 | expect_silent(corrplot(M, number.digits = 1)) 177 | # the allowed values for nsmall parameter of format() function is [0, 20] 178 | expect_silent(corrplot(M, method = 'number', number.digits = 20)) 179 | 180 | expect_error(corrplot(M, number.digits = 1.2), regexp = 'is not TRUE') 181 | expect_error(corrplot(M, number.digits = -1), regexp = 'is not TRUE') 182 | }) 183 | 184 | test_that('par() is restored after corrplot()', { 185 | grDevices::pdf(NULL) 186 | par1 = par('mar') 187 | corrplot(cor(mtcars)) 188 | par2 = par('mar') 189 | dev.off() 190 | expect_identical(par1, par2) 191 | }) 192 | 193 | test_that('Issue #79: Changing aspect ratio for the plot', { 194 | M = matrix(rnorm(70), ncol = 7) 195 | expect_silent(corrplot(M, is.corr = FALSE, win.asp = .7, method = 'circle')) 196 | expect_silent(corrplot(M, is.corr = FALSE, win.asp = .7, method = 'square')) 197 | expect_error(corrplot(M, is.corr = FALSE, win.asp = .7, method = 'pie'), 198 | regexp = 'supported only for circle and square methods') 199 | }) 200 | 201 | test_that('Issue #18', { 202 | M = cor(mtcars) 203 | # TODO: calling the function without actually checking anything 204 | expect_silent(corrplot(M, method = 'pie', is.corr = FALSE, diag = FALSE)) 205 | expect_silent(corrplot(M, method = 'pie', outline = TRUE)) 206 | expect_silent(corrplot(M, method = 'pie', outline = 'white')) 207 | }) 208 | 209 | test_that('Issue #76: separate `col` parameters corrplot.mixed', { 210 | M = cor(mtcars) 211 | expect_silent(corrplot.mixed(M, lower.col = 'black')) 212 | expect_silent(corrplot.mixed(M, lower = 'circle', 213 | upper = 'number', upper.col = 'black')) 214 | }) 215 | 216 | test_that('Issue #99: Mark significant correlations', { 217 | M = cor(mtcars) 218 | fakepmat = 1 - abs(M) ^ 0.2 # Hmisc::rcorr provides a p-value matrix, but 219 | # don't want to introduce the dependency 220 | expect_silent(corrplot(M, p.mat = fakepmat, insig = 'label_sig', pch = '!', 221 | sig.level = c(0.001, 0.1, 0.99))) 222 | expect_silent(corrplot(M[1:2, ], p.mat = fakepmat[1:2, ], method = 'ellipse', 223 | insig = 'label_sig', pch.col = 'white')) 224 | expect_silent(corrplot(M, p.mat = fakepmat, insig = 'label_sig', 225 | pch = 'p<.05', pch.cex = 0.5, order = 'AOE')) 226 | expect_warning(corrplot(M, p.mat = fakepmat[, 11:1], insig = 'label_sig', 227 | pch = 'p<.05', pch.cex = 0.5, order = 'AOE')) 228 | }) 229 | 230 | test_that('col.lim', { 231 | M = cor(mtcars) 232 | expect_warning(corrplot(M*2, is.corr = FALSE, col.lim=c(-2, 2) * 2)) 233 | expect_warning(corrplot(abs(M), is.corr = FALSE, col.lim=c(-1, 1))) 234 | }) 235 | 236 | 237 | test_that("plotCI == 'circle'", { 238 | M = cor(mtcars) 239 | res = cor.mtest(mtcars, conf.level = 0.95) 240 | ## plot confidence interval(0.95), 'circle' method 241 | corrplot(M, p.mat = res$p, low = res$lowCI, upp = res$uppCI, 242 | plotCI = 'circle', addg = 'grey20', cl.pos = 'n') 243 | expect_error(corrplot(M, p.mat = res$p, plotCI = 'circle'), 244 | regexp = 'Need lowCI.mat and uppCI.mat!') 245 | }) 246 | 247 | test_that("plotCI == 'square'", { 248 | M = cor(mtcars) 249 | res = cor.mtest(mtcars, conf.level = 0.95) 250 | ## plot confidence interval(0.95), 'circle' method 251 | corrplot(M, p.mat = res$p, low = res$lowCI, upp = res$uppCI, order = 'AOE', 252 | plotCI = 'square', addg = 'grey20', cl.pos = 'n') 253 | }) 254 | 255 | 256 | test_that("add numbers", { 257 | M = cor(mtcars) 258 | corrplot(M, addCoef.col ='black') 259 | }) 260 | 261 | test_that("p-value", { 262 | 263 | M = cor(mtcars) 264 | testRes = cor.mtest(mtcars, conf.level = 0.95) 265 | 266 | ## specialized the insignificant value according to the significant level 267 | corrplot(M, p.mat = testRes$p, sig.level = 0.10, order = 'hclust', addrect = 2) 268 | 269 | ## leave blank on no significant coefficient 270 | corrplot(M, p.mat = testRes$p, method = 'circle', type = 'lower', insig='blank', 271 | addCoef.col ='black', number.cex = 0.8, order = 'AOE', diag = FALSE) 272 | 273 | ## add p-values on no significant coefficients 274 | corrplot(M, p.mat = testRes$p, insig = 'p-value') 275 | }) 276 | 277 | 278 | test_that("if (diag == 'n' && tl.pos != 'd')", { 279 | M = cor(mtcars) 280 | corrplot.mixed(M, diag = 'n', tl.pos = 'lt') 281 | }) 282 | 283 | 284 | test_that('long name warning', { 285 | M = cor(mtcars) 286 | colnames(M) = rownames(M) = rep(toString(rep(LETTERS, 5)), 11) 287 | expect_warning(corrplot(M), regexp = 'Not been able to calculate text margin') 288 | }) 289 | -------------------------------------------------------------------------------- /vignettes/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taiyun/corrplot/62532f700e6c9d04b93ffbf0bf56e264b0e0368e/vignettes/.DS_Store -------------------------------------------------------------------------------- /vignettes/corrplot-intro.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'An Introduction to corrplot Package' 3 | author: 'Taiyun Wei, Viliam Simko' 4 | date: '`r Sys.Date()`' 5 | output: 6 | prettydoc::html_pretty: 7 | theme: cayman 8 | toc: true 9 | toc-title: 'Table of Contents' 10 | vignette: > 11 | %\VignetteIndexEntry{An Introduction to corrplot Package} 12 | %\VignetteEncoding{UTF-8} 13 | %\VignetteEngine{knitr::rmarkdown} 14 | --- 15 | 16 | ```{r setup, include=FALSE} 17 | 18 | knitr::opts_chunk$set( 19 | fig.align = 'center', 20 | fig.path = 'webimg/', 21 | fig.width = 7, 22 | fig.height = 7, 23 | out.width = '600px', 24 | dev = 'png') 25 | 26 | get_os = function() { 27 | sysinf = Sys.info() 28 | if (!is.null(sysinf)) { 29 | os = sysinf['sysname'] 30 | if (os == 'Darwin') 31 | os = 'osx' 32 | } else { ## mystery machine 33 | os = .Platform$OS.type 34 | if (grepl('^darwin', R.version$os)) 35 | os = 'osx' 36 | if (grepl('linux-gnu', R.version$os)) 37 | os = 'linux' 38 | } 39 | tolower(os) 40 | } 41 | if(get_os() =='windows' & capabilities('cairo') | all(capabilities(c('cairo', 'X11')))) { 42 | knitr::opts_chunk$set(dev.args = list(type='cairo')) 43 | } 44 | 45 | ``` 46 | 47 | ## Introduction 48 | 49 | R package **corrplot** provides a visual exploratory tool on correlation matrix that 50 | supports automatic variable reordering to help detect hidden patterns among variables. 51 | 52 | corrplot is very easy to use and provides a rich array of plotting options in 53 | visualization method, graphic layout, color, legend, text labels, etc. 54 | It also provides p-values and confidence intervals to help users determine the 55 | statistical significance of the correlations. 56 | 57 | 58 | `corrplot()` has about 50 parameters, however the mostly common ones are only a few. 59 | We can get a correlation matrix plot with only one line of code in most scenes. 60 | 61 | The mostly using parameters include `method`, `type`, `order`, `diag`, and etc. 62 | 63 | There are seven visualization methods (parameter `method`) in 64 | corrplot package, named `'circle'`, `'square'`, `'ellipse'`, 65 | `'number'`, `'shade'`, `'color'`, `'pie'`. Color intensity of the glyph 66 | is proportional to the correlation coefficients by default color setting. 67 | 68 | - `'circle'` and `'square'`, the **areas** of circles or squares show the 69 | absolute value of corresponding correlation coefficients. 70 | 71 | - `'ellipse'`, the ellipses have their eccentricity parametrically scaled to the correlation value. 72 | It comes from D.J. Murdoch and E.D. Chow's job, see in section References. 73 | 74 | - `'number'`, coefficients numbers with different color. 75 | 76 | - `'color'`, square of equal size with different color. 77 | 78 | - `'shade'`, similar to `'color'`, but the negative coefficients glyphs are shaded. 79 | Method `'pie'` and `'shade'` come from Michael Friendly's job. 80 | 81 | - `'pie'`, the circles are filled clockwise for positive values, anti-clockwise for negative 82 | values. 83 | 84 | 85 | 86 | 87 | 88 | `corrplot.mixed()` is a wrapped function for mixed visualization style, 89 | which can set the visual methods of lower and upper triangular 90 | separately. 91 | 92 | There are three layout types (parameter `type`): `'full'`, `'upper'` and 93 | `'lower'`. 94 | 95 | The correlation matrix can be reordered according to the correlation 96 | matrix coefficients. This is important to identify the hidden structure 97 | and pattern in the matrix. 98 | 99 | ```{r intro} 100 | library(corrplot) 101 | M = cor(mtcars) 102 | corrplot(M, method = 'number') # colorful number 103 | corrplot(M, method = 'color', order = 'alphabet') 104 | corrplot(M) # by default, method = 'circle' 105 | corrplot(M, order = 'AOE') # after 'AOE' reorder 106 | corrplot(M, method = 'shade', order = 'AOE', diag = FALSE) 107 | corrplot(M, method = 'square', order = 'FPC', type = 'lower', diag = FALSE) 108 | corrplot(M, method = 'ellipse', order = 'AOE', type = 'upper') 109 | corrplot.mixed(M, order = 'AOE') 110 | corrplot.mixed(M, lower = 'shade', upper = 'pie', order = 'hclust') 111 | ``` 112 | 113 | ## Reorder a correlation matrix 114 | 115 | The details of four `order` algorithms, named `'AOE'`, `'FPC'`, 116 | `'hclust'`, `'alphabet'` are as following. 117 | 118 | - `'AOE'` is for the angular order of the eigenvectors. It is 119 | calculated from the order of the angles $a_i$, 120 | 121 | $$ 122 | a_i = 123 | \begin{cases} 124 | \arctan (e_{i2}/e_{i1}), & \text{if $e_{i1}>0$;} 125 | \newline 126 | \arctan (e_{i2}/e_{i1}) + \pi, & \text{otherwise.} 127 | \end{cases} 128 | $$ 129 | 130 | where $e_1$ and $e_2$ are the largest two eigenvalues of the 131 | correlation matrix. See [Michael Friendly 132 | (2002)](http://www.datavis.ca/papers/corrgram.pdf) for details. 133 | 134 | - `'FPC'` for the first principal component order. 135 | 136 | - `'hclust'` for hierarchical clustering order, and `'hclust.method'` 137 | for the agglomeration method to be used. `'hclust.method'` should be 138 | one of `'ward'`, `'ward.D'`, `'ward.D2'`, `'single'`, `'complete'`, 139 | `'average'`, `'mcquitty'`, `'median'` or `'centroid'`. 140 | 141 | - `'alphabet'` for alphabetical order. 142 | 143 | 144 | You can also reorder the matrix 'manually' via function 145 | `corrMatOrder()`. 146 | 147 | If using `'hclust'`, `corrplot()` can draw rectangles around the plot of 148 | correlation matrix based on the results of hierarchical clustering. 149 | 150 | ```{r hclust} 151 | corrplot(M, order = 'hclust', addrect = 2) 152 | corrplot(M, method = 'square', diag = FALSE, order = 'hclust', 153 | addrect = 3, rect.col = 'blue', rect.lwd = 3, tl.pos = 'd') 154 | ``` 155 | 156 | R package **seriation** provides the infrastructure for ordering objects with an 157 | implementation of several seriation/sequencing/ordination techniques to reorder 158 | matrices, dissimilarity matrices, and dendrograms. For more information, 159 | see in section References. 160 | 161 | We can reorder the matrix via **seriation** package and then corrplot it. 162 | Here are some examples. 163 | 164 | 165 | 166 | ```{r seriation} 167 | library(seriation) 168 | list_seriation_methods('matrix') 169 | list_seriation_methods('dist') 170 | 171 | data(Zoo) 172 | Z = cor(Zoo[, -c(15, 17)]) 173 | 174 | dist2order = function(corr, method, ...) { 175 | d_corr = as.dist(1 - corr) 176 | s = seriate(d_corr, method = method, ...) 177 | i = get_order(s) 178 | return(i) 179 | } 180 | ``` 181 | 182 | Methods `'PCA_angle'` and `'HC'` in **seriation**, are same as `'AOE'` and `'hclust'` 183 | separately in `corrplot()` and `corrMatOrder()`. 184 | 185 | Here are some plots after seriation. 186 | 187 | ```{r seriation-plot} 188 | # Fast Optimal Leaf Ordering for Hierarchical Clustering 189 | i = dist2order(Z, 'OLO') 190 | corrplot(Z[i, i], cl.pos = 'n') 191 | 192 | # Quadratic Assignment Problem 193 | i = dist2order(Z, 'QAP_2SUM') 194 | corrplot(Z[i, i], cl.pos = 'n') 195 | 196 | # Multidimensional Scaling 197 | i = dist2order(Z, 'MDS_nonmetric') 198 | corrplot(Z[i, i], cl.pos = 'n') 199 | 200 | # Simulated annealing 201 | i = dist2order(Z, 'ARSA') 202 | corrplot(Z[i, i], cl.pos = 'n') 203 | 204 | # TSP solver 205 | i = dist2order(Z, 'TSP') 206 | corrplot(Z[i, i], cl.pos = 'n') 207 | 208 | # Spectral seriation 209 | i = dist2order(Z, 'Spectral') 210 | corrplot(Z[i, i], cl.pos = 'n') 211 | ``` 212 | 213 | `corrRect()` can add rectangles on the plot with three ways(parameter 214 | `index`, `name` and `namesMat`) after `corrplot()`. 215 | We can use pipe operator `*>%` in package `magrittr` with more convenience. 216 | Since R 4.1.0, `|>` is supported without extra package. 217 | 218 | ```{r rectangles} 219 | library(magrittr) 220 | 221 | # Rank-two ellipse seriation, use index parameter 222 | i = dist2order(Z, 'R2E') 223 | corrplot(Z[i, i], cl.pos = 'n') %>% corrRect(c(1, 9, 15)) 224 | 225 | # use name parameter 226 | # Since R 4.1.0, the following one line code works: 227 | # corrplot(M, order = 'AOE') |> corrRect(name = c('gear', 'wt', 'carb')) 228 | corrplot(Z, order = 'AOE') %>% 229 | corrRect(name = c('tail', 'airborne', 'venomous', 'predator')) 230 | 231 | 232 | # use namesMat parameter 233 | r = rbind(c('eggs', 'catsize', 'airborne', 'milk'), 234 | c('catsize', 'eggs', 'milk', 'airborne')) 235 | corrplot(Z, order = 'hclust') %>% corrRect(namesMat = r) 236 | ``` 237 | 238 | ## Change color spectra, color-legend and text-legend 239 | 240 | We can get sequential and diverging colors from `COL1()` and `COL2()`. 241 | The color palettes are borrowed from `RColorBrewer` package. 242 | 243 | **Notice**: the middle color getting from `COL2()` is fixed to `'#FFFFFF'`(white), 244 | thus we can visualizing element 0 with white color. 245 | 246 | - `COL1()`: Get sequential colors, suitable for visualize a non-negative or 247 | non-positive matrix (e.g. matrix in [0, 20], or [-100, -10], or [100, 500]). 248 | - `COL2()`: Get diverging colors, suitable for visualize a matrix which elements 249 | are partly positive and partly negative (e.g. correlation matrix in [-1, 1], or [-20, 100]). 250 | 251 | 252 | The colors of the correlation plots can be customized by `col` in `corrplot()`. 253 | They are distributed uniformly in `col.lim` interval. 254 | 255 | - `col`: vector, the colors of glyphs. They are distributed uniformly in `col.lim` interval. By default, 256 | - If `is.corr` is `TRUE`, `col` will be `COL2('RdBu', 200)`. 257 | - If `is.corr` is `FALSE`, 258 | - and `corr` is a non-negative or non-positive matrix, `col` will be `COL1('YlOrBr', 200)`; 259 | - otherwise (elements are partly positive and partly negative), `col` will be `COL2('RdBu', 200)`. 260 | - `col.lim`: the limits (x1, x2) interval for assigning color by `col`. By default, 261 | - `col.lim` will be `c(-1, 1)` when `is.corr` is `TRUE`, 262 | - `col.lim` will be `c(min(corr), max(corr))` when `is.corr` is `FALSE`. 263 | - **NOTICE**: if you set `col.lim` when `is.corr` is `TRUE`, the assigning colors are still 264 | distributed uniformly in [-1, 1], it only affect the display on color-legend. 265 | - `is.corr`: logical, whether the input matrix is a correlation matrix or not. The default value is `TRUE`. 266 | We can visualize a non-correlation matrix by setting `is.corr = FALSE`. 267 | 268 | Here all diverging colors from `COL2()` and sequential colors from `COL1()` are shown below. 269 | 270 | **Diverging colors**: 271 | 272 | ```{r echo=FALSE, fig.width = 8, fig.height = 6, out.width = '700px'} 273 | ## diverging colors 274 | plot.new() 275 | par(mar = c(0, 0, 0, 0) + 0.1) 276 | plot.window(xlim = c(-0.2, 1.1), ylim = c(0, 1), xaxs = 'i', yaxs = 'i') 277 | 278 | col = c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 279 | 280 | for(i in 1:length(col)) { 281 | colorlegend(COL2(col[i]), -10:10/10, align = 'l', cex = 0.8, xlim = c(0, 1), 282 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 283 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2, cex = 0.8) 284 | } 285 | ``` 286 | 287 | **Sequential colors**: 288 | 289 | 290 | ```{r echo=FALSE, fig.width = 8, fig.height = 6, out.width = '700px'} 291 | ## sequential colors 292 | plot.new() 293 | par(mar = c(0, 0, 0, 0) + 0.1) 294 | plot.window(xlim = c(-0.2, 1.1), ylim = c(0, 1), xaxs = 'i', yaxs = 'i') 295 | 296 | col = c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 297 | 'YlOrRd', 'YlOrBr', 'YlGn') 298 | 299 | for(i in 1:length(col)) { 300 | colorlegend(COL1(col[i]), 0:10, align = 'l', cex = 0.8, xlim = c(0, 1), 301 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 302 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2) 303 | } 304 | ``` 305 | 306 | Usage of `COL1()` and `COL2()`: 307 | 308 | ```{r eval=FALSE} 309 | COL1(sequential = c("Oranges", "Purples", "Reds", "Blues", "Greens", 310 | "Greys", "OrRd", "YlOrRd", "YlOrBr", "YlGn"), n = 200) 311 | 312 | COL2(diverging = c("RdBu", "BrBG", "PiYG", "PRGn", "PuOr", "RdYlBu"), n = 200) 313 | ``` 314 | 315 | 316 | In addition, function `colorRampPalette()` is very convenient for generating color spectrum. 317 | 318 | 319 | Parameters group `cl.*` is for color-legend. The common-using are: 320 | 321 | - `cl.pos` is for the position of color labels. It is character or 322 | logical. If character, it must be one of `'r'` (means right, default 323 | if `type='upper'` or `'full'`), `'b'` (means bottom, default if 324 | `type='lower'`) or `'n'`(means don't draw color-label). 325 | - `cl.ratio` is to justify the width of color-legend, 0.1\~0.2 is 326 | suggested. 327 | 328 | Parameters group `tl.*` is for text-legend. The common-using are: 329 | 330 | - `tl.pos` is for the position of text labels. It is character or 331 | logical. If character, it must be one of `'lt'`, `'ld'`, `'td'`, 332 | `'d'`, `'l'` or `'n'`. `'lt'`(default if `type='full'`) means left and top, 333 | `'ld'`(default if `type='lower'`) means left and diagonal, 334 | `'td'`(default if `type='upper'`) means top and diagonal(near), 335 | `'d'` means diagonal, `'l'` means left, `'n'` means don't add text-label. 336 | - `tl.cex` is for the size of text label (variable names). 337 | - `tl.srt` is for text label string rotation in degrees. 338 | 339 | ```{r color} 340 | corrplot(M, order = 'AOE', col = COL2('RdBu', 10)) 341 | 342 | corrplot(M, order = 'AOE', addCoef.col = 'black', tl.pos = 'd', 343 | cl.pos = 'n', col = COL2('PiYG')) 344 | 345 | corrplot(M, method = 'square', order = 'AOE', addCoef.col = 'black', tl.pos = 'd', 346 | cl.pos = 'n', col = COL2('BrBG')) 347 | 348 | ## bottom color legend, diagonal text legend, rotate text label 349 | corrplot(M, order = 'AOE', cl.pos = 'b', tl.pos = 'd', 350 | col = COL2('PRGn'), diag = FALSE) 351 | 352 | ## text labels rotated 45 degrees and wider color legend with numbers right aligned 353 | corrplot(M, type = 'lower', order = 'hclust', tl.col = 'black', 354 | cl.ratio = 0.2, tl.srt = 45, col = COL2('PuOr', 10)) 355 | 356 | ## remove color legend, text legend and principal diagonal glyph 357 | corrplot(M, order = 'AOE', cl.pos = 'n', tl.pos = 'n', 358 | col = c('white', 'black'), bg = 'gold2') 359 | ``` 360 | 361 | ## Visualize non-correlation matrix, NA value and math label 362 | 363 | We can visualize a non-correlation matrix by set `is.corr=FALSE`, and 364 | assign colors by `col.lim`. If the matrix have both positive and 365 | negative values, the matrix transformation keep every values 366 | positiveness and negativeness. 367 | 368 | If your matrix is rectangular, you can adjust the aspect ratio with the 369 | `win.asp` parameter to make the matrix rendered as a square. 370 | 371 | ```{r non-corr} 372 | ## matrix in [20, 26], grid.col 373 | N1 = matrix(runif(80, 20, 26), 8) 374 | corrplot(N1, is.corr = FALSE, col.lim = c(20, 30), method = 'color', tl.pos = 'n', 375 | col = COL1('YlGn'), cl.pos = 'b', addgrid.col = 'white', addCoef.col = 'grey50') 376 | 377 | 378 | ## matrix in [-15, 10] 379 | N2 = matrix(runif(80, -15, 10), 8) 380 | 381 | ## using sequential colors, transKeepSign = FALSE 382 | corrplot(N2, is.corr = FALSE, transKeepSign = FALSE, method = 'color', col.lim = c(-15, 10), 383 | tl.pos = 'n', col = COL1('YlGn'), cl.pos = 'b', addCoef.col = 'grey50') 384 | 385 | ## using diverging colors, transKeepSign = TRUE (default) 386 | corrplot(N2, is.corr = FALSE, col.lim = c(-15, 10), 387 | tl.pos = 'n', col = COL2('PiYG'), cl.pos = 'b', addCoef.col = 'grey50') 388 | 389 | ## using diverging colors 390 | corrplot(N2, is.corr = FALSE, method = 'color', col.lim = c(-15, 10), tl.pos = 'n', 391 | col = COL2('PiYG'), cl.pos = 'b', addCoef.col = 'grey50') 392 | ``` 393 | 394 | Notice: when `is.corr` is `TRUE`, `col.lim` only affect the color legend If 395 | you change it, the color on correlation matrix plot is still assigned on 396 | `c(-1, 1)` 397 | 398 | ```{r col-lim} 399 | # when is.corr=TRUE, col.lim only affect the color legend display 400 | corrplot(M/2) 401 | corrplot(M/2, col.lim=c(-0.5, 0.5)) 402 | ``` 403 | 404 | By default, **corrplot** renders NA values as `'?'` characters. Using 405 | `na.label` parameter, it is possible to use a different value (max. two 406 | characters are supported). 407 | 408 | Since version `0.78`, it is possible to use 409 | [plotmath](https://www.rdocumentation.org/packages/grDevices/topics/plotmath) 410 | expression in variable names. To activate plotmath rendering, prefix 411 | your label with `'$'`. 412 | 413 | ```{r NA-math} 414 | M2 = M 415 | diag(M2) = NA 416 | colnames(M2) = rep(c('$alpha+beta', '$alpha[0]', '$alpha[beta]'), 417 | c(4, 4, 3)) 418 | rownames(M2) = rep(c('$Sigma[i]^n', '$sigma', '$alpha[0]^100', '$alpha[beta]'), 419 | c(2, 4, 2, 3)) 420 | corrplot(10*abs(M2), is.corr = FALSE, col.lim = c(0, 10), tl.cex = 1.5) 421 | ``` 422 | 423 | ## Visualize p-value and confidence interval 424 | 425 | `corrplot()` can also visualize p-value and confidence interval on the 426 | correlation matrix plot. Here are some important parameters. 427 | 428 | About p-value: 429 | 430 | - `p.mat` is the p-value matrix, if `NULL`, parameter `sig.level`, 431 | `insig, pch`, `pch.col`, `pch.cex` are invalid. 432 | - `sig.level` is significant level, with default value 0.05. If the 433 | p-value in `p-mat` is bigger than `sig.level`, then the 434 | corresponding correlation coefficient is regarded as insignificant. 435 | If `insig` is `'label_sig'`, `sig.level` can be an increasing vector 436 | of significance levels, in which case `pch` will be used once for 437 | the highest p-value interval and multiple times (e.g. `'*'`, `'**'`, 438 | `'***'`) for each lower p-value interval. 439 | - `insig` Character, specialized insignificant correlation 440 | coefficients, `'pch'` (default), `'p-value'`, `'blank',` `'n'`, or 441 | `'label_sig'`. If `'blank'`, wipe away the corresponding glyphs; if 442 | `'p-value'`, add p-values the corresponding glyphs; if `'pch'`, add 443 | characters (see pch for details) on corresponding glyphs; if `'n'`, 444 | don't take any measures; if `'label_sig'`, mark significant 445 | correlations with `pch` (see `sig.level`). 446 | - `pch` is for adding character on the glyphs of insignificant 447 | correlation coefficients (only valid when insig is `'pch'`). See 448 | `?par` . 449 | 450 | About confidence interval: 451 | 452 | - `plotCI` is character for the method of plotting confidence 453 | interval. If `'n'`, don't plot confidence interval. If `'rect'`, 454 | plot rectangles whose upper side means upper bound and lower side 455 | means lower bound respectively. 456 | - `lowCI.mat` is the matrix of the lower bound of confidence interval. 457 | - `uppCI.mat` is the Matrix of the upper bound of confidence interval. 458 | 459 | We can get p-value matrix and confidence intervals matrix by 460 | `cor.mtest()` which returns a list containing: 461 | 462 | - `p` is the p-values matrix. 463 | - `lowCI` is the lower bound of confidence interval matrix. 464 | - `uppCI` is the lower bound of confidence interval matrix. 465 | 466 | ```{r test} 467 | testRes = cor.mtest(mtcars, conf.level = 0.95) 468 | 469 | ## specialized the insignificant value according to the significant level 470 | corrplot(M, p.mat = testRes$p, sig.level = 0.10, order = 'hclust', addrect = 2) 471 | 472 | 473 | ## leave blank on non-significant coefficient 474 | ## add significant correlation coefficients 475 | corrplot(M, p.mat = testRes$p, method = 'circle', type = 'lower', insig='blank', 476 | addCoef.col ='black', number.cex = 0.8, order = 'AOE', diag=FALSE) 477 | ``` 478 | 479 | ```{r special} 480 | ## leave blank on non-significant coefficient 481 | ## add all correlation coefficients 482 | corrplot(M, p.mat = testRes$p, method = 'circle', type = 'lower', insig='blank', 483 | order = 'AOE', diag = FALSE)$corrPos -> p1 484 | text(p1$x, p1$y, round(p1$corr, 2)) 485 | ``` 486 | 487 | ```{r p-values} 488 | ## add p-values on no significant coefficients 489 | corrplot(M, p.mat = testRes$p, insig = 'p-value') 490 | 491 | ## add all p-values 492 | corrplot(M, p.mat = testRes$p, insig = 'p-value', sig.level = -1) 493 | 494 | ## add significant level stars 495 | corrplot(M, p.mat = testRes$p, method = 'color', diag = FALSE, type = 'upper', 496 | sig.level = c(0.001, 0.01, 0.05), pch.cex = 0.9, 497 | insig = 'label_sig', pch.col = 'grey20', order = 'AOE') 498 | 499 | ## add significant level stars and cluster rectangles 500 | corrplot(M, p.mat = testRes$p, tl.pos = 'd', order = 'hclust', addrect = 2, 501 | insig = 'label_sig', sig.level = c(0.001, 0.01, 0.05), 502 | pch.cex = 0.9, pch.col = 'grey20') 503 | ``` 504 | 505 | Visualize confidence interval. 506 | 507 | ```{r confidence-interval} 508 | # Visualize confidence interval 509 | corrplot(M, lowCI = testRes$lowCI, uppCI = testRes$uppCI, order = 'hclust', 510 | tl.pos = 'd', rect.col = 'navy', plotC = 'rect', cl.pos = 'n') 511 | 512 | # Visualize confidence interval and cross the significant coefficients 513 | corrplot(M, p.mat = testRes$p, lowCI = testRes$lowCI, uppCI = testRes$uppCI, 514 | addrect = 3, rect.col = 'navy', plotC = 'rect', cl.pos = 'n') 515 | ``` 516 | 517 | ## References 518 | 519 | - Michael Friendly (2002). Corrgrams: Exploratory displays for correlation 520 | matrices. The American Statistician, 56, 316--324. 521 | 522 | - D.J. Murdoch, E.D. Chow (1996). A graphical display of large correlation 523 | matrices. The American Statistician, 50, 178--180. 524 | 525 | - Michael Hahsler, Christian Buchta and Kurt Hornik (2020). seriation: Infrastructure for Ordering 526 | Objects Using Seriation. R package version 1.2-9. https://CRAN.R-project.org/package=seriation 527 | 528 | - Hahsler M, Hornik K, Buchta C (2008). "Getting things in order: An introduction to the R package 529 | seriation." _Journal of Statistical Software_, *25*(3), 1-34. ISSN 1548-7660, doi: 530 | 10.18637/jss.v025.i03 (URL: https://doi.org/10.18637/jss.v025.i03), . 532 | -------------------------------------------------------------------------------- /vignettes/example-colorlegend.R: -------------------------------------------------------------------------------- 1 | ## diverging colors 2 | par(mar = c(0, 0, 0, 0) + 0.1) 3 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 4 | 5 | col = c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 6 | 7 | for(i in 1:length(col)) { 8 | colorlegend(COL2(col[i]), -10:10/10, align = 'l', cex = 0.8, xlim = c(0, 1), 9 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 10 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2, cex = 0.8) 11 | } 12 | 13 | 14 | 15 | ## sequential colors 16 | par(mar = c(0, 0, 0, 0) + 0.1) 17 | plot(0, xlim = c(-0.1, 1), ylim = c(0, 1), type = 'n') 18 | 19 | col = c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 20 | 'YlOrRd', 'YlOrBr', 'YlGn') 21 | 22 | for(i in 1:length(col)) { 23 | colorlegend(COL1(col[i]), 0:10, align = 'l', cex = 0.8, xlim = c(0, 1), 24 | ylim = c(i/length(col)-0.1, i/length(col)), vertical = FALSE) 25 | text(-0.01, i/length(col)-0.02, col[i], adj = 0.5, pos = 2) 26 | } 27 | 28 | 29 | 30 | ## other examples to show colorlegend function 31 | par(mar = rep(0, 4)) 32 | plot(0, xlim = c(0, 6), ylim = c(-0.5, 1.2), type = 'n') 33 | 34 | colorlegend(rainbow(100), 0:9) 35 | 36 | colorlegend(heat.colors(100), LETTERS[1:12], xlim = c(1, 2)) 37 | 38 | colorlegend(terrain.colors(100), 0:9, ratio.colbar = 0.6, 39 | lim.segment = c(0, 0.6), xlim = c(2, 3), align = 'l') 40 | 41 | colorlegend(topo.colors(100), 0:9, lim.segment = c(0, 0.6), 42 | xlim = c(3, 4), align = 'l', offset = 0) 43 | 44 | colorlegend(cm.colors(100), 1:5, xlim = c(4, 5)) 45 | 46 | colorlegend(sample(rainbow(12)), labels = LETTERS[1:12], 47 | at = seq(0.05, 0.95, len = 12), xlim = c(5, 6), align = 'r') 48 | 49 | colorlegend(colbar = grey(1:100 / 100), 1:10, col = 'red', align = 'l', 50 | xlim = c(0, 6), ylim = c(-0.5, -0.1), vertical = FALSE) 51 | 52 | colorlegend(sample(rainbow(12)), 53 | labels = LETTERS[1:12], at = seq(0.05, 0.95, len = 12), 54 | xlim = c(0, 6), ylim = c(1.1, 1.2), vertical = FALSE) 55 | -------------------------------------------------------------------------------- /vignettes/example-corrMatOrder.R: -------------------------------------------------------------------------------- 1 | M = cor(mtcars) 2 | 3 | (order.AOE = corrMatOrder(M, order = 'AOE')) 4 | (order.FPC = corrMatOrder(M, order = 'FPC')) 5 | (order.hc = corrMatOrder(M, order = 'hclust')) 6 | (order.hc2 = corrMatOrder(M, order = 'hclust', hclust.method = 'ward.D')) 7 | 8 | M.AOE = M[order.AOE, order.AOE] 9 | M.FPC = M[order.FPC, order.FPC] 10 | M.hc = M[order.hc, order.hc] 11 | M.hc2 = M[order.hc2, order.hc2] 12 | 13 | 14 | 15 | par(ask = TRUE) 16 | corrplot(M) 17 | corrplot(M.AOE) 18 | corrplot(M.FPC) 19 | corrplot(M.hc) 20 | 21 | corrplot(M.hc) 22 | corrRect.hclust(corr = M.hc, k = 2) 23 | 24 | corrplot(M.hc) 25 | corrRect.hclust(corr = M.hc, k = 3) 26 | 27 | corrplot(M.hc2) 28 | corrRect.hclust(M.hc2, k = 2, method = 'ward.D') 29 | -------------------------------------------------------------------------------- /vignettes/example-corrRect.R: -------------------------------------------------------------------------------- 1 | data(mtcars) 2 | M = cor(mtcars) 3 | 4 | r = rbind(c('gear', 'wt', 'qsec', 'carb'), 5 | c('wt', 'gear', 'carb', 'qsec')) 6 | corrplot(M, order = 'AOE') -> p 7 | corrRect(p, namesMat = r) 8 | 9 | # same as using pipe operator `|>` if R version >= 4.1.0: 10 | # corrplot(M, order = 'AOE') |> corrRect(namesMat = r) 11 | 12 | 13 | 14 | r = c('gear', 'carb', 'qsec', 'wt') 15 | corrplot(M, order = 'AOE', type='lower') -> p 16 | corrRect(p, namesMat = r) 17 | 18 | # same as using pipe operator `|>` if R version >= 4.1.0: 19 | # corrplot(M, order = 'AOE', type='lower') |> corrRect(namesMat = r) 20 | 21 | 22 | 23 | corrplot(M, order = 'hclust', type = 'upper') -> p 24 | corrRect(p, index = c(1, 6, 11)) 25 | 26 | # same as using pipe operator `|>` if R version >= 4.1.0: 27 | # corrplot(M, order = 'AOE', type='lower') |> corrRect(index = c(1, 6, 11)) 28 | 29 | 30 | 31 | corrplot(M, order = 'hclust') -> p 32 | corrRect(p, name = c('carb', 'qsec', 'gear')) 33 | 34 | # same as using pipe operator `|>` if R version >= 4.1.0: 35 | # corrplot(M, order = 'hclust') |> corrRect(name = c('carb', 'qsec', 'gear')) 36 | 37 | 38 | 39 | 40 | (order.hc = corrMatOrder(M, order = 'hclust')) 41 | (order.hc2 = corrMatOrder(M, order = 'hclust', hclust.method = 'ward.D')) 42 | M.hc = M[order.hc, order.hc] 43 | M.hc2 = M[order.hc2, order.hc2] 44 | 45 | par(ask = TRUE) 46 | 47 | # same as: corrplot(M, order = 'hclust', addrect = 2) 48 | corrplot(M.hc) 49 | corrRect.hclust(corr = M.hc, k = 2) 50 | 51 | # same as: corrplot(M, order = 'hclust', addrect = 3) 52 | corrplot(M.hc) 53 | corrRect.hclust(corr = M.hc, k = 3) 54 | 55 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D', addrect = 2) 56 | corrplot(M.hc2) 57 | corrRect.hclust(M.hc2, k = 2, method = 'ward.D') 58 | 59 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D', addrect = 3) 60 | corrplot(M.hc2) 61 | corrRect.hclust(M.hc2, k = 3, method = 'ward.D') 62 | 63 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D', addrect = 4) 64 | corrplot(M.hc2) 65 | corrRect.hclust(M.hc2, k = 4, method = 'ward.D') 66 | -------------------------------------------------------------------------------- /vignettes/example-corrRect.hclust.R: -------------------------------------------------------------------------------- 1 | data(mtcars) 2 | M = cor(mtcars) 3 | corrplot(M, order = 'FPC') -> p 4 | corrRect(p, index = c(1, 6, 11)) 5 | 6 | if(getRversion() >= '4.1.0') { 7 | corrplot(M, order = 'FPC') |> corrRect(index = c(1, 6, 11)) 8 | } 9 | 10 | (order.hc = corrMatOrder(M, order = 'hclust')) 11 | (order.hc2 = corrMatOrder(M, order = 'hclust', hclust.method = 'ward.D2')) 12 | M.hc = M[order.hc, order.hc] 13 | M.hc2 = M[order.hc2, order.hc2] 14 | 15 | par(ask = TRUE) 16 | 17 | # same as: corrplot(M, order = 'hclust', addrect = 2) 18 | corrplot(M.hc) 19 | corrRect.hclust(corr = M.hc, k = 2) 20 | 21 | # same as: corrplot(M, order = 'hclust', addrect = 3) 22 | corrplot(M.hc) 23 | corrRect.hclust(corr = M.hc, k = 3) 24 | 25 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 2) 26 | corrplot(M.hc2) 27 | corrRect.hclust(M.hc2, k = 2, method = 'ward.D2') 28 | 29 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 3) 30 | corrplot(M.hc2) 31 | corrRect.hclust(M.hc2, k = 3, method = 'ward.D2') 32 | 33 | # same as: corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 4) 34 | corrplot(M.hc2) 35 | corrRect.hclust(M.hc2, k = 4, method = 'ward.D2') 36 | -------------------------------------------------------------------------------- /vignettes/example-corrplot.R: -------------------------------------------------------------------------------- 1 | data(mtcars) 2 | M = cor(mtcars) 3 | set.seed(0) 4 | 5 | ## different color series 6 | ## COL2: Get diverging colors 7 | ## c('RdBu', 'BrBG', 'PiYG', 'PRGn', 'PuOr', 'RdYlBu') 8 | ## COL1: Get sequential colors 9 | ## c('Oranges', 'Purples', 'Reds', 'Blues', 'Greens', 'Greys', 'OrRd', 'YlOrRd', 'YlOrBr', 'YlGn') 10 | 11 | wb = c('white', 'black') 12 | 13 | par(ask = TRUE) 14 | 15 | ## different color scale and methods to display corr-matrix 16 | corrplot(M, method = 'number', col = 'black', cl.pos = 'n') 17 | corrplot(M, method = 'number') 18 | corrplot(M) 19 | corrplot(M, order = 'AOE') 20 | corrplot(M, order = 'AOE', addCoef.col = 'grey') 21 | 22 | corrplot(M, order = 'AOE', cl.length = 21, addCoef.col = 'grey') 23 | corrplot(M, order = 'AOE', col = COL2(n=10), addCoef.col = 'grey') 24 | 25 | corrplot(M, order = 'AOE', col = COL2('PiYG')) 26 | corrplot(M, order = 'AOE', col = COL2('PRGn'), addCoef.col = 'grey') 27 | corrplot(M, order = 'AOE', col = COL2('PuOr', 20), cl.length = 21, addCoef.col = 'grey') 28 | corrplot(M, order = 'AOE', col = COL2('PuOr', 10), addCoef.col = 'grey') 29 | 30 | corrplot(M, order = 'AOE', col = COL2('RdYlBu', 100)) 31 | corrplot(M, order = 'AOE', col = COL2('RdYlBu', 10)) 32 | 33 | 34 | corrplot(M, method = 'color', col = COL2(n=20), cl.length = 21, order = 'AOE', 35 | addCoef.col = 'grey') 36 | corrplot(M, method = 'square', col = COL2(n=200), order = 'AOE') 37 | corrplot(M, method = 'ellipse', col = COL2(n=200), order = 'AOE') 38 | corrplot(M, method = 'shade', col = COL2(n=20), order = 'AOE') 39 | corrplot(M, method = 'pie', order = 'AOE') 40 | 41 | ## col = wb 42 | corrplot(M, col = wb, order = 'AOE', outline = TRUE, cl.pos = 'n') 43 | 44 | ## like Chinese wiqi, suit for either on screen or white-black print. 45 | corrplot(M, col = wb, bg = 'gold2', order = 'AOE', cl.pos = 'n') 46 | 47 | 48 | ## mixed methods: It's more efficient if using function 'corrplot.mixed' 49 | ## circle + ellipse 50 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'd') 51 | corrplot(M, add = TRUE, type = 'lower', method = 'ellipse', order = 'AOE', 52 | diag = FALSE, tl.pos = 'n', cl.pos = 'n') 53 | 54 | ## circle + square 55 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'd') 56 | corrplot(M, add = TRUE, type = 'lower', method = 'square', order = 'AOE', 57 | diag = FALSE, tl.pos = 'n', cl.pos = 'n') 58 | 59 | ## circle + colorful number 60 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'd') 61 | corrplot(M, add = TRUE, type = 'lower', method = 'number', order = 'AOE', 62 | diag = FALSE, tl.pos = 'n', cl.pos = 'n') 63 | 64 | ## circle + black number 65 | corrplot(M, order = 'AOE', type = 'upper', tl.pos = 'tp') 66 | corrplot(M, add = TRUE, type = 'lower', method = 'number', order = 'AOE', 67 | col = 'black', diag = FALSE, tl.pos = 'n', cl.pos = 'n') 68 | 69 | 70 | ## order is hclust and draw rectangles 71 | corrplot(M, order = 'hclust') 72 | corrplot(M, order = 'hclust', addrect = 2) 73 | corrplot(M, order = 'hclust', addrect = 3, rect.col = 'red') 74 | corrplot(M, order = 'hclust', addrect = 4, rect.col = 'blue') 75 | corrplot(M, order = 'hclust', hclust.method = 'ward.D2', addrect = 4) 76 | 77 | ## visualize a matrix in [0, 1] 78 | corrplot(abs(M), order = 'AOE', col.lim = c(0, 1)) 79 | corrplot(abs(M), order = 'AOE', is.corr = FALSE, col.lim = c(0, 1)) 80 | 81 | 82 | # when is.corr=TRUE, col.lim only affect the color legend 83 | # If you change it, the color is still assigned on [-1, 1] 84 | corrplot(M/2) 85 | corrplot(M/2, col.lim = c(-0.5, 0.5)) 86 | 87 | # when is.corr=FALSE, col.lim is also used to assign colors 88 | # if the matrix have both positive and negative values 89 | # the matrix transformation keep every values positive and negative 90 | corrplot(M*2, is.corr = FALSE, col.lim = c(-2, 2)) 91 | corrplot(M*2, is.corr = FALSE, col.lim = c(-2, 2) * 2) 92 | corrplot(M*2, is.corr = FALSE, col.lim = c(-2, 2) * 4) 93 | 94 | ## 0.5~0.6 95 | corrplot(abs(M)/10+0.5, col = COL1('Greens', 10)) 96 | corrplot(abs(M)/10+0.5, is.corr = FALSE, col.lim = c(0.5, 0.6), col = COL1('YlGn', 10)) 97 | 98 | 99 | ## visualize a matrix in [-100, 100] 100 | ran = round(matrix(runif(225, -100, 100), 15)) 101 | corrplot(ran, is.corr = FALSE) 102 | corrplot(ran, is.corr = FALSE, col.lim = c(-100, 100)) 103 | 104 | ## visualize a matrix in [100, 300] 105 | ran2 = ran + 200 106 | 107 | # bad color, not suitable for a matrix in [100, 300] 108 | corrplot(ran2, is.corr = FALSE, col.lim = c(100, 300), col = COL2(, 100)) 109 | 110 | # good color 111 | corrplot(ran2, is.corr = FALSE, col.lim = c(100, 300), col = COL1(, 100)) 112 | 113 | 114 | ## text-labels and plot type 115 | corrplot(M, order = 'AOE', tl.srt = 45) 116 | corrplot(M, order = 'AOE', tl.srt = 60) 117 | corrplot(M, order = 'AOE', tl.pos = 'd', cl.pos = 'n') 118 | corrplot(M, order = 'AOE', diag = FALSE, tl.pos = 'd') 119 | corrplot(M, order = 'AOE', type = 'upper') 120 | corrplot(M, order = 'AOE', type = 'upper', diag = FALSE) 121 | corrplot(M, order = 'AOE', type = 'lower', cl.pos = 'b') 122 | corrplot(M, order = 'AOE', type = 'lower', cl.pos = 'b', diag = FALSE) 123 | 124 | 125 | 126 | #### color-legend 127 | corrplot(M, order = 'AOE', cl.ratio = 0.2, cl.align = 'l') 128 | corrplot(M, order = 'AOE', cl.ratio = 0.2, cl.align = 'c') 129 | corrplot(M, order = 'AOE', cl.ratio = 0.2, cl.align = 'r') 130 | corrplot(M, order = 'AOE', cl.pos = 'b') 131 | corrplot(M, order = 'AOE', cl.pos = 'b', tl.pos = 'd') 132 | corrplot(M, order = 'AOE', cl.pos = 'n') 133 | 134 | 135 | ## deal with missing Values 136 | M2 = M 137 | diag(M2) = NA 138 | corrplot(M2) 139 | corrplot(M2, na.label = 'o') 140 | corrplot(M2, na.label = 'NA') 141 | 142 | 143 | ##the input matrix is not square 144 | corrplot(M[1:8, ]) 145 | corrplot(M[, 1:8]) 146 | 147 | testRes = cor.mtest(mtcars, conf.level = 0.95) 148 | 149 | ## specialized the insignificant value according to the significant level 150 | corrplot(M, p.mat = testRes$p, sig.level = 0.05, order = 'hclust', addrect = 2) 151 | 152 | ## leave blank on no significant coefficient 153 | corrplot(M, p.mat = testRes$p, method = 'circle', type = 'lower', insig ='blank', 154 | addCoef.col ='black', number.cex = 0.8, order = 'AOE', diag = FALSE) 155 | 156 | ## add p-values on no significant coefficients 157 | corrplot(M, p.mat = testRes$p, insig = 'p-value') 158 | 159 | ## add all p-values 160 | corrplot(M, p.mat = testRes$p, insig = 'p-value', sig.level = -1) 161 | 162 | ## add significant level stars 163 | corrplot(M, p.mat = testRes$p, method = 'color', diag = FALSE, type = 'upper', 164 | sig.level = c(0.001, 0.01, 0.05), pch.cex = 0.9, 165 | insig = 'label_sig', pch.col = 'grey20', order = 'AOE') 166 | 167 | ## add significant level stars and cluster rectangles 168 | corrplot(M, p.mat = testRes$p, tl.pos = 'd', order = 'hclust', addrect = 2, 169 | insig = 'label_sig', sig.level = c(0.001, 0.01, 0.05), 170 | pch.cex = 0.9, pch.col = 'grey20') 171 | 172 | # Visualize confidence interval 173 | corrplot(M, lowCI = testRes$lowCI, uppCI = testRes$uppCI, order = 'hclust', 174 | tl.pos = 'd', rect.col = 'navy', plotC = 'rect', cl.pos = 'n') 175 | 176 | # Visualize confidence interval and cross the significant coefficients 177 | corrplot(M, p.mat = testRes$p, lowCI = testRes$lowCI, uppCI = testRes$uppCI, 178 | addrect = 3, rect.col = 'navy', plotC = 'rect', cl.pos = 'n') 179 | 180 | 181 | 182 | res1 = cor.mtest(mtcars, conf.level = 0.95) 183 | res2 = cor.mtest(mtcars, conf.level = 0.99) 184 | 185 | 186 | ## plot confidence interval(0.95), 'circle' method 187 | corrplot(M, low = res1$uppCI, upp = res1$uppCI, 188 | plotCI = 'circle', addg = 'grey20', cl.pos = 'n') 189 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 190 | plotCI = 'circle', addg = 'grey20', cl.pos = 'n') 191 | corrplot(M, low = res1$lowCI, upp = res1$uppCI, 192 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', 193 | plotCI = 'circle', cl.pos = 'n', pch.col = 'red') 194 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 195 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', 196 | plotCI = 'circle', cl.pos = 'n', pch.col = 'red') 197 | 198 | ## plot confidence interval(0.95), 'square' method 199 | corrplot(M, low = res1$lowCI, upp = res1$uppCI, 200 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', 201 | plotCI = 'square', addg = NULL, cl.pos = 'n') 202 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 203 | col = c('white', 'black'), bg = 'gold2', order = 'AOE', pch.col = 'red', 204 | plotCI = 'square', addg = NULL, cl.pos = 'n') 205 | 206 | ## plot confidence interval0.95, 0.95, 0.99, 'rect' method 207 | corrplot(M, low = res1$lowCI, upp = res1$uppCI, order = 'hclust', 208 | rect.col = 'navy', plotCI = 'rect', cl.pos = 'n') 209 | corrplot(M, p.mat = res1$p, low = res1$lowCI, upp = res1$uppCI, 210 | order = 'hclust', pch.col = 'red', sig.level = 0.05, addrect = 3, 211 | rect.col = 'navy', plotCI = 'rect', cl.pos = 'n') 212 | corrplot(M, p.mat = res2$p, low = res2$lowCI, upp = res2$uppCI, 213 | order = 'hclust', pch.col = 'red', sig.level = 0.01, addrect = 3, 214 | rect.col = 'navy', plotCI = 'rect', cl.pos = 'n') 215 | 216 | 217 | ## an animation of changing confidence interval in different significance level 218 | ## begin.animaton 219 | par(ask = FALSE) 220 | for (i in seq(0.1, 0, -0.005)) { 221 | tmp = cor.mtest(mtcars, conf.level = 1 - i) 222 | corrplot(M, p.mat = tmp$p, low = tmp$lowCI, upp = tmp$uppCI, order = 'hclust', 223 | pch.col = 'red', sig.level = i, plotCI = 'rect', cl.pos = 'n', 224 | mar = c(0, 0, 1, 0), 225 | title = substitute(alpha == x, 226 | list(x = format(i, digits = 3, nsmall = 3)))) 227 | Sys.sleep(0.15) 228 | } 229 | ## end.animaton 230 | -------------------------------------------------------------------------------- /vignettes/example-corrplot.mixed.R: -------------------------------------------------------------------------------- 1 | M = cor(mtcars) 2 | ord = corrMatOrder(M, order = 'AOE') 3 | M2 = M[ord, ord] 4 | 5 | 6 | corrplot.mixed(M2) 7 | corrplot.mixed(M2, lower = 'ellipse', upper = 'circle') 8 | corrplot.mixed(M2, lower = 'square', upper = 'circle') 9 | corrplot.mixed(M2, lower = 'shade', upper = 'circle') 10 | corrplot.mixed(M2, tl.pos = 'lt') 11 | corrplot.mixed(M2, tl.pos = 'lt', diag = 'u') 12 | corrplot.mixed(M2, tl.pos = 'lt', diag = 'l') 13 | corrplot.mixed(M2, tl.pos = 'n') 14 | -------------------------------------------------------------------------------- /vignettes/webimg/rectangles-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taiyun/corrplot/62532f700e6c9d04b93ffbf0bf56e264b0e0368e/vignettes/webimg/rectangles-1.png --------------------------------------------------------------------------------