Skip to content

Commit de66afc

Browse files
authored
[change] default (h)boxplot width to ratio (#175)
1 parent 7bb93f6 commit de66afc

File tree

8 files changed

+132
-54
lines changed

8 files changed

+132
-54
lines changed

src/plot/boxplot.typ

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#import "../style/styling.typ": mark, prepare-mark
55
#import "../logic/time.typ"
66
#import "../math.typ": minmax
7+
#import "../process-styles.typ": process-plot-item-width
78

89

910
#let render-boxplot(plot, transform) = {
@@ -196,10 +197,9 @@
196197
/// -> int | float
197198
whisker-pos: 1.5,
198199

199-
/// The width of the boxplots in $x$ data coordinates. This can be a constant width
200-
/// applied to all boxplots or an array of widths matching the number of data sets.
201-
/// -> int | float | array
202-
width: 0.5,
200+
/// The width of the boxplots in $x$ data coordinates. See @bar.width.
201+
/// -> ratio | int | float | duration | array
202+
width: 50%,
203203

204204
/// How to fill the boxes.
205205
/// -> none | color | gradient | tiling
@@ -272,8 +272,11 @@
272272
data = data.pos()
273273
let num-boxplots = data.len()
274274

275-
if type(x) in (int, float, datetime) { x = (x,) }
276-
else if x == auto { x = range(1, num-boxplots + 1) }
275+
if x == auto {
276+
x = range(1, num-boxplots + 1)
277+
} else if type(x) != array {
278+
x = (x,)
279+
}
277280

278281
let datetime-axes = (:)
279282
if type(x.at(0, default: 0)) == datetime {
@@ -285,8 +288,10 @@
285288
x.len() == num-boxplots,
286289
message: "The number of x coordinates does not match the number of data arrays"
287290
)
291+
292+
293+
width = process-plot-item-width(width, x)
288294

289-
if type(width) in (int, float) { width = (width,) * num-boxplots }
290295
assert(
291296
width.len() == num-boxplots,
292297
message: "The number of widths does not match the number of data arrays"

src/plot/hboxplot.typ

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#import "../style/styling.typ": mark, prepare-mark
55
#import "../logic/time.typ"
66
#import "../math.typ": minmax
7+
#import "../process-styles.typ": process-plot-item-width
78

89

910
#let render-boxplot(plot, transform) = {
@@ -154,10 +155,9 @@
154155
/// -> int | float
155156
whisker-pos: 1.5,
156157

157-
/// The width of the boxplots in $y$ data coordinates. This can be a constant width
158-
/// applied to all boxplots or an array of widths matching the number of data sets.
159-
/// -> int | float | array
160-
width: 0.5,
158+
/// The width of the boxplots in $y$ data coordinates. See @bar.width.
159+
/// -> ratio | int | float | duration | array
160+
width: 50%,
161161

162162
/// How to fill the boxes.
163163
/// -> none | color | gradient | tiling
@@ -224,8 +224,11 @@
224224
data = data.pos()
225225
let num-boxplots = data.len()
226226

227-
if type(y) in (int, float) { y = (y,) }
228-
else if y == auto { y = range(1, num-boxplots + 1) }
227+
if y == auto {
228+
y = range(1, num-boxplots + 1)
229+
} else if type(y) != array {
230+
y = (y,)
231+
}
229232

230233
let datetime-axes = (:)
231234
if type(y.at(0, default: 0)) == datetime {
@@ -237,7 +240,7 @@
237240
message: "The number of y coordinates does not match the number of data arrays"
238241
)
239242

240-
if type(width) in (int, float) { width = (width,) * num-boxplots }
243+
width = process-plot-item-width(width, y)
241244
assert(
242245
width.len() == num-boxplots,
243246
message: "The number of widths does not match the number of data arrays"

src/plot/hviolin.typ

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@
149149
data = data.pos()
150150
let num-violins = data.len()
151151

152-
if type(y) in (int, float, datetime) { y = (y,) } else if y == auto {
152+
if y == auto {
153153
y = range(1, num-violins + 1)
154+
} else if type(y) != array {
155+
y = (y,)
154156
}
155157

156158
let datetime-axes = (:)

src/plot/violin.typ

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,10 @@
495495
data = data.pos()
496496
let num-violins = data.len()
497497

498-
if type(x) in (int, float, datetime) { x = (x,) } else if x == auto {
498+
if x == auto {
499499
x = range(1, num-violins + 1)
500+
} else if type(x) != array {
501+
x = (x,)
500502
}
501503

502504
let datetime-axes = (:)

tests/plot/boxplot/ref/7.png

536 Bytes
Loading

tests/plot/boxplot/test.typ

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,21 @@
2626
range(4),
2727
(
2828
median: 2.5,
29-
q1: 1,
30-
q3: 3,
31-
whisker-low: 0,
32-
whisker-high: 10,
29+
q1: 1,
30+
q3: 3,
31+
whisker-low: 0,
32+
whisker-high: 10,
3333
),
3434
(
3535
median: 7,
36-
q1: 3,
37-
q3: 8,
38-
whisker-low: 2,
39-
whisker-high: 10,
40-
outliers: (0, 1)
36+
q1: 3,
37+
q3: 8,
38+
whisker-low: 2,
39+
whisker-high: 10,
40+
outliers: (0, 1),
4141
),
42-
x: (1, 2, 4)
43-
)
42+
x: (1, 2, 4),
43+
),
4444
)
4545

4646

@@ -64,8 +64,8 @@
6464
outliers: "s",
6565
outlier-size: 2pt,
6666
outlier-fill: green,
67-
outlier-stroke: .5pt + black
68-
)
67+
outlier-stroke: .5pt + black,
68+
),
6969
)
7070

7171

@@ -78,13 +78,13 @@
7878
#lq.diagram(
7979
lq.boxplot(
8080
(1, 2, 3, 7, 8),
81-
mean: "x"
81+
mean: "x",
8282
),
8383
lq.boxplot(
8484
(1, 2, 3, 7, 8),
8585
mean: green + 1pt,
86-
x: 2
87-
)
86+
x: 2,
87+
),
8888
)
8989

9090

@@ -96,9 +96,9 @@
9696

9797
#lq.diagram(
9898
lq.boxplot(
99-
(1, 3, 4, 5, 6, 3, 1, 72, 3, 7, 8, 10,11, 34),
99+
(1, 3, 4, 5, 6, 3, 1, 72, 3, 7, 8, 10, 11, 34),
100100
whisker-pos: 6,
101-
)
101+
),
102102
)
103103

104104

@@ -116,4 +116,37 @@
116116
(0, 4, 5, 6),
117117
(-1, 0, 9, 10),
118118
),
119-
)
119+
)
120+
121+
#pagebreak()
122+
123+
124+
// Datetime x and ratio/duration width
125+
#lq.diagram(
126+
lq.boxplot(
127+
(1, 2),
128+
(1, 2),
129+
x: (
130+
datetime(year: 2025, month: 2, day: 1),
131+
datetime(year: 2025, month: 3, day: 1),
132+
),
133+
width: 80%,
134+
),
135+
lq.boxplot(
136+
(1, 2),
137+
x: datetime(year: 2025, month: 4, day: 1),
138+
width: duration(weeks: 4),
139+
),
140+
lq.boxplot(
141+
(1, 2),
142+
(1, 2),
143+
x: (
144+
datetime(year: 2025, month: 5, day: 1),
145+
datetime(year: 2025, month: 6, day: 1),
146+
),
147+
width: (
148+
duration(weeks: 2),
149+
duration(weeks: 1),
150+
),
151+
),
152+
)

tests/plot/hboxplot/ref/7.png

492 Bytes
Loading

tests/plot/hboxplot/test.typ

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,21 @@
2626
range(4),
2727
(
2828
median: 2.5,
29-
q1: 1,
30-
q3: 3,
31-
whisker-low: 0,
32-
whisker-high: 10,
29+
q1: 1,
30+
q3: 3,
31+
whisker-low: 0,
32+
whisker-high: 10,
3333
),
3434
(
3535
median: 7,
36-
q1: 3,
37-
q3: 8,
38-
whisker-low: 2,
39-
whisker-high: 10,
40-
outliers: (0, 1)
36+
q1: 3,
37+
q3: 8,
38+
whisker-low: 2,
39+
whisker-high: 10,
40+
outliers: (0, 1),
4141
),
42-
y: (1, 2, 4)
43-
)
42+
y: (1, 2, 4),
43+
),
4444
)
4545

4646

@@ -64,8 +64,8 @@
6464
outliers: "s",
6565
outlier-size: 2pt,
6666
outlier-fill: green,
67-
outlier-stroke: .5pt + black
68-
)
67+
outlier-stroke: .5pt + black,
68+
),
6969
)
7070

7171

@@ -78,13 +78,13 @@
7878
#lq.diagram(
7979
lq.hboxplot(
8080
(1, 2, 3, 7, 8),
81-
mean: "x"
81+
mean: "x",
8282
),
8383
lq.hboxplot(
8484
(1, 2, 3, 7, 8),
8585
mean: green + 1pt,
86-
y: 2
87-
)
86+
y: 2,
87+
),
8888
)
8989

9090

@@ -96,9 +96,9 @@
9696

9797
#lq.diagram(
9898
lq.hboxplot(
99-
(1, 3, 4, 5, 6, 3, 1, 72, 3, 7, 8, 10,11, 34),
99+
(1, 3, 4, 5, 6, 3, 1, 72, 3, 7, 8, 10, 11, 34),
100100
whisker-pos: 6,
101-
)
101+
),
102102
)
103103

104104
#pagebreak()
@@ -114,4 +114,37 @@
114114
(0, 4, 5, 6),
115115
(-1, 0, 9, 10),
116116
),
117-
)
117+
)
118+
119+
#pagebreak()
120+
121+
122+
// Datetime x and ratio/duration width
123+
#lq.diagram(
124+
lq.hboxplot(
125+
(1, 2),
126+
(1, 2),
127+
y: (
128+
datetime(year: 2025, month: 2, day: 1),
129+
datetime(year: 2025, month: 3, day: 1),
130+
),
131+
width: 80%,
132+
),
133+
lq.hboxplot(
134+
(1, 2),
135+
y: datetime(year: 2025, month: 4, day: 1),
136+
width: duration(weeks: 4),
137+
),
138+
lq.hboxplot(
139+
(1, 2),
140+
(1, 2),
141+
y: (
142+
datetime(year: 2025, month: 5, day: 1),
143+
datetime(year: 2025, month: 6, day: 1),
144+
),
145+
width: (
146+
duration(weeks: 2),
147+
duration(weeks: 1),
148+
),
149+
),
150+
)

0 commit comments

Comments
 (0)