Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix colorbar corner cases (singleton) #3511

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/basic_recipes/contourf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ function Makie.plot!(c::Contourf{<:Tuple{<:AbstractVector{<:Real}, <:AbstractVec
_get_isoband_levels(Val(mode), levels, vec(zs))
end

colorrange = lift(c, c._computed_levels) do levels
minimum(levels), maximum(levels)
end
colorrange = lift(distinct_extrema_nan, c._computed_levels)

computed_colormap = lift(compute_contourf_colormap, c, c._computed_levels, c.colormap, c.extendlow,
c.extendhigh)
c.attributes[:_computed_colormap] = computed_colormap
Expand Down Expand Up @@ -171,7 +170,6 @@ function _group_polys(points, ids)
for p1 in polys_lastdouble, p2 in polys_lastdouble]

unclassified_polyindices = collect(1:size(containment_matrix, 1))
# @show unclassified_polyindices

# each group has first an outer polygon, and then its holes
# TODO: don't specifically type this 2f0?
Expand Down
11 changes: 7 additions & 4 deletions src/basic_recipes/tricontourf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,14 @@ function Makie.convert_arguments(::Type{<:Tricontourf}, x::AbstractVector{<:Real
end

function compute_contourf_colormap(levels, cmap, elow, ehigh)
levels_scaled = (levels .- minimum(levels)) ./ (maximum(levels) - minimum(levels))
n = length(levels_scaled)

_cmap = to_colormap(cmap)

lo, hi = extrema(levels)
lo == hi && return cgrad(_cmap, levels; categorical=true)

levels_scaled = (levels .- lo) ./ (hi - lo)
n = length(levels_scaled)

if elow === :auto && ehigh !== :auto
cm_base = cgrad(_cmap, n + 1; categorical=true)[2:end]
cm = cgrad(cm_base, levels_scaled; categorical=true)
Expand Down Expand Up @@ -122,7 +125,7 @@ function Makie.plot!(c::Tricontourf{<:Tuple{<:DelTri.Triangulation, <:AbstractVe
return _get_isoband_levels(Val(mode), levels, vec(zs))
end

colorrange = lift(extrema_nan, c, c._computed_levels)
colorrange = lift(distinct_extrema_nan, c, c._computed_levels)
computed_colormap = lift(compute_contourf_colormap, c, c._computed_levels, c.colormap, c.extendlow,
c.extendhigh)
c.attributes[:_computed_colormap] = computed_colormap
Expand Down
9 changes: 6 additions & 3 deletions src/colorsampler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,14 @@ function _colormapping(
end

colorrange = lift(color_tight, colorrange; ignore_equal_values=true) do color, crange
return crange isa Automatic ? Vec2{Float64}(distinct_extrema_nan(color)) : Vec2{Float64}(crange)
if !(auto = crange isa Automatic)
crange[1] == crange[2] && error("Cannot use a colorrange with a single value ($crange): provide distinct values instead.")
end
return auto ? Vec2{Float64}(distinct_extrema_nan(color)) : Vec2{Float64}(crange)
end

colorrange_scaled = lift(colorrange, colorscale; ignore_equal_values=true) do range, scale
return Vec2f(apply_scale(scale, range))
colorrange_scaled = lift(colorrange, colorscale; ignore_equal_values=true) do crange, cscale
return Vec2f(apply_scale(cscale, crange))
end

color_scaled = lift(color_tight, colorscale) do color, scale
Expand Down
12 changes: 11 additions & 1 deletion src/layouting/data_limits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,17 @@ end

function distinct_extrema_nan(x)
lo, hi = extrema_nan(x)
lo == hi ? (lo - 0.5f0, hi + 0.5f0) : (lo, hi)
δ⁻ = if lo == hi
iszero(lo) ? zero(lo) : one(lo)
else
zero(lo)
end
δ⁺ = if lo == hi
iszero(hi) ? one(hi) : zero(hi)
else
zero(hi)
end
(lo - δ⁻, hi + δ⁺)
end

function point_iterator(plot::Union{Scatter, MeshScatter, Lines, LineSegments})
Expand Down
4 changes: 2 additions & 2 deletions src/makielayout/blocks/colorbar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ end

function extract_colormap(plot::Union{Contourf,Tricontourf})
levels = plot._computed_levels
limits = lift(l -> (l[1], l[end]), levels)
colorrange = lift(distinct_extrema_nan, levels)
function extend_color(color, computed)
color === nothing && return automatic
color == :auto || color == automatic && return computed
return computed
end
elow = lift(extend_color, plot.extendlow, plot._computed_extendlow)
ehigh = lift(extend_color, plot.extendhigh, plot._computed_extendhigh)
return ColorMapping(levels[], levels, plot._computed_colormap, limits, plot.colorscale, Observable(1.0),
return ColorMapping(levels[], levels, plot._computed_colormap, colorrange, plot.colorscale, Observable(1.0),
elow, ehigh, plot.nan_color)
end

Expand Down
5 changes: 2 additions & 3 deletions src/makielayout/ticklocators/wilkinson.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function WilkinsonTicks(k_ideal::Int; k_min = 2, k_max = 10,
min_px_dist = 50.0)

if !(0 < k_min <= k_ideal <= k_max)
error("Invalid tick number specifications k_ideal $k_ideal, k_min $k_min, k_max $k_max")
error("Invalid tick number specifications k_ideal=$k_ideal, k_min=$k_min, k_max=$k_max")
end

WilkinsonTicks(k_ideal, k_min, k_max, Q, granularity_weight, simplicity_weight,
Expand All @@ -17,9 +17,8 @@ end
get_tickvalues(ticks::WilkinsonTicks, vmin, vmax) = get_tickvalues(ticks, Float64(vmin), Float64(vmax))

function get_tickvalues(ticks::WilkinsonTicks, vmin::Float64, vmax::Float64)

tickvalues, _ = PlotUtils.optimize_ticks(Float64(vmin), Float64(vmax);
extend_ticks = false, strict_span=true, span_buffer = nothing,
extend_ticks = false, span_buffer = nothing, strict_span = vmin ≉ vmax,
k_min = ticks.k_min,
k_max = ticks.k_max,
k_ideal = ticks.k_ideal,
Expand Down
47 changes: 40 additions & 7 deletions test/makielayout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ end
@test isempty(ax.scene.plots)
end

@testset "zero heatmap" begin
@testset "Colorbar: zero heatmap" begin
xs = LinRange(0, 20, 10)
ys = LinRange(0, 15, 10)
zs = zeros(length(xs), length(ys))
Expand All @@ -42,15 +42,48 @@ end
_, hm = heatmap(fig[1, 1], xs, ys, zs)
cb = Colorbar(fig[1, 2], hm)

@test hm.calculated_colors[].colorrange[] == Vec(-0.5, 0.5)
@test cb.limits[] == Vec(-.5, .5)

let (lo, hi) = hm.calculated_colors[].colorrange[]
@test lo ≉ hi
end
let (lo, hi) = cb.limits[]
@test lo ≉ hi
end
hm.colorrange = Float32.((-1, 1))
@test cb.limits[] == Vec(-1, 1)
end

# TODO: This doesn't work anymore because colorbar doesn't use the same observable
# cb.limits[] = Float32.((-2, 2))
# @test hm.attributes[:colorrange][] == (-2, 2)
@testset "Colorbar: invalid limits" begin
fig = Figure()
Axis(fig[1, 1])
@test_throws ErrorException Colorbar(fig[1, 2], limits = (1, 1))
end

@testset "Colorbar: zero contourf" begin
x = [0, 1]
y = [0, 2]
z = zeros(2, 2)

fig = Figure()
_, ct = contourf(fig[1, 1], x, y, z)
cb = Colorbar(fig[1, 2], ct)

let (lo, hi) = cb.limits[]
@test lo ≉ hi
end
end

@testset "Colorbar: zero tricontourf" begin
x = randn(10)
y = randn(10)
z = @. -sqrt(x^2 + y^2) + 0.1 * randn()

fig = Figure()
_, ct = tricontourf(fig[1, 1], x, y, z)
cb = Colorbar(fig[1, 2], ct)

let (lo, hi) = cb.limits[]
@test lo ≉ hi
end
end

@testset "Axis limits basics" begin
Expand Down
Loading