Fancy Correlation Plots in MATLAB

I'm trying to find a way to generate these pretty correlation plots in MATLAB. These are generated in R using 'corrplot' function, but couldn't find any similar code in MATLAB. Any help would be appreciated.
As a quick description, this function will create a color scale of the correlation values, and create circles in each cell of the correlation matrix/plot with the associated color. The size of the circles is also an indicator of the magnitude of the correlation, with larger circles representing a stronger relationship (positive or negative). More details could be found here.

 Accepted Answer

Maybe something like this can work for you (after more polishing)
% sample correlation matrix
r = normalize(randn(10, 10), 'range', [-1, 1]);
for i = 1:size(r, 1)
r(i, i) = 1;
end
% labels
labels = "variable" + (1:size(r, 1));
% scatter plot
n = size(r, 1);
y = triu(repmat(n+1, n, n) - (1:n)') + 0.5;
x = triu(repmat(1:n, n, 1)) + 0.5;
x(x == 0.5) = NaN;
scatter(x(:), y(:), 400.*abs(r(:)), r(:), 'filled', 'MarkerFaceAlpha', 0.6)
% enclose markers in a grid
xl = [1:n+1;repmat(n+1, 1, n+1)];
xl = [xl(:, 1), xl(:, 1:end-1)];
yl = repmat(n+1:-1:1, 2, 1);
line(xl, yl, 'color', 'k') % horizontal lines
line(yl, xl, 'color', 'k') % vertical lines
% show labels
text(1:n, (n:-1:1) + 0.5, labels, 'HorizontalAlignment', 'right')
text((1:n) + 0.5, repmat(n + 1, n, 1), labels, ...
'HorizontalAlignment', 'right', 'Rotation', 270)
h = gca;
colorbar(h);
h.Visible = 'off';
h.Position(4) = h.Position(4)*0.9;
axis(h, 'equal')
colormap('jet')

3 Comments

emami.m
emami.m on 23 Dec 2020
Edited: emami.m on 23 Dec 2020
Thank you Ive J, it's perfect.
Just another quick question. Why circle colors are a bit different from the color bar? For instance, the diagonal values which are equal to one are not the exact color for 1 in the color bar.
Ive J
Ive J on 23 Dec 2020
Edited: Ive J on 23 Dec 2020
That's because of MarkerFaceAlpha. If you remove that argument, everything works fine.
Thank you !

Sign in to comment.

More Answers (2)

emami.m
emami.m on 23 Dec 2020
Edited: emami.m on 23 Dec 2020
Thanks to Mathieu NOE I have edited the code provided in this post:
to produce more similar graph to the one I was looking for (The one generated with R).
Also an issue with circle size for correlations in [-1,1] has been solved.
This code can produce triangular display as well.
Custom colormap and a sample graph that I generated is attached.
For using custom colormap, uncomment line 7,21,34.
% Produce the input lower triangular matrix data
C = -1 + 2.*rand(12,12);
C = tril(C,-1);
C(logical(eye(size(C)))) = 1;
% Set [min,max] value of C to scale colors
clrLim = [-1,1];
% load('CorrColormap.mat') % Uncomment for custom CorrColormap
% Set the [min,max] of diameter where 1 consumes entire grid square
diamLim = [0.1, 1];
myLabel = {'ICA','Elev','Pr','Rmax','Rmin','Srad','Wspd','Tmin','Tmax','VPD','ET_o','AW'};
% Compute center of each circle
% This assumes the x and y values were not entered in imagesc()
x = 1 : 1 : size(C,2); % x edges
y = 1 : 1 : size(C,1); % y edges
[xAll, yAll] = meshgrid(x,y);
xAll(C==0)=nan; % eliminate cordinates for zero correlations
% Set color of each rectangle
% Set color scale
cmap = jet(256);
% cmap = CorrColormap; % Uncomment for CorrColormap
Cscaled = (C - clrLim(1))/range(clrLim); % always [0:1]
colIdx = discretize(Cscaled,linspace(0,1,size(cmap,1)));
% Set size of each circle
% Scale the size between [0 1]
Cscaled = (abs(C) - 0)/1;
diamSize = Cscaled * range(diamLim) + diamLim(1);
% Create figure
fh = figure();
ax = axes(fh);
hold(ax,'on')
colormap(ax,'jet');
% colormap(CorrColormap) %Uncomment for CorrColormap
tickvalues = 1:length(C);
x = zeros(size(tickvalues));
text(x, tickvalues, myLabel, 'HorizontalAlignment', 'right');
x(:) = length(C)+1;
text(tickvalues, x, myLabel, 'HorizontalAlignment', 'right','Rotation',90);
% Create circles
theta = linspace(0,2*pi,50); % the smaller, the less memory req'd.
h = arrayfun(@(i)fill(diamSize(i)/2 * cos(theta) + xAll(i), ...
diamSize(i)/2 * sin(theta) + yAll(i), cmap(colIdx(i),:),'LineStyle','none'),1:numel(xAll));
axis(ax,'equal')
axis(ax,'tight')
set(ax,'YDir','Reverse')
colorbar()
caxis(clrLim);
axis off

8 Comments

excellent work !!
Some suggestions,
1. Avoid using length(), especially with matricies and multidimensional arrays.
tickvalues = 1:size(C,2); % <----
x = zeros(size(tickvalues));
text(. . .);
x = size(C,1)+1; % <----
text(. . .);
2. Use ticklabels instead of text and keep the axes on. Otherwise if you want to change your axis limits or zoom into something on the axes you'll lose the positioning of the text relative to the axis lines.
tickvalues = 1:size(C,2);
set(ax,'XTick',tickvalues,'XTickLabel',myLabel)
set(ax,'YTick',tickvalues,'YTickLabel',myLabel)
ax.XAxis.TickLabelRotation = 90;
Adding grid on may help with visual aligmnet of smaller markers.
3. Why reverse the y axis? Normally in correlation plots point (n,n) refers to the same conditions along the x and y axes.
4. Minor, but label the colorbar
cb = colorbar();
ylabel(cb, 'correlation coefficient')
With these suggestions,
.... and remove / comment axis off
otherwise you lose all axis labeling, tick marks and background
Thank you Adam Danz and Mathieu NOE for sharing good points.
you're welcome !
I have a question about the last graph in matlab, can you show the values as in the second graph of R? (the graph of R is in the first comment)
Thanks for sharing this and it helps me a lot. Just one tiny thing I found out during my time playing with this script is that the following lines:
Cscaled = (C - clrLim(1))/range(clrLim); % always [0:1]
colIdx = discretize(Cscaled,linspace(0,1,size(cmap,1)));
may cause a problem if (1) clrlim is switched to [0 1] and (2) the max of C is larger than 1. In this case the current Cscaled line actually does not scaled C at all, resulting in NaN values in colIdx at positions i where C(i) > 1. I modified the Cscaled line to overcome this problem:
Cscaled = (C - min(C(:)))/(max(C(:))-min(C(:)));
Hope this helps!
Thank you for sharing it!

Sign in to comment.

jon erickson
jon erickson on 18 Sep 2025
Thanks for sharing this. For producing a single, standalone figure this works well. However, in the case of wishing to compare two correlation matrices (say a before and after intervention), the color indexing can vary wildly depending on the nature of the data. So the use case is limited in this sense.

1 Comment

hello
why woudn't it possible to compare two correlation plots ? I don't see what speaks against that

Sign in to comment.

Categories

Asked:

on 21 Dec 2020

Commented:

on 19 Sep 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!