Q:

How to plot, in R, a correlogram on top of a correlation matrix?

I've followed the instructions on this website from STHDA to plot correlation matrices and correlograms in R. The website and examples are really good. However, I'd like to plot the upper part of the correlogram over the upper part of the correlation matrix.
Here's the code:
library(PerformanceAnalytics)
chart.Correlation(mtcars, histogram=TRUE, pch=19)

This should give me the correlation matrix using scatter plots, together with the histogram, which I'd like to maintain. But for the upper part of the plot, I'd like to have the correlogram obtained from this code:
library(corrplot)
corrplot(cor(mtcars), type="upper", order="hclust", tl.col="black", tl.srt=45)

The obvious way of doing it is exporting all graphs in pdf and then work with Inkscape, but it would be nicer if I could get this directly from R. Is there any possible way for doing this?
Thanks.

A:

The trick to using the panel functions within pairs is found in help(pairs):

A panel function should not attempt to start a new plot, but just plot within a given coordinate system: thus 'plot' and 'boxplot' are not panel functions.

So, you should use graphic-adding functions, such as points, lines, polygon, or perhaps (when available) plot(..., add=TRUE), but not a straight-up plot. What you were suggesting in your comment (with SpatialPolygons) might have worked with some prodding if you actually tried to plot it on a device vice just returning it from your plotting function.
In my example below, I actually do "create a new plot", but I cheat (based on this SO post) by adding a second plot on top of the one already there. I do this to shortcut an otherwise necessary scale/shift, which would still not be perfect since you appear to want a "perfect circle", something that can really only be guaranteed with asp=1 (aspect ratio fixed at 1:1).
colorRange <- c('#69091e', '#e37f65', 'white', '#aed2e6', '#042f60')
## colorRamp() returns a function which takes as an argument a number
## on [0,1] and returns a color in the gradient in colorRange
myColorRampFunc <- colorRamp(colorRange)

panel.cor <- function(w, z, ...) {
    correlation <- cor(w, z)

    ## because the func needs [0,1] and cor gives [-1,1], we need to
    ## shift and scale it
    col <- rgb( myColorRampFunc( (1+correlation)/2 )/255 )

    ## square it to avoid visual bias due to "area vs diameter"
    radius <- sqrt(abs(correlation))
    radians <- seq(0, 2*pi, len=50)     # 50 is arbitrary
    x <- radius * cos(radians)
    y <- radius * sin(radians)
    ## make them full loops
    x <- c(x, tail(x,n=1))
    y <- c(y, tail(y,n=1))

    ## I trick the "don't create a new plot" thing by following the
    ## advice here: http://www.r-bloggers.com/multiple-y-axis-in-a-r-plot/
    ## This allows
    par(new=TRUE)
    plot(0, type='n', xlim=c(-1,1), ylim=c(-1,1), axes=FALSE, asp=1)
    polygon(x, y, border=col, col=col)
}

pairs(mtcars, upper.panel=panel.cor)

You can manipulate the size of the circles -- at the expense of unbiased visualization -- by playing with the radius. The colors I took directly from the page you linked to originally.
Similar functions can be used for your lower and diagonal panels.

