Single colorbar for heatmap grid layout

Take for example:

using Plots

plot(
    heatmap(rand(10,10)),
    heatmap(rand(10,10)),
    heatmap(rand(10,10)),
    heatmap(rand(10,10));
    layout=4
)

heatmaps

How could it be possible to have a single colorbar for all heatmaps?

If you don’t mind trying out a different package, this is one of the problems why I wrote MakieLayout http://makie.juliaplots.org/stable/makielayout/tutorial.html

Other than that, I think people have come up with hacks to solve your problem in Plots, too, maybe you can find other threads in this discourse as well

1 Like

Yes this isn’t easily possible in Plots.jl, as the plots are produced independently and there aren’t currently any figure level arguments (like figure title, legend etc.)

The usual hacks that I think Jules refers to are basically adding another subplot to your figure, which would just have the colorbar, and then do legend = :none on the heatmaps.

If you don’t mind one subplot being sized differently you could just do:

plot([[heatmap(rand(10, 10), legend = :none) for _ ∈ 1:3]; heatmap(rand(10, 10))]...)

image

This does what you want but not directly.

julia> ps = [heatmap(rand(10,10), legend=:none) for i=1:2,j=1:2] # Make heatmaps without legends
2×2 Matrix{Plots.Plot{Plots.GRBackend}}:
 Plot{Plots.GRBackend() n=1}  Plot{Plots.GRBackend() n=1}
 Plot{Plots.GRBackend() n=1}  Plot{Plots.GRBackend() n=1}

julia> l = @layout[grid(2,2) a{0.05w}] # Stack a layout that rightmost one is for color bar
Plots.GridLayout(1, 2)

julia> p = plot(ps..., heatmap((0:0.01:1).*ones(101,1), legend=:none, xticks=:none, yticks=(1:10:101, string.(0:0.1:1))), layout=l) # Plot them set y values of color bar accordingly

julia> savefig(p, "plot.png")

plot

4 Likes

Yes!! I was trying to do the same @layout trick, but couldn’t figure out how to make the single large colorbar. A smooth heatmap is very clever!