snotskie / EpistemicNetworkAnalysis.jl

Native implementation of Epistemic Network Analysis written in the Julia programming language. Based on rENA 0.2.0.1.
https://snotskie.github.io/EpistemicNetworkAnalysis.jl/
GNU General Public License v3.0
6 stars 2 forks source link

ellipse confidence intervals #58

Closed snotskie closed 7 months ago

snotskie commented 7 months ago

as a visual counterpart to https://github.com/snotskie/EpistemicNetworkAnalysis.jl/issues/55, add a plot option to show ellipses instead of rectangles for confidence intervals

As a proof of concept...

With outliers:

image

Without outliers:

image

# Add ellipses
# h/t https://discourse.julialang.org/t/plot-ellipse-in-makie/82814/4
let
    for job in selected_jobs
        jobRows = map(jobp -> jobp == job, modelMeas.metadata.job_nameright)
        jobUnits = modelMeas.metadata.unitID[jobRows]
        xs = Vector{Float64}(modelMeas.points[x, jobUnits])
        ys = Vector{Float64}(modelMeas.points[y, jobUnits])
        q1x = quantile(xs, .25)
        q3x = quantile(xs, .75)
        iqrx = q3x - q1x
        inx = map(xs) do x
            if x < q1x - 1.5 * iqrx
                return false
            elseif x > q3x + 1.5 * iqrx
                return false
            else
                return true
            end
        end
        q1y = quantile(ys, .25)
        q3y = quantile(ys, .75)
        iqry = q3y - q1y
        iny = map(ys) do y
            if y < q1y - 1.5 * iqry
                return false
            elseif y > q3y + 1.5 * iqry
                return false
            else
                return true
            end
        end
        inxy = inx .& iny
        xs, ys = xs[inxy], ys[inxy]
        Σ = cov([xs ys])
        @show Σ
        vals = eigvals(Σ)
        vecs = eigvecs(Σ)
        if vals[1] <= vals[2]
            vals[1], vals[2] = vals[2], vals[1]
            vecs[:, 1], vecs[:, 2] = vecs[:, 2], vecs[:, 1]
        end
        θ = atan(vecs[2,1] / vecs[1,1])
        if θ < 0
            θ += 2π
        end
        cx = mean(xs)
        cy = mean(ys)
        t = range(0, 2π, length=100)
        for confidence in [0.5, 0.6, 0.7, 0.8, 0.9]
            quant = sqrt(quantile(Chisq(2), confidence))
            rx = quant * sqrt(vals[1])
            ry = quant * sqrt(vals[2])
            xe = rx .* cos.(t)
            ye = ry .* sin.(t)
            ellipse = [xe ye] * [cos(θ) sin(θ); -sin(θ) cos(θ)]
            pxs = cx .+ ellipse[:, 1]
            pys = cy .+ ellipse[:, 2]
            plot!(pMeas, pxs, pys, label="$(job) CI", alpha=1-confidence, color=:black)
        end
    end
end

display(pMeas)
snotskie commented 7 months ago

image

snotskie commented 7 months ago

staged in https://github.com/snotskie/EpistemicNetworkAnalysis.jl/commit/e73c91f259646b646b2e6bc24d238b1c357ec6ef