Reputation: 10510
In a heatmap, how could I create a three-color gradient, with blue for negative values, red for positive values and white for zero, such that with many zero values, much of the heatmap would be white (and not light red as with the default gradient).
A = [5 0 -3 -2 7; 0 5 0 0 0; -2 0 -1 0 0; -4 0 0 -10 0; 0 0 0 0 9]
using Plots
heatmap(Array(A),
c = cgrad([:blue,:white,:red]),
yflip = true,
xlabel = "row", ylabel = "col",
title = "Nonzeros, Positives, Negatives, in Matrix")
Here the gradient is automatically centered at the midpoint, a sensible default.
Related: here.
Post-Scriptum
As BallPointBen suggests, it would seem that computing the range of values is the recommended approach. Here is some benchmarking. The best approach, suggested by BallPointBen, is max = maximum(abs, A)
julia> using BenchmarkTools
julia> A = rand(10_000, 10_100)
julia> @btime max = maximum(abs.(A))
432.837 ms (6 allocations: 770.57 MiB)
0.999999999929502
julia> @btime max = maximum(abs.(extrema(A)))
339.597 ms (5 allocations: 144 bytes)
0.999999999929502
julia> @btime max = maximum(abs, A)
60.690 ms (1 allocation: 16 bytes)
0.9999999985609005
Upvotes: 1
Views: 1434
Reputation: 13750
You can compute the maximum absolute value in your array, then use it to set the clims
argument. c.f. http://docs.juliaplots.org/latest/generated/attributes_subplot/
julia> max_val = maximum(abs, A)
10
julia> heatmap(Array(A),
c = cgrad([:blue,:white,:red]),
yflip = true,
xlabel = "row", ylabel = "col",
title = "Nonzeros, Positives, Negatives, in Matrix",
clims=(-max_val, max_val))
Upvotes: 2