Search code examples
juliaboxplotscalingstatsplots

StatsPlots Boxplot decrease width of boxes


I have a boxplot in Julia, that I created using StatsPlots boxplot:

boxes = -0.002:0.0001:0.0012
boxed = [[sum([1 for tuple ∈ data if tuple.y > box-0.000125 && tuple.y ≤ box+0.000125]) for box ∈ boxes] for data in datas]
boxplot(repeat([box for box ∈ boxes], outer=size(boxed)[1]), [(boxed...)...]; outliers=false)

The current result looks like this: bad boxplot which is obviously hideous. I need to reduce the width of the boxes to a ~20000th of what it currently is. I can achieve this by scaling the x axis accordingly:

boxplot(repeat([box*20000 for box ∈ boxes], outer=size(boxed)[1]), [(boxed...)...]; outliers=false)

better boxplot but then the x-axis has wrong values.

The help of the boxplot command sadly doesn't specify such an option:

help?> boxplot
search: boxplot boxplot! groupedboxplot groupedboxplot!

  boxplot(x, y)
  boxplot!(x, y)

  Make a box and whisker plot.

  Keyword arguments
  ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

    •  notch: Bool. Notch the box plot? (false)

    •  range: Real. Values more than range*IQR below the first quartile or above the third quartile are shown as outliers (1.5)

    •  outliers: Bool. Show outliers? (true)

    •  whisker_width: Real or Symbol. Length of whiskers (:match)

  Example
  ≡≡≡≡≡≡≡≡≡

  julia> using StatsPlots
  julia> boxplot(repeat([1,2,3],outer=100),randn(300))

and I've already tried reasonable options like boxwex, width or box_width, which all didn't help. The documentation sadly also is of no help at all.

How can I change the width of the boxes without changing the scale of the x axis?


If, for some reason, you're interested, here's the content of the boxed array:

[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 26, 80, 170, 322, 486, 688, 817, 888, 849, 783, 732, 624, 500, 349, 232, 130, 49], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 28, 83, 181, 318, 491, 670, 761, 849, 843, 862, 799, 646, 481, 361, 225, 98, 50], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 28, 80, 179, 322, 493, 660, 753, 803, 832, 823, 783, 657, 541, 367, 223, 121, 62], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 23, 84, 171, 312, 463, 640, 778, 834, 820, 763, 752, 655, 518, 374, 244, 133, 52], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 21, 70, 169, 342, 527, 725, 808, 861, 857, 799, 688, 622, 523, 369, 232, 115, 41], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9, 28, 76, 150, 301, 492, 660, 760, 823, 862, 790, 749, 646, 525, 352, 223, 116, 54], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 21, 64, 165, 290, 434, 585, 771, 852, 847, 785, 739, 630, 535, 354, 230, 114, 42], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 19, 76, 190, 337, 506, 680, 775, 851, 853, 816, 705, 588, 496, 388, 232, 127, 54]]

With that, the plot can be replicated as follows:

using StatsPlots
boxes = -0.002:0.0001:0.0012
boxed = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 26, 80, 170, 322, 486, 688, 817, 888, 849, 783, 732, 624, 500, 349, 232, 130, 49], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 28, 83, 181, 318, 491, 670, 761, 849, 843, 862, 799, 646, 481, 361, 225, 98, 50], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 28, 80, 179, 322, 493, 660, 753, 803, 832, 823, 783, 657, 541, 367, 223, 121, 62], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 23, 84, 171, 312, 463, 640, 778, 834, 820, 763, 752, 655, 518, 374, 244, 133, 52], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 21, 70, 169, 342, 527, 725, 808, 861, 857, 799, 688, 622, 523, 369, 232, 115, 41], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9, 28, 76, 150, 301, 492, 660, 760, 823, 862, 790, 749, 646, 525, 352, 223, 116, 54], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 21, 64, 165, 290, 434, 585, 771, 852, 847, 785, 739, 630, 535, 354, 230, 114, 42], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 19, 76, 190, 337, 506, 680, 775, 851, 853, 816, 705, 588, 496, 388, 232, 127, 54]]
boxplot(repeat([box for box ∈ boxes], outer=size(boxed)[1]), [(boxed...)...]; outliers=false)

Solution

  • You can change the xticks:

    boxed = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 7, 26, 80, 170, 322, 486, 688, 817, 888, 849, 783, 732, 624, 500, 349, 232, 130, 49], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 28, 83, 181, 318, 491, 670, 761, 849, 843, 862, 799, 646, 481, 361, 225, 98, 50], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 28, 80, 179, 322, 493, 660, 753, 803, 832, 823, 783, 657, 541, 367, 223, 121, 62], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 23, 84, 171, 312, 463, 640, 778, 834, 820, 763, 752, 655, 518, 374, 244, 133, 52], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 21, 70, 169, 342, 527, 725, 808, 861, 857, 799, 688, 622, 523, 369, 232, 115, 41], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9, 28, 76, 150, 301, 492, 660, 760, 823, 862, 790, 749, 646, 525, 352, 223, 116, 54], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 21, 64, 165, 290, 434, 585, 771, 852, 847, 785, 739, 630, 535, 354, 230, 114, 42], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 19, 76, 190, 337, 506, 680, 775, 851, 853, 816, 705, 588, 496, 388, 232, 127, 54]]
    
    boxes = -0.002:0.0001:0.0012
    
    xx = repeat(boxes, outer = length(boxed))
    yy = collect(Iterators.flatten(boxed))
    
    using StatsPlots
    
    xtick = collect(-0.002:0.0005:0.0012)
    
    boxplot(xx * 20000, yy, xticks = (xtick * 20000, xtick))
    
    

    enter image description here

    Update: you can change bar_width

    boxplot(xx, yy, bar_width = 0.0001)
    

    enter image description here