# The correct way to display non-normal data?

In my university we learned a lot about normal data, but handling non-normal data wasn't really covered. For some benchmarking of an application I have data has a very high frequency around one value

Doing my standard tests, additionally to the histogram, to check for normality are qqplot() and qqline()

It is clear that this dataset deviates from a normal distribution. Now the question remains: how to present this data in an acceptable and understandable manner. My first idea was to just display the median, but I also want to account for the error in measurement.

The two options I'm considering are boxplots or present the CI with bootstrapping. With boxplots I have some reservations about the readability in combination with non-normal data.

Therefore I've explored bootstrapping. However in order to do using the mean (red line) seems wrong and therefore I would use the trimmed mean 20% (purple line)

Using the R library simpleboot I could use the trimmed mean and get the Bootstrap Bias-Corrected Accelerated (BCa) as discussed in Bootstrap Methods and Permutation Tests, Hesterberg values for the error ranges.

## Summary:

I have non-normal data which I'm not experienced with. I'm wondering if using bootstrapping to dervice the BCa is the/a correct way to present this type of data. Also I'm worrying that I'm overcomplicating this.

EDIT: as requested in the output of dput:

 100272, 101960, 101972, 101988, 101988, 101988, 101988, 101988, 101988, 101988, 101408, 101428, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432, 101428, 101400, 101420, 101424, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101420, 101424, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428, 101432, 101432, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101412, 101432, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101408, 101428, 101432, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436

• @StephanKolassa sure. It's added. – swennemen May 17 '16 at 11:46

First off, there is not "the" correct way of presenting your data. Depending on what is important or relevant to you, there may be different possibilities.

You only have 101 data points. In such a situation, it often makes sense to plot the raw data instead of summary graphics like histograms or smoothed density plots.

The raw data can be shown using q-q-plots, as you do, or using the ECDF, as Frank Harrell suggests. However, I don't think a rug plot will be very enlightening, because of the sheer concentration of 83% of your data points in the interval $[101,428; 101,436]$.

I personally like the beanplot and the beeswarm, and since your data is essentially discrete (it all comes in multiples of 4), the sunflowerplot:

library(beanplot)
library(beeswarm)

foo <- c(100272, 101960, 101972, 101988, 101988, 101988, 101988, 101988,
101988, 101988, 101408, 101428, 101432, 101432, 101432, 101432,
101432, 101432, 101432, 101432, 101432, 101432, 101432, 101432,
101432, 101432, 101432, 101432, 101428, 101400, 101420, 101424,
101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428,
101428, 101428, 101428, 101428, 101428, 101428, 101428, 101428,
101428, 101420, 101424, 101428, 101428, 101428, 101428, 101428,
101428, 101428, 101428, 101432, 101432, 101436, 101436, 101436,
101436, 101436, 101436, 101436, 101412, 101432, 101436, 101436,
101436, 101436, 101436, 101436, 101436, 101436, 101436, 101436,
101436, 101436, 101436, 101436, 101436, 101436, 101436, 101408,
101428, 101432, 101436, 101436, 101436, 101436, 101436, 101436,
101436, 101436, 101436, 101436, 101436)

opar <- par(mfrow=c(1,3))
beanplot(foo,col="grey",yaxt="n",main="Bean plot/\nViolin plot",border="black")
beeswarm(foo,pch=19,main="Beeswarm\nplot")
sunflowerplot(x=rep(1,length(foo)),y=foo,main="Sunflower\nplot",xlab="",xaxt="n",ylab="")
par(opar)


All of these show the high concentration around specific values already mentioned, even if the beanplot is not overly pretty and the beeswarm cuts off a number of data points.

Here are a few more possibilities.

Edit: in each case, you can add the trimmed mean as a horizontal line using abline. I played around a bit with bootstrapping it; however, once you trim off 20%, the trimmed mean almost does not vary at all any more, so even a 99% confidence interval has a width of only 2.9 and is essentially invisible on these scales. In any case, your distribution is so enormously discrete that the mean, whether trimmed or not, does not really convey a lot of information. Given this utter discreteness, you may even want to plot a simple table of the values, which is the logical end point of making histogram bins smaller and smaller:

plot(as.numeric(names(table(foo))),table(foo),type="h",xlab="",ylab="")
axis(2)


• Wow some very useful information you're sharing here, I learned some new things :) – swennemen May 17 '16 at 13:25
• Thank you. Learning new things is kind of the idea at StackExchange ;-) – Stephan Kolassa May 17 '16 at 13:27

Bootstrapping is not really a method for graphing data. It can be useful for finding confidence intervals, but your question is about display.

A boxplot can be a very good method of showing your data. My guess is that you will have a lot of outliers (at least if you use any of the default methods of determining outliers).

The density plot you've shown is also OK, you might want to add a rug plot underneath.

Yet another option is a strip plot.

You can add confidence intervals to either of the last two choices.

• In addition to Peter's comments, I would use quite a few more bins in the histogram, use a rug plot, and show the empirical cumulative distribution function, which requires no binning at all. – Frank Harrell May 17 '16 at 11:48
• I see. And what about plotting a Confidence Interval with the trimmed mean and the BCa as error bars? The public that will read it will probably not be famillair with strip- and/or rugplots. – swennemen May 17 '16 at 11:52
• Strip and rug plots are very easy to interpret - much easier than trimmed mean and BCa errors! With any of the suggestions that I or Frank made, all the information is right there in front of the viewer. But you can certainly add things if you want. However, I might put that info in the text. – Peter Flom - Reinstate Monica May 18 '16 at 12:45