Plotting patches of constant values using Makie

Dear all,
I have an issue when plotting patches with Makie when the field has no spatial variations.
I provide a MWE below. The returned error is ArgumentError: range step cannot be zero if v=zeros(nel) (constant data) . However if v=rand(nel) it works.
I suspect that using limits=(min_v, max_v) is the source of the zero range step (since min_v==max_v). Commenting it disables the errors but also the plot (at least in Jupyter). Anyone has an idea of potential workarounds?

using CairoMakie
using Makie.GeometryBasics

function PatchPlotMakie(mesh, v, xmin, xmax, ymin, ymax; cmap = :viridis, min_v = minimum(v), max_v = maximum(v))
    f = Figure()
    ar = (maximum(mesh.xv) - minimum(mesh.xv)) / (maximum(mesh.xv) - minimum(mesh.yv))
    Axis(f[1, 1], aspect = ar)
    p = [Polygon( Point2f0[ (mesh.xv[mesh.e2v[i,j]], mesh.yv[mesh.e2v[i,j]]) for j=1:mesh.nf_el] ) for i in 1:mesh.nel]
    poly!(p, color = v, colormap = cmap, strokewidth = 0, strokecolor = :black, markerstrokewidth = 0, markerstrokecolor = (0, 0, 0, 0), aspect_ratio=:image, colorrange=(min_v,max_v))
    Colorbar(f[1, 2], colormap = cmap, limits=(min_v, max_v), flipaxis = true, size = 25, height = Relative(2/3) )
    display(f)
    return nothing
end

# Generate data
nel  = 4
v    = ones(nel)
# v    = rand(nel)
xv   = [-1.  .0  1. -1. .0  1. -1. .0  1.]
yv   = [-1. -1. -1.  .0 .0  .0  1. 1.  1.]
e2v  = [1 2 5 4; 2 3 6 5; 4 5 8 7; 5 6 9 8]
mesh = (xv=xv, yv=yv, e2v=e2v, nf_el=4, nel=nel )

# Call function
PlotMakie(mesh, v, minimum(xv), maximum(xv), minimum(yv), maximum(yv))

If you only have one value in your data, both the automatic colorrange calculation will fail and the Colorbar will also not like that the limits are the same. You should just catch this case and decide what you want your colors to be like. Think about it, with zero range of the colorbar, which color from the colormap should a point with that value have, all of them at the same time? The first? The last? The middle? It’s undefined.

Here’s one example where I increase the max by 1 if min and max are approximately the same:

using Makie.GeometryBasics

function PatchPlotMakie(msh, v, xmin, xmax, ymin, ymax; cmap = :viridis, min_v = minimum(v), max_v = maximum(v))
    f = Figure()
    ar = (maximum(msh.xv) - minimum(msh.xv)) / (maximum(msh.xv) - minimum(msh.yv))
    Axis(f[1, 1], aspect = ar)
    limits = min_v ≈ max_v ? (min_v, min_v + 1) : (min_v, max_v)
    p = [Polygon( Point2f0[ (msh.xv[msh.e2v[i,j]], msh.yv[msh.e2v[i,j]]) for j=1:msh.nf_el] ) for i in 1:msh.nel]
    poly!(p, color = v, colormap = cmap, strokewidth = 0, strokecolor = :black, markerstrokewidth = 0, markerstrokecolor = (0, 0, 0, 0), aspect_ratio=:image, colorrange=limits)
    Colorbar(f[1, 2], colormap = cmap, limits=limits, flipaxis = true, size = 25, height = Relative(2/3) )
    display(f)
    return nothing
end

# Generate data
nel  = 4
v    = ones(nel)
# v    = rand(nel)
xv   = [-1.  .0  1. -1. .0  1. -1. .0  1.]
yv   = [-1. -1. -1.  .0 .0  .0  1. 1.  1.]
e2v  = [1 2 5 4; 2 3 6 5; 4 5 8 7; 5 6 9 8]
msh = (xv=xv, yv=yv, e2v=e2v, nf_el=4, nel=nel )

# Call function
PatchPlotMakie(msh, v, minimum(xv), maximum(xv), minimum(yv), maximum(yv))

1 Like

Thanks, that’s a concise workaround :smiley: