Get from Ico-github-logo

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video

Highlights from
Alternative box plot

  • functionTemplate(input_args)
    FUNCTIONTEMPLATE Summary of this function goes on this H1 line
  • iosr.acoustics.irStats(fi...
    IRSTATS Calculate RT, DRR, Cte, and EDT for impulse response file
  • iosr.acoustics.rtEst(abs_...
    RTEST Estimate reverberation time based on room size and absorption
  • iosr.auditory.azimuth2itd...
    AZIMUTH2ITD Convert azimuth in degrees to ITD
  • iosr.auditory.binSearch(S...
    Conduct a binary search
  • iosr.auditory.calcIld(L,R...
    CALCILD Calculate normalised interaural level difference
  • iosr.auditory.chXcorr(hc_...
    CHXCORR Calculate cross-correlograms with a wide range of options.
  • iosr.auditory.chXcorr2(hc...
    CHXCORR2 Calculate cross-correlograms with a range of options.
  • iosr.auditory.createWindo...
    Create a Hann or exp. window with specified onsets/offsets
  • iosr.auditory.dupWeight(f)
    DUP_WEIGHT Calculate duplex weighting coefficients for ITD and ILD
  • iosr.auditory.erbRate2hz(x)
    ERBRATE2HZ Convert ERB rate to Hz.
  • iosr.auditory.freqMulti(f)
    FREQMULTI Calculate frequency coefficient for ITD-azimuth warping
  • iosr.auditory.gammatoneFa...
    GAMMATONEFAST Produce an array of responses from gammatone filters via FFT
  • iosr.auditory.hz2erbRate(x)
    HZ2ERBRATE Convert Hz to ERB rate
  • iosr.auditory.instItd(l,r...
    INSTITD Calculate instantaneous ITD
  • iosr.auditory.iso226(phon...
    ISO226 ISO 226:2003 Normal equal-loudness-level contours
  • iosr.auditory.itd2azimuth...
    ITD2AZIMUTH Convert ITD to azimuth
  • iosr.auditory.lindemannIn...
    LINDEMANNINH Signal pre-processing for Lindemann's cross-correlation
  • iosr.auditory.loudWeight(...
    LOUDWEIGHT Calculate loudness weighting coefficients based on ISO 226
  • iosr.auditory.makeErbCFs(...
    MAKEERBCFS Make a series of center frequencies equally spaced in ERB-rate.
  • iosr.auditory.meddisHairC...
    Calculate Ray Meddis' hair cell model for a number of channels.
  • iosr.auditory.perceptualC...
    PERCEPTUALCENTROID Perceptual spectral centroid
  • iosr.auditory.xcorrLindem...
    XCORRLINDEMANN Cross-correlation based on Lindemann's precedence model
  • iosr.bss.applyIdealMasks(...
    APPLYIDEALMASKS Calculate and apply ideal masks via STFT
  • iosr.bss.applyMask(s,m,nf...
    APPLYMASK Apply a time-frequency mask to an STFT
  • iosr.bss.calcImr(m,im)
    CALCIMR Calculates the Ideal Mask Ratio (IMR)
  • iosr.bss.calcSnr(output,t...
    CALCSNR Calculate the separation SNR
  • iosr.bss.cfs2fcs(cfs,fs)
    CFS2FCS Calculate gammatone crossover frequencies.
  • iosr.bss.generateMixtures...
    GENERATEMIXTURES Generate arrays of mixtures from targets and interferers.
  • iosr.bss.getFullMask(m,fr...
    GETFULLMASK Convert frame rate mask to a sample-by-sample mask
  • iosr.bss.idealMasks(st,si...
    IDEALMASKS Calculate ideal time-frequency masks from STFTs
  • iosr.bss.resynthesise(x,f...
    RESYNTHESISE Resynthesise a target from a time-frequency mask
  • iosr.dsp.autocorr(x,Q,dim)
    AUTOCORR Perform autocorrelation via FFT
  • iosr.dsp.convFft(a,b,shape)
    CONVFFT Convolve two vectors using FFT multiplication
  • iosr.dsp.istft(s,nfft,hop...
    ISTFT Calculate the Inverse Short-Time Fourier Transform
  • iosr.dsp.lapwin(L,b)
    LAPWIN Laplace window.
  • iosr.dsp.localpeaks(x,mode)
    LOCALPEAKS Find local peaks and troughs in a vector
  • iosr.dsp.ltas(x,fs,varargin)
    LTAS calculate the long-term average spectrum of a signal
  • iosr.dsp.matchEQ(x,fs,mag...
    MATCHEQ Match the LTAS of a signal to an arbitrary spectral magnitude
  • iosr.dsp.rcoswin(N)
    RCOSWIN Raised cosine window.
  • iosr.dsp.rms(x,dim)
    RMS Calculate the rms of a vector or matrix
  • iosr.dsp.sincFilter(x,Wn,...
    SINCFILTER Apply a near-ideal low-pass or band-pass brickwall filter
  • iosr.dsp.smoothSpectrum(X...
    SMOOTHSPECTRUM Apply 1/N-octave smoothing to a frequency spectrum
  • iosr.dsp.stft(x,nfft,hop,fs)
    STFT Calculate the short-time Fourier transform of a signal
  • iosr.dsp.vsmooth(x,frame,...
    VSMOOTH Smooth a vector using mathematical functions
  • iosr.figures.chMap(M)
    CHMAP Create a monochrome-compatible colour map
  • iosr.figures.cmrMap(M)
    CMRMAP Create a monochrome-compatible colour map
  • iosr.figures.multiwaveplo...
    MULTIWAVEPLOT Stacked line plots from a matrix or vectors
  • iosr.figures.subfigrid(nr...
    SUBFIGRID Create axis positions for subfigures
  • iosr.general.cell2csv(C,f...
    CELL2CSV Output a cell array to a CSV file
  • iosr.general.checkMexComp...
    CHECKMEXCOMPILED Check if mex file is compiled for system
  • iosr.general.getContents(...
    GETCONTENTS Get the contents of a specified directory
  • iosr.general.updateConten...
    UPDATECONTENTS Create a Contents.m file including subdirectories
  • iosr.general.urn(varargin)
    URN Generate random number sequence without duplicates
  • iosr.install
    INSTALL Set search paths, and download and install dependencies.
  • iosr.statistics.getRmse(X...
    GETRMSE Calculate the root-mean-square error between input data
  • iosr.statistics.laprnd(va...
    LAPRND Pseudorandom numbers drawn from the Laplace distribution
  • iosr.statistics.qqPlot(va...
    QQPLOT Quantile-quantile plot with patch option
  • iosr.statistics.quantile(...
    QUANTILE Quantiles of a sample via various methods.
  • iosr.statistics.tab2box(X...
    TAB2BOX Prepare tabular data for boxPlot function
  • iosr.statistics.trirnd(va...
    TRIRND Pseudorandom numbers drawn from the triangular distribution
  • iosr.svn.buildSvnProfile(...
    BUILDSVNPROFILE Read data from files tagged with SVN keywords
  • iosr.svn.headRev(folders,...
    HEADREV Retrieve the head revision for specified files
  • iosr.svn.readSvnKeyword(f...
    READSVNKEYWORD Read data from a file tagged with an SVN keyword
  • boxPlot.m
  • classTemplate
    CLASSTEMPLATE Summary of this class goes on this H1 line
  • iosr.bss.mixture
    MIXTURE Class of sound source separation mixture.
  • iosr.bss.source
    SOURCE Class of sound source separation source.
    AUDIO Abstract superclass providing audio-related properties and methods.
  • iosr.statistics.functiona...
    FUNCTIONALSPREADPLOT Draw a functional plot showing data spread
  • iosr.statistics.statsPlot
    STATSPLOT An abstract superclass for classes that plot statistics
  • example.m
    determine STFT parameters
  • Contents.m
  • View all files
4.9 | 10 ratings Rate this file 73 Downloads (last 30 days) File Size: 658 KB File ID: #46545 Version: 3.2.1
image thumbnail

Alternative box plot



08 May 2014 (Updated )

Draw a box plot with various display options

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

| Watch this File

File Information

NOTE: this function is now available from the IoSR Matlab Toolbox as iosr.statistics.boxPlot.
Alternative box plot function for Matlab with many options. These options include:
- Variable sample sizes (via the tab2box() function).
- Show box sample size.
- Scaled or uniform box spacing.
- Box width scaled by sample size.
- Overlay scatter plots of underlying data.
- Overlay the mean of the data.
- Overlay additional percentiles, and attach labels to them.
- Hierarchical X-labeling and support for multidimensional data.
- Notched boxes.
- Vertical lines to separate groups.
- Automated construction of a legend.
- Set box limits as percentiles.
- Set whisker extent via various methods.
- Use of weighted quantiles.


Hierarchically Grouped Boxplot and Not Box Plot inspired this file.

MATLAB release MATLAB 8.5 (R2015a)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (58)
18 Jan 2017 Christopher Hummersone

Hi Roland. Thanks for the feedback and suggestion. I've implemented your suggestion as an optional first argument in the constructor (keeping it consistent with other Matlab functions). The change has been committed to the GitHub repo and should be pulled on to the FX within 24 hours. Thanks!

Comment only
16 Jan 2017 Roland

Roland (view profile)

Hi Christopher,

great work. your box plot looks much better than the official version of the statistics toolbox. however, i have a kindly feature request. can you provide an optional property in the constructor method for feeding an axis handle from outside? or is there already any workaround to come up with an "own" axis handle?

best, roland

07 Dec 2016 Christopher Hummersone

Hi Arnold,

It took me a little while to even show the legend title (for me, the 'visible' property of the legend title object was 'off' by default).

Anyway, I think this speaks to known problems with the legend title in HG2. See: So I have no other ideas, or any fixes, I'm afraid.


Comment only
07 Dec 2016 arnold

arnold (view profile)

Hi Christopher,

I had another look at the legend. Since Matlab had finally given the possibility to set a title to a legend I tried to do just that but the title is always off (position wise), in the lower left corner of the entirety of the legend (at least I found it to be reproducible where it is situated).

Do you have any idea why that would be?
I found the Matlab ability to add a title to the figure quite useful and robust so I'm wondering what's gong on here.

kind regards

Comment only
12 Aug 2016 cai onion

Hi Chris,
Thanks for your suggestion. I have revised the script "boxPlot", but another errors were gotten, as followings:
Undefined function 'histcounts' for input arguments of type 'double'.

Error in iosr.statistics.boxPlot/xOffset (line 2328)
[N,~,bin] = histcounts(y); % create a histogram

Error in iosr.statistics.boxPlot/drawOutliers (line 1482)
xScatter = X + (0.8.*halfboxwidth.*obj.xOffset(obj.statistics.outliers{subidx{:}}));

Error in iosr.statistics.boxPlot/draw (line 1299)

Error in iosr.statistics.boxPlot (line 658)

Error in Boxplot4Index (line 23)
h11 = iosr.statistics.boxPlot(NewCC,...

It seemed that this tool was not suitable for the older version of Matlab.

Comment only
11 Aug 2016 Christopher Hummersone

Hi Cai,

Unfortunately the matlab.mixin.SetGet class was introduced in R2014b. To make boxPlot work on earlier versions, try modifying line 1, replacing "matlab.mixin.SetGet" with "handle". boxPlot should work OK, but you won't be able to use set(...) and get(...) syntaxes to change boxPlot properties.


Comment only
11 Aug 2016 cai onion

Dear Christopher,
I tried to use this tool to make a boxplot figure, but it did not work. The error was listed as followings:
Error using iosr.statistics.boxPlot
The specified superclass 'matlab.mixin.SetGet' contains a parse error or cannot be found on MATLAB's search
path, possibly shadowed by another file with the same name.

Error in Boxplot4Index (line 23)

I did not know how to solve it. I was using a win7 and Version 2013a. However this script could be run successfully in win 7 and matlab 2015b. Thanks.

Comment only
09 Aug 2016 Christopher Hummersone

No problem at all (sorry if I sounded defensive).

When boxPlot was a function, it was called box_plot. I renamed it to boxPlot because I reimplemented it as a class, and the two coexisted locally for a short time. Still, in every other context Matlab correctly distinguishes between "boxplot" and "boxPlot", just not with the keyboard/mouse shortcuts.

Comment only
08 Aug 2016 arnold

arnold (view profile)

thanks Chris,
my lack of knowledge and usage on the notches caused that question, now looking at it I get it, it just looked like a glitch in the way the boxes were being set up.

as for the aliasing, of course I did not mean to criticize, just state my surprise as ever since HG2 I didn't consider this could cause a problem anymore. Using a tool like export_fig negates such things anyways.

As of the toolbox-issue. It's ok. When the reinstall didn't help I thought I'm just too stupid to get it. Did you not at one point change the name from box_plot to boxPlot? I guess having a unique name could remedy the problem but I could be wrong.

Comment only
08 Aug 2016 Christopher Hummersone

Hi Arnold,

The strange shapes you see are because the notch extends beyond the IQR (boxPlot should warn you about this). The notch is analogous to a confidence interval; its height is ±(1.58*IQR)/sqrt(N). So it will be generally be large if you have a small sample size (you can see a similar effect here: - scroll down to "NOTCHES"). So this behaviour is expected.

This is something I have no control over; it's determined by whatever functions/drivers you use to create the image file. Do you use export_fig ( It's a fantastic tool. Among its MANY options is control over the degree of anti-aliasing.

I understand your problem. I typed 'import iosr.statistics.*' and F1 (etc) on 'boxPlot' no longer gives help related to iosr.statistics.boxPlot. Yet the 'which' function and other runtime name resolution operations run as expected. I'm afraid this is a shortcoming in Matlab. Perhaps consider filing a bug report? But there is nothing I can do about it I'm afraid.

Comment only
07 Aug 2016 arnold

arnold (view profile)

I see (the problem with legend and hatchfill2). I didn't think it through since I almost always use legendflex.

I never used it but it doesn't seem to work for me. I see oddly shaped boxes, I'll send you a screenshot.
Also, I get heavy aliasing at the angled box edges, something I thought Mathworks prevented with their HG2 graphics system.

I have to ask again about the toolbox construct. I reinstalled matlab yesterday just to fix this but it didn't work. I'm on 2016a as you but hitting F1 or CTRL+D to get help or open boxPlot opens the original Mathworks function for me in either case (having installed iosr+ or having imported it at session start).

Comment only
04 Aug 2016 Christopher Hummersone

Hi Arnold.

I've been thinking about this, but I can't think of a good interface without adding every hatchfill2 option to boxPlot. But it is easy enough to use with boxPlot, e.g.:

import iosr.statistics.boxPlot;
h = boxPlot(rand(100,3,3));

will add a hatch to the first box in each x-group.

Of course this won't update the legend, which is a known shortcoming of hatchfill2. There is a discussion about hatchfill2 and legends on the hatchfill2 FX page.


Comment only
30 Jul 2016 arnold

arnold (view profile)

Hi Chris,
to continue ideas.... implementing hatchfill2 might readability of the diagrams.

I use it quite often for publications/diagrams but haven't tried using it with boxPlot.
I'll never understand why matlab does not have native hatch support.
As far as I know at least legendflex supports it in legends.

Comment only
18 Jul 2016 arnold

arnold (view profile)

Hi Chris,

I see, I somehow overlooked that option, thanks! I'm just too unfamiliar with matlab toolboxes and how to handle them properly otherwise I might have picked up on it myself.

Thanks for the kind words, I'd like to think I gave some useful hints/feedback. Starting at an early point there has been no reason whatsoever anymore to go and use the integrated boxplot function, it is just too limited and cumbersome compared to yours. This sadly applies to a lot of the data visualization features like no proper XY errorbars etc. shame, but for most decent plots (besides boxplots now) one still has to go and copy all data to something like Origin instead.
If I were Mathworks, I'd ask you to have this integrated.


Comment only
11 Jul 2016 Christopher Hummersone

Hi Arnold,

I've already had this debate with another user: As I mentioned in the discussion, 'Typing "import iosr.statistics.*" will prevent you from having to re-write any code.'

As it mentions in the readme "Basic installation only requires you to add the install directory to the Matlab search path." So you don't need to run iosr.install, just add the install path to your Matlab path. The rest of the tools in the package might not be relevant to you, but they are to myself and colleagues. Since they're only text files, you can ignore them; they take up very little space on your hard disk.

Getting function help (and opening the function for editing) works as normal for me, but I am using R2016a, so I'm afraid I can't help if you're using an earlier version. Typing "help iosr" should present you with a full list of the toolbox contents. In that list, each file should have a clickable link that displays help for that file.



P.S. Getting "Pick of the Week" was great. But many of the features of boxPlot were your ideas, so huge thanks for that.

Comment only
11 Jul 2016 arnold

arnold (view profile)

Dear Christopher,

I was offline for quite a while but saw this made it to 'picks of the week', very nice. Alternative boxplot has come a long way.

One thing that confuses me a bit is why you have packed so many different tools into one toolbox. I understand you have put in a lot of work into all these other tools but I don't see how they are related for most users. The installer created another folder called 'SOFA_API'... I have no interest in installing that when I am looking for the 'alternative boxlplot'

Bottom line, a ton of stuff that people might not want seems to be added even to the path. I'm not sure everybody things this is more tidy than before. iosr.statistics.boxplot is not more readable that box_plot, which it was some version ago.

One thing I usually use all the time in the editor is mark a function name and use CTRL+D or F1 to either open the function or get the help in order to figure out syntax questions etc. Now, with the function being iosr.statistics.boxplot one can't do that anymore. The only way I see now is more cumbersome, manually digging through the folders and finding that function again.

Is there an easier way to open the function and/or help that I am unaware of?

For now I'll stick with the older version because I don't want to change syntax everywhere just now. Maybe I can figure out an easier way to strip the toolbox of everything but the boxplot, quantile2 and tab2box functions.

Comment only
07 Jul 2016 Christopher Hummersone

Many thanks, Sean. I've uploaded a fix to GitHub.

Comment only
07 Jul 2016 Sean de Wolski

You have a bug on line 842

assert(isnumeric(obj.addPrctilesTxtSize) && isscalar(obj.addPrctilesTxtSize), '''ADDPRCTILESTXTSIZE'' should be a numeric scalar')

It's checking the property and not the new setting: val.

Comment only
19 May 2016 Christopher Hummersone

Hi again Arnold. I think I found and fixed your bug.

I've also been trying, on and off, to implement your sorting suggesting. But after a number of attempts, I've decided that it's too difficult to implement, because the input can have an arbitrary number of dimensions, each of an unknown size.

If you, or anyone else, wants to have a go, feel free to fork the repo!

Comment only
07 May 2016 Warwick

I got it to work properly. Probably I had a glitch in my set paths.
Great contribution. Thanks

06 May 2016 Christopher Hummersone

Hi Warwick.

I also have Matlab's boxplot function, and use this version with no problems. Note that Matlab class/function calls are case-sensitive, so you should be able to call this class as 'boxPlot' with no problems. If you can't, then I can only assume that there is an issue with your path (or it may be an OS thing, as I'm using a Mac). If you still can't get it to work, could you please post the error text, and perhaps a minimal working example? Thanks.


Comment only
06 May 2016 Warwick

This looks pretty useful. I like the option to have whiskers at [5,95] percentiles, for example, rather than 1.5*IQR which is not applicable to skewed data. However, because I already have Matlab's boxplot (no caps), your boxPlot is not recognised when I call it even though I have put it into a 'set path'. Or, at least, Matlab by default chooses its own boxplot function. Is there a workaround to this? How would I rename it to boxPlotCH, say? I'm using a Mac and Version 2016a if that is important.

Comment only
03 May 2016 Christopher Hummersone

Hi Arnold,

I'm afraid I've been unable to recreate the error. Can you please download the latest version, and post a minimal working example that reproduces the error?


Comment only
29 Apr 2016 arnold

arnold (view profile)

Hi Christopher,
I was playing with the new features when I discovered a bug I can't really make out. It might have something to do with the overhaul of the handles you did? When using samplesize 'true' this is the result:
Reference to non-existent field 'groupsTxt'.

Error in boxPlot/drawGlobalGraphics (line 1672)

Error in boxPlot/draw (line 1322)

Error in boxPlot (line 656)

I'm on the current version 2016a, don't have an installation of 2015 up and running to cross check it there.

Comment only
04 Mar 2016 Christopher Hummersone

Hi Royi,

3) The code is now on GitHub.
1) I've added an issue on to the GitHub repo for the percentile enhancement.
2) I have already implemented a 'showOutlier' option.


Comment only
03 Mar 2016 Royi Avital

Hi Christopher,
I wrote my response in context of my previous comment and your reply:
1. It would be great to have a marker for the 5% and 9% Percentile. Juts like there is the median, the mean, and 25% / 75%, add another label for 5% / 95% (Maybe optional by default).
2. I think the outliers and the scatter should (And underneath are) 2 separate scatter series. What I would like to have is the opacity and visibility property of those 2 be exposed using the methods of your function. Something like hBoxPlot.scatterVisible = false(); hBoxPlot.outlierVisible = true();.
3. Putting your code on GitHub is a great idea in my opinion.

Thank You.

Comment only
02 Mar 2016 Christopher Hummersone

Hi Royi,

I'm not sure what you mean. Can you post a link to an example?



Comment only
01 Mar 2016 Royi Avital

Hi Christophe,

1. I think you should add new queue for 5% and 95%. It can be a Star or any other marker, just to be able to put the 5% and 9% point on the graph (In addition to what we have now).
2. I think you just need to make the outliers and the data have the property "Visible" exposed in your methods, that would be perfect and easy to do on your hand (Also the opacity).
3. Putting it on GitHub is a great idea!

Thank You!

Comment only
01 Mar 2016 Christopher Hummersone

Hi Arnold. Perhaps I should put the file on Github and let you (or others) tinker ;-)

I'll put the weighting and sorting options on my [very long] todo list. Do you have any useful references on implementing a weighting algorithm?

Comment only
29 Feb 2016 arnold

arnold (view profile)

Hi Christopher,

I just now had another idea which should be easy to implement yet very useful visually:
An option to sort the groups so that the boxes within one x-group are ascending/descending.
Of course the similar functionality for the x-groups would also make sense.
This should make it a lot easier to read the data, especially if there are a lot of groups

This contribution is coming along very nicely due to your tireless commitment. Well done!
You should probably set up a donation link. :)

Comment only
28 Feb 2016 arnold

arnold (view profile)

I know it is not very common in most plotting tools but it is the scientifically 'more correct' approach if one has measurement errors. Obviously people need to know what they're doing with errors and PDFs anyways for things to be 'correct' but take a guess how many people use boxplots for 3 data-points ^^.
As I said, most scientist then go and do scatter plots with one point each + error bars (either all data points or just replace all by one using proper error propagation).
R does indeed have it. Matlab is quite cumbersome with all of that since no total least square for x errors is supported i.e.

Anyways, back on target:
Depending on how much effort you want to put into it, there are several approaches. I would start with the first and easiest:
Stick to normally distributed errors. As you suggested, the user has the option to give an extra array/vector of 'errors', one for each value or datum as you call it. Usually for most that'll be the standard deviation of the measurement i.e.. You can then calculate the weights (1./sigma.^2) for each group and using this get a weighted mean and confidence interval based on those errors.
Out of my head I have no clue about a a weighted median though it seems defined on wikipedia i.e.

I think it would go along nicely with box_plot but I could also see it as a standalone contribution on the fileexchange, also using tab2box for grouping and then doing a proper weighted mean with (asymmetrical) error bars in x and y some time in the future maybe.
Again I think the smaller effort of including it here assuming normally distributed errors/stdevs would serve 90% of the demand.
It's really a shame that Mathworks don't seem to bother about these things :)

Comment only
28 Feb 2016 Christopher Hummersone

Roy - thanks for your feedback. I'll upload a modified function soon. To be clear, do you mean that the box should be 5–95%, or the whiskers? Also, the documentation was poorly phrased. What I meant was that the scatter plot does not include the outliers (as you observe, they are plotted separately). I'm not particularly keen on adding an option that would make the plot misleading. A suitable alternative (to me) would be to set 'limit' to 'none'.

Arnold - that's an interesting idea. It's something I've not come across before, at least in Matlab, but I see R has one or two libraries for weighted box plots. So would the idea be that you specify an additional array, the same size as Y, that determines the weight associated with each datum?

Comment only
28 Feb 2016 arnold

arnold (view profile)

Hi Christopher,

what about adding functionality to display weighted boxplots - that would also be really useful and quite unique as no matlab function I know supports it. I could most definitely use it and I'm sure I'm not the only one.
As of now I always go and calculate weighted means and confidence intervals using the matlab fit function (or one by myself) and then usually plot as a scatter plot or errorbar.


Comment only
26 Feb 2016 Royi Avital

Great submission.

Few notes:
1. Could you add the option for 5% and 95% bars (In addition to 25% and 75%)?
2. The documentation states that when the option to show scatter data is on the outliers will be removed though it doesn't happen. Could you just give a different "On / OFF" to each (Can be done manually using the handlers, yet better use the classes).

Thank You!

26 Feb 2016 Christopher Hummersone

@arnold I added the 'theme' property I mentioned. Hopefully

>> set(h,'theme','colorall')

(h is the boxPlot handle) is somewhere close to what you described...?

I know the interface is more complicated, because of the support for an arbitrary number of dimensions in Y. Here are a couple of tips.

1) You no longer need to precisely specify any colormaps; you can just specify a function handle, for example,

>> set(h,'boxColor',@parula)

This functionality is described towards the end of the help.

2) Getting and setting boxPlot properties is asymmetrical, especially for group properties. For example,

>> h.boxColor = 'none';
>> h.boxColor

ans =


So you could try capturing a property value, e.g.

>> bc = get(h,'boxColor');

modifying its value, and returning the modified value to the box plot, e.g.

set(h,'boxColor', bc);

Comment only
25 Feb 2016 arnold

arnold (view profile)

true... maybe using the same color but just darken is more intuitive.

I just don't seem to get the necessary input format for the colormap of the boxes/groups. How do I just assign a standard colormap like parula, hot, etc??
This matlab typical approach by giving it a matrix of RGB vectors doesn't work
'boxColor', parula(size(g{1},1))

ah, forget it. it's documented in the classdef but wasn't really clear in the box_plot function.
I find it a bit cumbersome since I sometimes leave out the darkest color of parula for instance by choosing the colormap space to be slightly larger than I need it. parula(6) for 5 groups for instance and then use the lightest 5.

Comment only
19 Feb 2016 Christopher Hummersone

@arnold would that not make the scatter plots difficult to see if the box is the same colour?! Or perhaps you mean the outliers? The trick with this is providing a consistent and easy-to-use interface. I'm thinking about adding a 'theme' option that automates various display options (especially colour). For example, one theme option could be 'colorboxes' which would give you something similar to the screenshot attached here; 'grayboxes' would do something similar but in grayscale; 'colorlines' would have unfilled boxes and change all of the line colours; etc. I'd happily add any suggested themes.

Comment only
29 Jan 2016 Fabian Schrumpf

Very usefull and versatile function. Let's you adjust a lot of settings that the build-in function boxplot() doesn't give you access to. Thanks for sharing.

09 Dec 2015 arnold

arnold (view profile)

have you thought of optionally colouring the scatter plots with the same colour as the according box instead of just gray?

Comment only
22 Nov 2015 Christopher Hummersone

Thanks for the feedback, José. Actually showing the mean was something I was thinking about. It's an easy addition, so I've just uploaded a revised version. The outputs have been modified to include the mean data and a handle to the markers used to plot the means (see updated documentation).

Comment only
20 Nov 2015 José Ignacio Orlando

Awesome contribution!

Is is possible to plot the mean values in the same plot?

16 Nov 2015 Anders

Anders (view profile)

06 Nov 2015 Sven

Sven (view profile)

28 Oct 2015 Christopher Hummersone

Hi Arnold,

I did upgrade to R2015b, but I'm fairly certain the updated function doesn't require any functionality that's new to R2015b.

Unfortunately I had to change quite a bit about the function interface in order to support the new functionality, which does make some things harder to do than they were.

If data.groups has one column, then you can use:

[~,h] = box_plot(...);

(g has as many cells as data.groups has columns.)

As for boxcolor, it and other parameters should be specified as a cell array of size G-by-I-by-J (check out the help text for more info).

The interface is more cumbersome now, I accept that, so I'd appreciate any insight you can offer that would make it less cumbersome (whilst retaining the flexibility of allowing data.groups to be of arbitrary size). At the moment I'm thinking of further developing the function into a class and providing methods to handle things like legends and plotting parameters.


Comment only
26 Oct 2015 arnold

arnold (view profile)

did you change matlab versions in between?
I could upgrade to 2015b but haven't gotten around to it yet. (I'm still at 2014b)

Comment only
26 Oct 2015 arnold

arnold (view profile)


I'm having a couple of issues with the current version, coming from revision 381.

[y,x,g] = tab2box(data.x, data.y, data.groups);
now results in g being a cell array with everything in the first cell, i.e. a 5x1 list. So the legend which used to work doesn't anymore:
legend(squeeze(hb(:,1,:)),g, 'location', 'best');
results in:
Error using legend (line 120)
Invalid argument. Type 'help legend' for more

The Group-Coloring of the boxes used to work like:
'boxColor', parula(size(g,1))
but also, because of g ending up as a cell structure with everything in the first cell, it doesn't anymore.
How to apply 'boxColor' now? Using 'boxcolor', parula(5) results in:
Error using box_plot (line 318)
BOX_PLOT needs propertyName/propertyValue pairs

Comment only
24 May 2015 arnold

arnold (view profile)

I see you're still busy adding features and bugfixing, well, I can recommend two or three more things. Don't take it the wrong way, I'm just suggesting what I edit in my plots and what my experience with catchy scientific plotting tells me.

- background scatter plot (with jitter in x) behind each box: it's sometimes nice to see the actual data points too, many modern tools like Origin and JMP offer this option. If you just overlay a scatterplot (randomize x-position according to the width of the boxes for nicer look instead of strict x-position and set color according to box group) it achieves just that. I did it manually in some scripts now, and it looks great.

- An option to display the number of data points which make up the box on the top right (i.e.) of each box. the the prior suggestion, this helps to understand the quality of the statistics behind the boxes since many people ignorantly use box-plots with far too little data.
We've done this in our institute for years and I think it enhances the speed & quality of data interpretation.

- when the x-groups are non-scalar, vertical separator lines between the groups usually improve readability

- the ultimate box-plotting tool would be the combination of your contribution here with "hierarchical box plot" (also found on fileexchange).

... as I said, I don't say you have to include any of this ;)

Comment only
19 May 2015 Christopher Hummersone

Thanks again for your feedback and suggestions, Arnold. At your suggestion I've added an xSpacing option, that I hope is satisfying. I've also fixed both functions to remove NaNs in x and corresponding y data. Again, I hope that fixes the problem. As for logarithmic spacing, there is undoubtedly a solution, but I think it will make things unnecessarily complicated. Instead, I suggest using the new xSpacing option. The former boxWidthMode evolved into the boxSpacing option, and would not have been helpful in this case.

Comment only
18 May 2015 arnold

arnold (view profile)

yes, that fixed the bug! Thank you!

Some more suggestions. I miss the option to use an X vector with numbers for labelling but NOT spacing the axis accordingly. When X contains strings it goes and just evenly spaces the categories. It would be nice if evenly spaced x-ticks/groups would be possible for numbered X vectors as well. Maybe you just go and introduce the option 'xSpacing', 'scalar' or 'even'

Regarding this, I also found another bug. When X contains numbers AND nan's (which happens to some of my datasets), line 390 in box_plot throws an error. Adding the line x(isnan(x)) = [ ] fixes it. I'm not sure if it's generally applicable.

A minor thing... When using scalar x-axis-spacing with a numbered X-vector, the box widths get messed up when applying a logarithmic scale. You did have a 'boxwidthmode' which is no longer supported, did that have something to do with it?
I have no elegant solution for this in mind.

Thx very much!

18 May 2015 Christopher Hummersone

Ah. Of course the example works for me! There was a bug in quantile2 that I fixed a while back, but forgot to upload the file to the FX. Please download the most recent version:

Hopefully that should help. I've also updated the box_plot documentation to explicitly mention tab2box.

Comment only
17 May 2015 arnold

arnold (view profile)

Hi Christopher,

Interesting function of yours (tab2box). Looks like that, combined with box_plot.m could be what I've been looking for ... but for me (R2014b) the example given by you in the file itself (line 35-57) doesn't even work. Throws the same error as it does for my own data table:

Attempted to access x2(1); index out of bounds because numel(x2)=0.

Error in quantile2 (line 156)
q(m,n) = x2(1);

Error in box_plot (line 266)
Z.median = quantile2(y,.5,[],options.method); % median

Comment only
17 May 2015 Christopher Hummersone

Hi Arnold,

Thanks for your feedback and comment. Just to make sure I understand correctly, you're suggesting that the Y input should facilitate plotting samples of different sizes? So the columns could be of different lengths? What if Y could be a cell array?

The tab2box function implicitly offers this functionality, since it will pad Y with NaN when samples are unequal in size. But this relies on the data being in tabular form initially.

Comment only
17 May 2015 arnold

arnold (view profile)

if you used structures, you could have different x-values and sizes for each set. This would make a great addition, since Matlab and other submissions here haven't supported this forver.

or you could just introduce a group vector. X an ix1 vextor for the x-positions. Y an m x i matrix for the data and g a i x 1 vector for the groups....

Comment only
17 May 2015 arnold

arnold (view profile)

Hi Christopher,

great function, thx.
It would be great if you added the ability to use different sizes for the groups which would not have to be integrated into one 3d matrix.

22 Aug 2014 Christopher Hummersone

There's example code in the file help...

Comment only
20 Aug 2014 Juan Deaton

Can you attach the code example for the figure you have at the top?

Comment only
12 Jun 2014 Christopher Hummersone

@Alberto you mean the box colour? Use the 'boxColor' option and set it, for example, to [1 1 1; .5 .5 .5] (assuming you have two boxes per y-tick). Setting parameters for each group is described towards the bottom of the help text.

Comment only
11 Jun 2014 Alberto

Nice function, it works as promise. I miss the option , (or i don't know how to do it ) to fill the notch with a specified color like on the figure example.

09 May 2014 1.1

Changed/corrected quantile estimation algorithm. Details in help text.

12 May 2014 1.2

Moved quantile calculation to new function.

14 May 2014 1.3

Function now natively supports sub-groups, handles NaNs more robustly, and returns sample size(s). A few other minor tweaks and doc changes.

23 Apr 2015 1.4

Improved robustness to small or empty samples. Add tab2box function for arranging tabular into the format accepted by box_plot.

18 May 2015 1.4.1

Updated documentation.

19 May 2015 1.5

Remove NaN from x data (and corresponding y data).

23 May 2015 1.5.1

Fixed bug where x is a cell array of strings.

22 Sep 2015 1.6

Added options to: overlay a scatter plot of the underlying data, display the sample size in each box, add x-group separators, and add hierarchical labelling. Shuffled outputs slightly. Thanks to Arnold for the suggestions.

22 Sep 2015 1.6

Updated image.

23 Sep 2015 1.6

Forgot to include tab2box.

23 Sep 2015 1.6.1

Shuffled a few things around so that the creation order defines the layering, rather than relying on uistack(). Added linkprop() and listener to keep axes in sync and to change xseparator if ylim changes.

24 Sep 2015 1.6.2

Added x shaping for overlayed scatter plots whereby the random x offset is related to the data distribution. Fixed bug whereby xSeparator handle would be sought even if xSeparator was not specified.

27 Sep 2015 1.6.3

Added x-shaping to outliers and tweaked offset distribution.

01 Oct 2015 2.0

Numerous changes to interface in order to support multidimensional data and improve hierarchical data labelling. Added scaleWidth option to scale box widths according to sample size.

13 Oct 2015 2.0.1

Small tweaks to improve robustness.

29 Oct 2015 2.0.2

Corrected bug where x offset was erroneous if y was not hierarchical.

16 Nov 2015 2.0.3

Fixed automatic placement of boxes.

16 Nov 2015 2.0.4

Added layer and transparency options.

19 Nov 2015 2.0.5

Added trap for MarkerEdgeAlpha (scatterAlpha), which older versions of Matlab do not support.

22 Nov 2015 2.0.6

Added options for displaying the means.

23 Nov 2015 2.0.7

Corrected calculation of mean when data include NaN. Updated picture.

07 Dec 2015 2.0.8

Added meanSize property.

15 Feb 2016 3.0

Re-implemented function as a class (with a new name). Added property to automate construction of a legend.

17 Feb 2016 3.0.1

Added ability to specify colors as a colormap function. Changed some size properties to no longer be specifiable for each group. Bug fixes.

19 Feb 2016 3.0.2

More bug fixes. Forced legend alpha to match box alpha.

26 Feb 2016 3.1

Added 'theme' property to allow multiple display properties to be changed simultaneously. Various bug fixes.

01 Mar 2016 3.1.1

Added percentile options for box and whisker extent. Modified help to clarify scatter plotting.

20 May 2016 3.1.1

Moved file to Github.

21 May 2016 3.2.1

Updated version number.

06 Jun 2016 3.2.1

Moved function in to updated toolbox.

28 Jul 2016 3.2.1

Updated description.

25 Feb 2017 3.2.1

Added acknowledgement.

Contact us