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

WIP: Lean box plot option #413

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
122 changes: 84 additions & 38 deletions src/boxplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
notch = false,
range = 1.5,
outliers = true,
whisker_width = :match,
whisker_width = :half,
mode = :box
)
# if only y is provided, then x will be UnitRange 1:size(y,2)
if typeof(x) <: AbstractRange
Expand All @@ -28,9 +29,11 @@ notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
warning = false
outliers_x, outliers_y = zeros(0), zeros(0)
bw = plotattributes[:bar_width]
bw == nothing && (bw = 0.8)
@assert whisker_width == :match || whisker_width >= 0 "whisker_width must be :match or a positive number"
ww = whisker_width == :match ? bw : whisker_width
isnothing(bw) && (bw = 0.8)
@assert whisker_width == :match || whisker_width == :half || whisker_width >= 0 "whisker_width must be :match, :half, or a positive number"
ww = whisker_width == :match ? bw :
whisker_width == :half ? bw / 2 :
whisker_width
for (i, glabel) in enumerate(glabels)
# filter y
values = y[filter(i -> _cycle(x, i) == glabel, 1:length(y))]
Expand Down Expand Up @@ -77,74 +80,117 @@ notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
q1, q5 = (min(q1, q2), max(q4, q5)) # whiskers cannot be inside the box
end
# Box
push!(xsegs, m, lw, rw, m, m) # lower T
push!(ysegs, q1, q1, q1, q1, q2) # lower T
push!(
texts,
"Lower fence: $q1",
"Lower fence: $q1",
"Lower fence: $q1",
"Lower fence: $q1",
"Q1: $q2",
"",
)
if mode == :lean
push!(xsegs, m, m)
push!(ysegs, q1, q2)
push!(
texts,
"Lower fence: $q1",
"Q1: $q2",
"",
)
else
push!(xsegs, m, lw, rw, m, m) # lower T
push!(ysegs, q1, q1, q1, q1, q2) # lower T
push!(
texts,
"Lower fence: $q1",
"Lower fence: $q1",
"Lower fence: $q1",
"Lower fence: $q1",
"Q1: $q2",
"",
)
end
if notch
push!(xsegs, l, l, L, m, R, r, r, l) # lower box
push!(xsegs, l, l, L, R, r, r, l) # upper box
push!(xsegs, r, r, R, L, l, l, r, r) # lower box
push!(xsegs, r, r, l, l, L, R, r, r) # upper box

push!(ysegs, q2, q3 - n, q3, q3, q3, q3 - n, q2, q2) # lower box
push!(ysegs, q2, q3 - n, q3, q3, q3 - n, q2, q2, q3 - n) # lower box
push!(
texts,
"Q1: $q2",
"Median: $q3 ± $n",
"",
"Median: $q3 ± $n",
"Median: $q3 ± $n",
"Median: $q3 ± $n",
"Q1: $q2",
"Q1: $q2",
"Median: $q3 ± $n",
"",
)
push!(ysegs, q4, q3 + n, q3, q3, q3 + n, q4, q4) # upper box

push!(ysegs, q3 + n, q4, q4, q3 + n, q3, q3, q3 + n, q4) # upper box
push!(
texts,
"Median: $q3 ± $n",
"Q3: $q4",
"Q3: $q4",
"Median: $q3 ± $n",
"Median: $q3 ± $n",
"",
"Median: $q3 ± $n",
"Median: $q3 ± $n",
"Q3: $q4",
"",
)
elseif mode == :lean
push!(xsegs, m, lw, rw, m, m, l, r, m, m, lw, rw, m) # median line and quartile whiskers
push!(ysegs, q2, q2, q2, q2, q3, q3, q3, q3, q4, q4, q4, q4) # median line and quartile whiskers
push!(
texts,
"Q1: $q2",
"Q1: $q2",
"Q1: $q2",
"Q1: $q2",
"Median: $q3",
"Median: $q3",
"Median: $q3",
"Median: $q3",
"Q3: $q4",
"Q3: $q4",
"Q3: $q4",
"Q3: $q4",
"",
)
else
push!(xsegs, l, l, m, r, r, l) # lower box
push!(xsegs, l, l, r, r, l) # upper box
push!(ysegs, q2, q3, q3, q3, q2, q2) # lower box
push!(xsegs, r, r, l, l, r, r) # lower box
push!(xsegs, r, l, l, r, r, m) # upper box
push!(ysegs, q2, q3, q3, q2, q2, q3) # lower box
push!(
texts,
"Q1: $q2",
"Median: $q3",
"Median: $q3",
"Median: $q3",
"Q1: $q2",
"Q1: $q2",
"Median: $q3",
"",
)
push!(ysegs, q4, q4, q3, q3, q4, q4) # upper box
push!(texts, "Q3: $q4", "Q3: $q4", "Median: $q3", "Median: $q3", "Q3: $q4", "Q3: $q4", "")
end
if mode == :lean
push!(xsegs, m, m)
push!(ysegs, q5, q4)
push!(
texts,
"Upper fence: $q5",
"Q3: $q4",
"",
)
else
push!(xsegs, m, lw, rw, m, m) # upper T
push!(ysegs, q5, q5, q5, q5, q4) # upper T
push!(
texts,
"Upper fence: $q5",
"Upper fence: $q5",
"Upper fence: $q5",
"Upper fence: $q5",
"Q3: $q4",
"",
)
push!(ysegs, q4, q3, q3, q4, q4) # upper box
push!(texts, "Q3: $q4", "Median: $q3", "Median: $q3", "Q3: $q4", "Q3: $q4", "")
end
push!(xsegs, m, lw, rw, m, m) # upper T
push!(ysegs, q5, q5, q5, q5, q4) # upper T
push!(
texts,
"Upper fence: $q5",
"Upper fence: $q5",
"Upper fence: $q5",
"Upper fence: $q5",
"Q3: $q4",
"",
)

end

Expand Down