Asked by Eric Sampson
on 1 Feb 2013

I'm trying to find a way to recreate JMP-style variability charts using MATLAB.

I've tried looking through the Stats Toolbox and the File Exchange, and can't find anything that would do the trick. Anyone have an idea?

Thanks!

Answer by Matt Tearle
on 1 Feb 2013

Edited by Matt Tearle
on 22 Mar 2013

Accepted answer

**EDIT**: file added to MATLAB File Exchange. Share and enjoy!

Based on your comment above, `boxplot` with nominal grouping variables will do it:

x = randn(400,1); y1 = nominal(round(rand(400,1)),{'little','lots'}); y2 = nominal(round(rand(400,1)),{'large','small'}); y3 = nominal(round(rand(400,1)),{'gourmet','plain'}); boxplot(x,[y1,y2,y3])

Hopefully this is basically how your data is already arranged. `x` contains all 400 observations of the response variable. `y1`, `y2`, and `y3` are nominal arrays that record each observation's status for the three categories.

The boxplot labeling doesn't emphasize the hierarchy, but the results are correct.

**EDIT TO ADD** Oops, I got the grouping variables backward. Anyway, this is getting close to what you posted:

boxplot(x,[y3,y2,y1],... 'plotstyle','compact','labelorientation','horizontal',... 'factorseparator',[1,2])

The only problem is that the vertical arrangement of the group labels is backwards, for showing the hierarchy. This can be hacked, though, if you need:

h = findobj(get(gca,'children'),'type','text'); tl = get(h,'position'); tl = cat(1,tl{:}); tl(:,2) = flipud(tl(:,2)); for k = 1:length(h) set(h(k),'position',tl(k,:)) end

**EDIT TO ADD (2)**: Not pretty, but here's a function that does a reasonable job of approximating the graphic:

function variabilityplot(x,y) n = size(y,2); numgrps = zeros(1,n); for k = 1:n numgrps(k) = numel(unique(y(:,k))); end numgrps = cumprod(numgrps); N = numgrps(n);

y = fliplr(y); boxplot(x,y,... 'plotstyle','compact','labelorientation','horizontal',... 'factorseparator',1:n);

hbxplt = get(gca,'children'); hall = get(hbxplt,'children'); halltype = get(hall,'type'); hsepln = hall(end-n+1:end);

htxt = hall(strcmpi('text',halltype)); set(htxt,'units','data') txtpos = get(htxt,'position'); txtpos = cat(1,txtpos{:}); txtpos(:,2) = flipud(txtpos(:,2));

x = reshape(txtpos(:,1),N,n); for k = 2:n m = numgrps(k-1); for j = 1:N ii = floor((j-1)/m); i1 = 1 + m*ii; i2 = m*(1+ii); x(j,k) = mean(x(i1:i2,1)); end end txtpos(:,1) = x(:); for k = 1:length(htxt) set(htxt(k),'position',txtpos(k,:)) end

tlcol = 0.5*[1,1,1]; txtpos = get(htxt,'extent'); txtpos = cat(1,txtpos{:}); xl = xlim; yl = ylim; y1 = min(yl); y2 = min(txtpos(:,2)); y = linspace(y1,y2,n+1); for k = 2:(n+1) line(xl,[y(k),y(k)],'parent',gca,'clipping','off','color',tlcol) end line(xl(1)*[1,1],[y1,y2],'parent',gca,'clipping','off','color',tlcol) line(xl(2)*[1,1],[y1,y2],'parent',gca,'clipping','off','color',tlcol) for j = 1:n newy = get(hsepln(j),'YData'); newy(newy==yl(2)) = y(j+1); line(get(hsepln(j),'XData'),newy,'parent',gca,'clipping','off','color',tlcol) end

delete(hsepln(1))

Trying it out:

x = randn(400,1); y1 = nominal(randi(2,400,1),{'little','lots'}); y2 = nominal(randi(3,400,1),{'large','medium','small'}); y3 = nominal(randi(2,400,1),{'gourmet','plain','aardvark','potato'},[1,2,3,4]); y = [y1,y2,y3]; variabilityplot(x,y)

If you think it's useful, I'll clean it up a bit and put it on the File Exchange soon.

Show 5 older comments

Eric Sampson
on 11 Feb 2013

Matt Tearle
on 22 Mar 2013

Eric Sampson
on 18 Oct 2013

Answer by Shashank Prasanna
on 1 Feb 2013

You can certainly use boxplots: http://www.mathworks.com/help/stats/boxplot.html

But I am not certain there is something that generates a plot that looks exactly like that. You may have to generate a boxplot and add all the labels below them after that.

Opportunities for recent engineering grads.

## 3 Comments

## Matt Tearle (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/60857#comment_126557

How important is the formatting detail? A boxplot will do the job, but look quite different. Which details of the appearance are important to you?

## Eric Sampson (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/60857#comment_126559

Matt, the critical part is how it understands the hierarchical nature of the groups (in the example, note how oil amt is a subset of batch size, which is a subset of popcorn type), and also how it includes that understanding in the layout of the X axis labeling. The end users are accustomed to this chart layout, and expect to see the same look.

## Shashank Prasanna (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/60857#comment_126560

If you know how the 'understanding is included' in that chart, you can use that information and create a boxplot. There is nothing this specialized that is offered in the statistics toolbox. You could put in a ticket with the mathworks as a suggested enhancement along with your usecase.