diff --git a/CHANGELOG.md b/CHANGELOG.md index 00f6cf05745..91b777dc523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] - Refactored rendering in GLMakie to go through a series of steps abstracted by a render pipeline. This allows rendering to be adjusted from outside and should simplify introducing more post-processing options in the future. [#4689](https://github.com/MakieOrg/Makie.jl/pull/4689) +- Fixed indexing error edge case in violin median code [#4682](https://github.com/MakieOrg/Makie.jl/pull/4682) ## [0.22.0] - 2024-12-12 diff --git a/src/stats/violin.jl b/src/stats/violin.jl index 78506efef94..ca47a36108e 100644 --- a/src/stats/violin.jl +++ b/src/stats/violin.jl @@ -134,9 +134,9 @@ function plot!(plot::Violin) if show_median # interpolate median bounds between corresponding points xm = spec.median - ip = findfirst(>(xm), spec.kde.x) - ym₋, ym₊ = spec.kde.density[ip-1], spec.kde.density[ip] - xm₋, xm₊ = spec.kde.x[ip-1], spec.kde.x[ip] + ip = Base.max(2, something(findfirst(>(xm), spec.kde.x), length(spec.kde.x))) + ym₋, ym₊ = spec.kde.density[Base.max(1, ip-1)], spec.kde.density[ip] + xm₋, xm₊ = spec.kde.x[Base.max(1, ip-1)], spec.kde.x[ip] ym = (xm * (ym₊ - ym₋) + xm₊ * ym₋ - xm₋ * ym₊) / (xm₊ - xm₋) median_left = point_func(spec.side == 1 ? spec.x : spec.x - ym * scale, xm) median_right = point_func(spec.side == -1 ? spec.x : spec.x + ym * scale, xm) diff --git a/test/statistical_tests.jl b/test/statistical_tests.jl index 9e7e15f5ed4..b1f6c0ac71b 100644 --- a/test/statistical_tests.jl +++ b/test/statistical_tests.jl @@ -294,4 +294,10 @@ end @test p2.plots[2] isa LineSegments @test p2.plots[2][:color][] === :white @test p2.plots[2][:visible][] === :false + + # median edge case #4675 + @test violin(fill(1, 1000), push!(fill(0, 999), 1), show_median=true, datalimits=(-0.001,Inf)) !== nothing + # And some others + @test violin(fill(1, 1000),fill(0, 1000), show_median=true) !== nothing + @test violin([1], [1], show_median=true) !== nothing end