Skip to content

Commit

Permalink
Merge pull request #2 from legend-exp/singlefits
Browse files Browse the repository at this point in the history
Add `residualplot!` and `lplot!` for histogram single fits
  • Loading branch information
fhagemann authored Feb 20, 2025
2 parents 34e0573 + 6a40fad commit 7ac3a15
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
MathTeXEngine = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53"
RadiationDetectorSignals = "bf2c0563-65cf-5db2-a620-ceb7de82658c"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[extensions]
LegendMakieExt = ["Makie", "Dates", "FileIO", "Format", "LaTeXStrings", "MathTeXEngine", "Unitful"]
LegendMakieExt = ["Makie", "Dates", "FileIO", "Format", "LaTeXStrings", "MathTeXEngine", "StatsBase", "Unitful"]
LegendMakieRadiationDetectorSignalsExt = "RadiationDetectorSignals"

[compat]
Expand All @@ -28,5 +29,6 @@ Makie = "0.22"
MakieCore = "0.9"
MathTeXEngine = "0.6.1"
RadiationDetectorSignals = "0.3.8"
StatsBase = "0.33.7, 0.34"
Unitful = "1.6"
julia = "1.10"
4 changes: 4 additions & 0 deletions ext/LegendMakieExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ module LegendMakieExt
import LaTeXStrings
import Makie
import MathTeXEngine
import StatsBase
import Unitful

import LegendMakie: pt
import Unitful: @u_str

include("recipes/recipes.jl")
include("recipes/lplot.jl")
include("recipes/watermarks.jl")

function __init__()
Expand Down
60 changes: 60 additions & 0 deletions ext/recipes/lplot.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# This file is a part of LegendMakie.jl, licensed under the MIT License (MIT).


function round_wo_units(x::Unitful.RealOrRealQuantity; digits::Int=2)
Unitful.unit(x) == Unitful.NoUnits ? round(x; digits) : round(Unitful.unit(x), x; digits)
end

function LegendMakie.lplot!(
report::NamedTuple{(:f_fit, :h, :μ, :σ, :gof)};
title::AbstractString = "", show_residuals::Bool = true,
xlabel = "", xticks = -4:2:4, xlims = (-5,5), ylims = (0,nothing),
legend_position = :lt, watermark::Bool = true, kwargs...
)

fig = Makie.current_figure()

g = Makie.GridLayout(fig[1,1])
ax = Makie.Axis(g[1,1],
title = title, titlefont = :bold, titlesize = 16pt, xlabel = xlabel,
xticks = xticks, limits = (xlims, ylims), ylabel = "Normalized Counts",
)

# Create histogram
Makie.plot!(ax, report.h, label = "Data")

_x = range(minimum(xlims), stop = maximum(xlims), length = 1000)
Makie.lines!(_x, report.f_fit.(_x), color = :red,
label = "Normal Fit\nμ = $(round_wo_units(report.μ, digits=2))\nσ = $(round_wo_units(report.σ, digits=2))")

Makie.axislegend(ax, position = legend_position)

if !isempty(report.gof) && show_residuals

ax.xticklabelsize = 0
ax.xticksize = 0
ax.xlabel = ""

ax2 = Makie.Axis(g[2,1], xticks = xticks, yticks = -3:3:3, limits = (xlims,(-5,5)), xlabel = xlabel, ylabel = "Residuals (σ)")
LegendMakie.residualplot!(ax2, (x = report.gof.bin_centers, residuals_norm = [ifelse(abs(r) < 1e-6, 0.0, r) for r in report.gof.residuals_norm]))

# link axis and put plots together
Makie.linkxaxes!(ax, ax2)
Makie.rowgap!(g, 0)
Makie.rowsize!(g, 1, Makie.Auto(3))

# align ylabels
yspace = maximum(Makie.tight_yticklabel_spacing!, (ax, ax2))
ax.yticklabelspace = yspace
ax2.yticklabelspace = yspace
end

all = Makie.Axis(g[:,:])
Makie.hidedecorations!(all)
Makie.hidespines!(all)
Makie.current_axis!(all)

watermark && LegendMakie.add_watermarks!(; kwargs...)

fig
end
21 changes: 21 additions & 0 deletions ext/recipes/recipes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This file is a part of LegendMakie.jl, licensed under the MIT License (MIT).

import LegendMakie: residualplot!

Makie.@recipe(ResidualPlot, report) do scene
Makie.Attributes(
color_1σ = :darkgrey,
color_3σ = :lightgrey,
color = :black
)
end

function Makie.plot!(p::ResidualPlot{<:Tuple{NamedTuple{(:x, :residuals_norm)}}})
report = p.report[]
xvalues = report.x
res = report.residuals_norm
Makie.hspan!(p, [-3], [3], color = p.color_3σ)
Makie.hspan!(p, [-1], [1], color = p.color_1σ)
Makie.scatter!(p, xvalues, res, color = p.color)
p
end
4 changes: 4 additions & 0 deletions src/lplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ function lplot end
function lplot! end
export lplot, lplot!


# recipes
function residualplot! end

# watermark functions
function add_logo! end
function add_legend_logo! end
Expand Down
2 changes: 2 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
LegendSpecFits = "18221496-77af-46cf-bab8-820da09f7f97"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
RadiationDetectorSignals = "bf2c0563-65cf-5db2-a620-ceb7de82658c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
Documenter = "1"
LegendSpecFits = "0.3"
Makie = "0.22"
11 changes: 10 additions & 1 deletion test/test_lplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using LegendMakie
using Makie

import LegendSpecFits

using Test

@testset "lplot" begin
Expand All @@ -17,7 +19,14 @@ using Test

# test alternative watermark
ax2 = Axis(fig[1,2])
hist!(ax2, randn(10000))
@test_nowarn LegendMakie.residualplot!(ax2, (x = 1:10, residuals_norm = randn(10)))
@test_nowarn LegendMakie.add_watermarks!(legend_logo = true, position = "outer top", preliminary = false)
end

@testset "Test LegendSpecFits reports" begin
@testset "Singlefits" begin
result, report = LegendSpecFits.fit_single_trunc_gauss(randn(10000), (low = -4.0, high = 4.0, max = NaN))
@test_nowarn lplot(report, xlabel = "x")
end
end
end

0 comments on commit 7ac3a15

Please sign in to comment.