How to plot matrix as gradient grid?

Hello,
I have a matrix of floating numbers that I would like to plot as a grid whose cells are shaded according to these numbers. Thus, having

julia> grid = rand(Float32, 5, 5)
5×5 Matrix{Float32}:
 0.157996  0.965474   0.869818  0.741637   0.621585
 0.799489  0.944857   0.243435  0.0732432  0.928711
 0.143084  0.755295   0.153082  0.45804    0.586859
 0.896089  0.772248   0.631192  0.0818451  0.586762
 0.689304  0.0514671  0.73454   0.567052   0.735969

I would like to get:

What would be the syntax?
Thank you

Oh, do you mean just like a heatmap?

Makie.jl: heatmap

Plots.jl: Heatmap, categorical axes, and aspect_ratio · Plots

2 Likes

Exactly! Thank you

using CairoMakie
xs = collect(range(1,stop=5)) 
ys = collect(range(1,stop=5)) 
zs = [cos(x) * sin(y) for x in xs, y in ys]
fig, ax, hm = heatmap(xs, ys, grid)
Colorbar(fig[:, end+1], hm)

Nice! CairoMakie is my favorite =]

In case you are interested in doing more stats-oriented plotting, AlgebraOfGraphics.jl is built-on top of Makie.jl and it gives you superpowers

1 Like

You might also like the aspect/Aspect keyword/object if you want the grid to be squares :slight_smile:

1 Like

Good point. I tried with

ax = Axis(fig[1, 1], ...aspect = 1)

but it came out rectangular…

using CairoMakie
using ColorSchemes
xs = collect(range(1,stop=5))
ys = collect(range(1,stop=5))
grid1 = rand(Float16, 5, 5)
grid2 = rand(Float16, 5, 5)
grid = grid1/grid2
fig, ax, hm = heatmap(xs, ys, grid,  colormap = :bwr) # or :roma
ax = Axis(fig[1, 1], aspect = 1, xlabel = "X", ylabel = "Y",
    title = "Title")
Colorbar(fig[:, end+1], hm)
save("heatmap.png", fig, px_per_unit = 2)


It looks like two plots have merged…

Yea, so I think there’s a couple things going on here. The merged look is coming from the two separate axes that are being set up (one from fig, ax, hm = ..., and the other from ax = Axis(...)), so I would just pick one and go with that. If we go with the first way, we can pass a special keyword arg

The other thing that I think is going on is that aspect = 1 will take care of the aspect ratio of the axis for us, but the figure will still need some special care to get right. There is a really nice way to do this that was recently added that I think @jacobusmmsmit was referring to, so I might try something like this:

xs = 1:5 # Don't think we need to collect here, a UnitRange should be fine
ys = 1:5
grid1 = rand(Float16, 5, 5)
grid2 = rand(Float16, 5, 5)
grid = grid1/grid2

fig, ax, hm = heatmap(xs, ys, grid;
    axis = (xlabel="X", ylabel="Y"),
    colormap = :bwr,
)

Colorbar(fig[:, end+1], hm)

colsize!(fig.layout, 1, Aspect(1, 1.0))
resize_to_layout!(fig)

fig

2 Likes

Perfect! Thank you.

An addition: how can I show a grid (to facilitate the discrimination between cells of equal color)? Thanks

I think this was addressed here How to add grid lines on top of a heatmap in Makie? - #2 by jules

So basically just:

using CairoMakie

fig = Figure()
ax = Axis(fig[1, 1];
	xgridcolor = :white,
	xgridstyle = :dot,
	xgridwidth = 10,
	ygridcolor = :red,
	ygridwidth = 10,
)

hm = heatmap!(ax, rand(5, 5))

translate!(hm, 0, 0, -100)

fig

A bunch more options can be found here API

I have seen that, but I am initializing fig, ax, hm in a single call. To me, the lines do not appear:

using CairoMakie
using ColorSchemes
xs = 1:11
ys = 1:11
grid1 = rand(Float16, 11, 11)
grid2 = rand(Float16, 11, 11)
grid = grid1/grid2
fig, ax, hm = heatmap(xs, ys, grid;
    axis = (xlabel="X", ylabel="Y", xgridcolor = :black, ygridcolor = :black),
    colormap = :bwr)
Colorbar(fig[:, end+1], hm)
colsize!(fig.layout, 1, Aspect(1, 1.0))
resize_to_layout!(fig)
save("heatmap.png", fig, px_per_unit = 2)

You don’t have the line translate!(hm, 0, 0, -100), just add that after the heatmap call.

1 Like

Yep, thank you!