Skip to main content
added 2 characters in body
Source Link
kglr
  • 400.5k
  • 18
  • 488
  • 929

Update: It turns out that this approach has an advantage over the others posted in that it can handle different settings for BarOrigin without modification.

BoxWhiskerChart[preP2[data2, durations2], 
     ChartLabels -> (Style[#, 20] & /@ {"A", "B", "C", "D"}), 
     ChartStyle -> 63, BarSpacing -> 0, ImageSize -> 400, 
     Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
     ChartElementFunction -> ceF2["GlassBoxWhisker"], 
     BarOrigin -> #] & /@ {Bottom, Top, Left, Right} // Partition[#, 2] & // Grid

enter image description here


Original answer:

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

Update: It turns out that this approach has an advantage over the others posted in that it can handle different settings for BarOrigin without modification.

BoxWhiskerChart[preP2[data2, durations2], 
     ChartLabels -> (Style[#, 20] & /@ {"A", "B", "C", "D"}), 
     ChartStyle -> 63, BarSpacing -> 0, ImageSize -> 400, 
     Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
     ChartElementFunction -> ceF2["GlassBoxWhisker"], 
     BarOrigin -> #] & /@ {Bottom, Top, Left, Right} // Partition[#, 2] & // Grid

enter image description here


Original answer:

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

added 2 characters in body
Source Link
kglr
  • 400.5k
  • 18
  • 488
  • 929

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

Is it possible to apply a list of durations to BoxWidth somehow?

That is, can we somehow use "BoxWidth" to reflect durations rather than sample sizes.

A simple trick to achieve this is to use a fake data set with (1) sample sizes that depend on durations so that using the "BoxWidth" -> "Scaled" does give the desired bar widths, (2) actual data used as metadata so that its quantiles can be used inside the ChartElementFunction to set the correct "BoxRange" and produce the correct primitives. We also set (i) BarSpacing -> 0 to avoid more complicated sample size calculations, (ii) "EqualSpacing" -> False to avoid complications with tick/ label positions.

ClearAll[ceF2, preP2]
ceF2 [f_: "BoxWhisker"] := (Module[{br = Quantile[#3[[1, 1]], {0., .25, .5, .75, 1.}]}, 
 Charting`ChartStyleInformation["BoxRange"] = br; 
 ChartElementDataFunction[f][{#[[1]] + #3[[1, 2]] - Mean[#[[1]]], #[[2]]}, ##2]] &)

preP2 = ConstantArray[1, #2^2] -> {#, #3} & @@@ Transpose[{#, 5 Normalize[#2, GCD @@ # &],
 Range[Length@#] - .5}] &;

Examples:

data = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations = {180, 60};

BoxWhiskerChart[preP2[data, durations], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF["GlassBoxWhisker"]]ceF2["GlassBoxWhisker"]]

enter image description here

data2 = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3}, {4, 2, 3, 2, 8},   
 {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations2 = {180, 60, 120, 90};
BoxWhiskerChart[preP2[data2, durations2], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B", "C", "D"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF["GlassBoxWhisker"]]ceF2["GlassBoxWhisker"]]

enter image description here

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

Is it possible to apply a list of durations to BoxWidth somehow?

That is, can we somehow use "BoxWidth" to reflect durations rather than sample sizes.

A simple trick to achieve this is to use a fake data set with (1) sample sizes that depend on durations so that using the "BoxWidth" -> "Scaled" does give the desired bar widths, (2) actual data used as metadata so that its quantiles can be used inside the ChartElementFunction to set the correct "BoxRange" and produce the correct primitives. We also set (i) BarSpacing -> 0 to avoid more complicated sample size calculations, (ii) "EqualSpacing" -> False to avoid complications with tick/ label positions.

ClearAll[ceF2, preP2]
ceF2 [f_: "BoxWhisker"] := (Module[{br = Quantile[#3[[1, 1]], {0., .25, .5, .75, 1.}]}, 
 Charting`ChartStyleInformation["BoxRange"] = br; 
 ChartElementDataFunction[f][{#[[1]] + #3[[1, 2]] - Mean[#[[1]]], #[[2]]}, ##2]] &)

preP2 = ConstantArray[1, #2^2] -> {#, #3} & @@@ Transpose[{#, 5 Normalize[#2, GCD @@ # &],
 Range[Length@#] - .5}] &;

Examples:

data = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations = {180, 60};

BoxWhiskerChart[preP2[data, durations], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF["GlassBoxWhisker"]]

enter image description here

data2 = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3}, {4, 2, 3, 2, 8},   
 {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations2 = {180, 60, 120, 90};
BoxWhiskerChart[preP2[data2, durations2], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B", "C", "D"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF["GlassBoxWhisker"]]

enter image description here

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

Is it possible to apply a list of durations to BoxWidth somehow?

That is, can we somehow use "BoxWidth" to reflect durations rather than sample sizes.

A simple trick to achieve this is to use a fake data set with (1) sample sizes that depend on durations so that using the "BoxWidth" -> "Scaled" does give the desired bar widths, (2) actual data used as metadata so that its quantiles can be used inside the ChartElementFunction to set the correct "BoxRange" and produce the correct primitives. We also set (i) BarSpacing -> 0 to avoid more complicated sample size calculations, (ii) "EqualSpacing" -> False to avoid complications with tick/ label positions.

ClearAll[ceF2, preP2]
ceF2 [f_: "BoxWhisker"] := (Module[{br = Quantile[#3[[1, 1]], {0., .25, .5, .75, 1.}]}, 
 Charting`ChartStyleInformation["BoxRange"] = br; 
 ChartElementDataFunction[f][{#[[1]] + #3[[1, 2]] - Mean[#[[1]]], #[[2]]}, ##2]] &)

preP2 = ConstantArray[1, #2^2] -> {#, #3} & @@@ Transpose[{#, 5 Normalize[#2, GCD @@ # &],
 Range[Length@#] - .5}] &;

Examples:

data = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations = {180, 60};

BoxWhiskerChart[preP2[data, durations], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF2["GlassBoxWhisker"]]

enter image description here

data2 = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3}, {4, 2, 3, 2, 8},   
 {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations2 = {180, 60, 120, 90};
BoxWhiskerChart[preP2[data2, durations2], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B", "C", "D"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF2["GlassBoxWhisker"]]

enter image description here

Source Link
kglr
  • 400.5k
  • 18
  • 488
  • 929

For practical purposes this question is solved by the two answers above. This answer, out of curiosity, takes up the puzzle

Is it possible to apply a list of durations to BoxWidth somehow?

That is, can we somehow use "BoxWidth" to reflect durations rather than sample sizes.

A simple trick to achieve this is to use a fake data set with (1) sample sizes that depend on durations so that using the "BoxWidth" -> "Scaled" does give the desired bar widths, (2) actual data used as metadata so that its quantiles can be used inside the ChartElementFunction to set the correct "BoxRange" and produce the correct primitives. We also set (i) BarSpacing -> 0 to avoid more complicated sample size calculations, (ii) "EqualSpacing" -> False to avoid complications with tick/ label positions.

ClearAll[ceF2, preP2]
ceF2 [f_: "BoxWhisker"] := (Module[{br = Quantile[#3[[1, 1]], {0., .25, .5, .75, 1.}]}, 
 Charting`ChartStyleInformation["BoxRange"] = br; 
 ChartElementDataFunction[f][{#[[1]] + #3[[1, 2]] - Mean[#[[1]]], #[[2]]}, ##2]] &)

preP2 = ConstantArray[1, #2^2] -> {#, #3} & @@@ Transpose[{#, 5 Normalize[#2, GCD @@ # &],
 Range[Length@#] - .5}] &;

Examples:

data = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations = {180, 60};

BoxWhiskerChart[preP2[data, durations], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF["GlassBoxWhisker"]]

enter image description here

data2 = {{1, 4, 3, 5, 1, 2}, {1, 5, 4, 3, 3}, {4, 2, 3, 2, 8},   
 {1, 5, 4, 3, 3, 4, 4, 2, 3, 2, 8}};
durations2 = {180, 60, 120, 90};
BoxWhiskerChart[preP2[data2, durations2], 
 ChartLabels -> (Style[#, 20] & /@ {"A", "B", "C", "D"}), ChartStyle -> 63, 
 BarSpacing -> 0, Method -> {"BoxWidth" -> "Scaled", "EqualSpacing" -> False}, 
 ChartElementFunction -> ceF["GlassBoxWhisker"]]

enter image description here