# How can i plot a Correlation HeatMap?

**URL:** <https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411>\
**Category:** General Usage\
**Tags:** question, plotting, plots, statsplots\
**Created:** [March 24, 2022, 4:01pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411 "2022-03-24T16:01:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![folleyz](https://avatars.discourse-cdn.com/v4/letter/f/977dab/32.png) [@folleyz](https://discourse.julialang.org/u/folleyz)\
**Post date:** [March 24, 2022, 4:01pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/1 "2022-03-24T16:01:13Z")

</div>

Hello Guys!

I need a help. i want make this heatmap:

![heat](https://global.discourse-cdn.com/julialang/original/3X/f/9/f96b45dbb322dd82cc30fc77434e64b9cc2a2a5a.png)

I’m trying with that code:

```julia
Plots.heatmap(cor(Matrix(df[!,[:Age,:Balance, :Tenure,:NumOfProducts,:EstimatedSalary]]))
)

```

![image](https://global.discourse-cdn.com/julialang/original/3X/b/b/bb2810ca47e902fff65a0037e578265419103f38.png)

\*\*

> **But how can i put the annotations of the correlation values and the columns names in the ticks?**

\*\*

Another try but using a DataFrame:

```julia
a = DataFrame(cor(Matrix(df[!,[:Age,:Balance, :Tenure,:NumOfProducts, :EstimatedSalary]])), [:Age,:Balance, :Tenure,:NumOfProducts, :EstimatedSalary]) 

```

| Age | Balance | Tenure | NumOfProducts | EstimatedSalary | |
| --- | --- | --- | --- | --- | --- |
| | Float64 | Float64 | Float64 | Float64 | Float64 |
| 1 | 1.0 | 0.0283084 | -0.00999683 | -0.0306801 | -0.00720104 |
| | | | | | |
| 2 | 0.0283084 | 1.0 | -0.0122539 | -0.30418 | 0.0127975 |
| | | | | | |
| 3 | -0.00999683 | -0.0122539 | 1.0 | 0.0134438 | 0.00778383 |
| | | | | | |
| 4 | -0.0306801 | -0.30418 | 0.0134438 | 1.0 | 0.0142042 |
| | | | | | |
| 5 | -0.00720104 | 0.0127975 | 0.00778383 | 0.0142042 | 1.0 |
| | | | | | |

```julia
begin
@df a Plots.heatmap(cols([:Age,:Balance, :Tenure,:NumOfProducts,:EstimatedSalary]))
	annotate!([(1, 1, (a[1,1], 8, :red, :center))])
end

```

![image](https://global.discourse-cdn.com/julialang/original/3X/d/b/db5f0010bdb54d9af07c1534be842ac60ccec12a.png)

Here i used annotate to create the correlation value, but i made this manually and have no idea of how to put the column names in the ticks.

Have another clever or easier way to do that?

Thx!

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 24, 2022, 7:17pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/2 "2022-03-24T19:17:01Z")

</div>

> [@folleyz](#):
>
> But how can i put the annotations of the correlation values and the columns names in the ticks?

One way is by searching discourse, which led me [here](https://discourse.julialang.org/t/why-this-code-cant-annote-all-heatmap-cells/69431).

---

<div class="post-metadata">

**Author:** ![folleyz](https://avatars.discourse-cdn.com/v4/letter/f/977dab/32.png) [@folleyz](https://discourse.julialang.org/u/folleyz)\
**Post date:** [March 24, 2022, 7:39pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/3 "2022-03-24T19:39:58Z")

</div>

I’m working all day on this and i found a solution, off course isn’t the best.

1 - First i created a dataframe with the correlations:

```julia
a = DataFrame(cor(Matrix(df[!,[:Age,:Balance, :Tenure,:NumOfProducts, :EstimatedSalary]])), [:Age,:Balance, :Tenure,:NumOfProducts, :EstimatedSalary]) 

```

| Age | Balance | Tenure | NumOfProducts | EstimatedSalary | |
| --- | --- | --- | --- | --- | --- |
| | Float64 | Float64 | Float64 | Float64 | Float64 |
| 1 | 1.0 | 0.0283084 | -0.00999683 | -0.0306801 | -0.00720104 |
| | | | | | |
| 2 | 0.0283084 | 1.0 | -0.0122539 | -0.30418 | 0.0127975 |
| | | | | | |
| 3 | -0.00999683 | -0.0122539 | 1.0 | 0.0134438 | 0.00778383 |
| | | | | | |
| 4 | -0.0306801 | -0.30418 | 0.0134438 | 1.0 | 0.0142042 |
| | | | | | |
| 5 | -0.00720104 | 0.0127975 | 0.00778383 | 0.0142042 | 1.0 |
| | | | | | |

2 - Then this for loop

```julia
begin
	g = []
	b = 1
	for e in 1:5
		for i in eachrow(a[!,[:Age,:Balance,:Tenure,:NumOfProducts,:EstimatedSalary]])
			if b == 1
				c = (e, e, (string(round(i[1],digits = 3)), 8, :red, :center))
			elseif b == e
				c = (e, 1, (string(round(i[1],digits = 3)), 8, :red, :center))
			else
				c = (e, b, (string(round(i[e],digits = 3)), 8, :red, :center))
			end
			
			if b <= 4 
				b += 1
			else
				b = 1
			end
			push!(g,c)
		end
	end
end

```

3 - Convert the types of g:

```julia
k = Vector{Tuple{Int64, Int64, Tuple{String, Int64, Symbol, Symbol}}}(g)

```

4 - Finally the Correlation Heatmap.

```julia
begin
	xlabel = names(a)
	
	@df a Plots.heatmap(cols([:Age,:Balance, :Tenure,:NumOfProducts,:EstimatedSalary]);
	xticks=(1:5, xlabel),
	yticks=(1:5, xlabel))
	annotate!(k)

end

```

![image](https://global.discourse-cdn.com/julialang/original/3X/3/1/3191675258ae96eef990c9dbc0d08d6ed41b469e.png)

Thx, with your post i implemented the columns names in the ticks

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 24, 2022, 8:06pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/4 "2022-03-24T20:06:07Z")

</div>

Fyi, plot argument `xrotation=90` rotates the xticks as per your model example.

---

<div class="post-metadata">

**Author:** ![folleyz](https://avatars.discourse-cdn.com/v4/letter/f/977dab/32.png) [@folleyz](https://discourse.julialang.org/u/folleyz)\
**Post date:** [March 24, 2022, 8:44pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/5 "2022-03-24T20:44:14Z")

</div>

> [@rafael.guerra](#):
>
> xrotation=90

Nice! thx for the tip.

Below the final function to plot a corr heatmap:

```julia

function corrheatmap(df::AbstractDataFrame ,colnames::Vector{Symbol})
	a = DataFrame(cor(Matrix(df[!,colnames])), colnames)
	
	g = []
	b = 1
	for e in 1:length(colnames)
		for i in eachrow(a[!,colnames])
			if b == 1 && e != 1
				c = (e, e, (string(round(i[1],digits = 3)), 8, :red, :center))
			elseif b == e
				c = (e, 1, (string(round(i[1],digits = 3)), 8, :red, :center))
			else
				c = (e, b, (string(round(i[e],digits = 3)), 8, :red, :center))
			end
			
			if b < length(colnames) 
				b += 1
			else
				b = 1
			end
			push!(g,c)
		end
	end

	k = Vector{Tuple{Int64, Int64, Tuple{String, Int64, Symbol, Symbol}}}(g)

	@df a Plots.heatmap(cols(colnames);
		xticks=(1:length(colnames), colnames),
		yticks=(1:length(colnames), colnames),
		xrotation = 90)
		annotate!(k)
	
end

```

```julia
corrheatmap(df,[:Age,:Balance,:EstimatedSalary])

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/2/2242c9178cd855eaebcd4bede51e5618ea6f7575.png)

👍

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 24, 2022, 11:32pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/6 "2022-03-24T23:32:26Z")

</div>

Your efforts are commendable, but please note that this task should be less labor intensive. For example we could do:

```julia
using DataFrames, Statistics, Plots

# INPUT DATA
df = DataFrame(Age=rand(4), Balance=rand(4), Tenure=rand(4), Salary=rand(4))
cols = [:Age, :Balance, :Tenure] # define subset
M = cor(Matrix(df[!,cols])) # correlation matrix

# PLOT
(n,m) = size(M)
heatmap(M, fc=cgrad([:white,:dodgerblue4]), xticks=(1:m,cols), xrot=90, yticks=(1:m,cols), yflip=true)
annotate!([(j, i, text(round(M[i,j],digits=3), 8,"Computer Modern",:black)) for i in 1:n for j in 1:m])

```

(_ **NB** :_ added `yflip=true` _for standard orientation of matrix display)_

 ![Plots_heatmap_corr_matrix_annotated](https://global.discourse-cdn.com/julialang/original/3X/a/7/a77ef9eb6fa9f3df5609de8e92cb9a4a88d3d60d.png)

---

<div class="post-metadata">

**Author:** ![folleyz](https://avatars.discourse-cdn.com/v4/letter/f/977dab/32.png) [@folleyz](https://discourse.julialang.org/u/folleyz)\
**Post date:** [March 25, 2022, 12:26am UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/7 "2022-03-25T00:26:53Z")

</div>

Wow! Nice @rafael.guerra !

Your solution its much better and clean, i’ll use that.

Thx for participating!

---

<div class="post-metadata">

**Author:** ![fabern](https://avatars.discourse-cdn.com/v4/letter/f/76d3ee/32.png) [@fabern](https://discourse.julialang.org/u/fabern)\
**Post date:** [October 27, 2023, 4:24pm UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/8 "2023-10-27T16:24:16Z")

</div>

If somebody arrives here looking for a solution with `Makie`. Below is an adaptation of @rafael.guerra’s code:

```julia
df = DataFrame(Age=rand(4), Balance=rand(4), Tenure=rand(4), Salary=rand(4))
cols = [:Age, :Balance, :Tenure] # define subset
M = cor(Matrix(df[!,cols])) # correlation matrix
(n,m) = size(M)
# # Plots.jl
# Plots.heatmap(M, fc=cgrad([:white,:dodgerblue4]), xticks=(1:m,cols), xrot=90, yticks=(1:m,cols), yflip=true)
# Plots.annotate!([(j, i, Plots.text(round(M[i,j],digits=3), 8,"Computer Modern",:black)) for i in 1:n for j in 1:m])
# Makie.jl
fig, axis_hm, plot_hm =
    Makie.heatmap(M;
        colormap = :RdBu, colorrange = (-1,1),
        axis = (xticks=(1:m, String.(cols)),
                yticks=(1:m,String.(cols)),
                yreversed=true,
                xticklabelrotation = π/2));
Makie.Colorbar(fig[1, 2], plot_hm);
[Makie.text!(axis_hm,
    "$(round(M[i,j],digits=3))",
    position = (i,j),
    align = (:center, :center), fontsize=14,
    color = ifelse(abs(M[i,j]) > 0.5, :white, :black))
    for i in 1:n for j in 1:m];
fig

```

 ![plot_367](https://global.discourse-cdn.com/julialang/original/3X/7/5/7557df5aa76ea731165d0181fae82bba199af78b.png)

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [March 13, 2024, 6:34am UTC](https://discourse.julialang.org/t/how-can-i-plot-a-correlation-heatmap/78411/9 "2024-03-13T06:34:52Z")

</div>

Bump to add PlotlyJS solution in case anyone is interest.

```julia
using Statistics
using DataFrames
using Printf
using PlotlyJS

function plot_cormap(df::AbstractDataFrame; colorscale="Viridis", fontcolor="#aabbcc", fontsize=14)
    m = cor(Matrix(df))
    annotations = [
        attr(text=@sprintf("%.2f", m[i,j]), x=names(df)[i], y=names(df)[j], showarrow=false, font=attr(size=fontsize, color=fontcolor)) for i in 1:size(m)[1] for j in 1:size(m)[2]
    ]
    t = heatmap(z=m, x=names(df), y=names(df), colorscale=colorscale)

    layout = Layout(;
        annotations
    )

    return plot(t, layout)
end

```

The following figure is produced by

```julia
df = DataFrame(rand(10, 10), :auto)
plot_cormap(df)

```

 ![newplot](https://global.discourse-cdn.com/julialang/original/3X/a/1/a191426d6d993141492ff5d62c793dbef1735830.png)
