Hi all,

I needed to make bean plots (see
http://www.jstatsoft.org/v28/c01/paper ) so I made a function to plot
them by tuning the violin plot code from here:
http://pyinsci.blogspot.com/2009/09/violin-plot-with-matplotlib.html

Please see the attached file if interested.

Is there a repository where this kind of additional plot functions
could be submitted? The violinplot function needs scipy, so it's maybe
matplotlib itself is out of the question?

Best,

Teemu
# Author: Teemu Ikonen <tpiko...@gmail.com>
# Based on code by Flavio Codeco Coelho,
# http://pyinsci.blogspot.com/2009/09/violin-plot-with-matplotlib.html
import numpy as np
from matplotlib.pyplot import figure, show
from scipy.stats import gaussian_kde
from numpy.random import normal


def violinplot(ax, data, pos, bp=False, cut=False):
    """Make a violin plot of each dataset in the `data` sequence.
    """
    dist = np.max(pos)-np.min(pos)
    w = min(0.15*max(dist,1.0),0.5)
    for d,p in zip(data,pos):
        k = gaussian_kde(d) #calculates the kernel density
        s = 0.0
        if not cut:
            s = 1.5*np.std(d) #FIXME: magic constant 1.5
        m = k.dataset.min() - s #lower bound of violin
        M = k.dataset.max() + s #upper bound of violin
        x = np.linspace(m, M, 100) # support for violin
        v = k.evaluate(x) #violin profile (density curve)
        v = w*v/v.max() #scaling the violin to the available space
        ax.fill_betweenx(x,-v+p,v+p,facecolor='y',alpha=0.3)
    if bp:
        ax.boxplot(data,notch=1,positions=pos,vert=1)


def stripchart(ax, data, pos, mean=False, median=False, width=None):
    """Plot samples given in `data` as horizontal lines.

    Keyword arguments:
        mean: plot mean of each dataset as a thicker line if True
        median: plot median of each dataset as a dot if True.
        width: Horizontal width of a single dataset plot.
    """
    if width:
        w = width
    else:
        dist = np.max(pos)-np.min(pos)
        w = min(0.15*max(dist,1.0),0.5)
    for d,p in zip(data,pos):
        hw = w/2.0
        ax.hlines(d, p-hw, p+hw, lw=0.5)
        if mean:
            ax.hlines(np.mean(d), p-w, p+w, lw=1.0, color='b')
        if median:
            ax.plot(p, np.median(d), 'o', color='r')


def beanplot(ax, data, pos, mean=True, median=True, cut=False):
    """Make a bean plot of each dataset in the `data` sequence.

    Reference: http://www.jstatsoft.org/v28/c01/paper
    """
    #FIXME: Implement also the asymmetric beanplot
    dist = np.max(pos)-np.min(pos)
    w = min(0.15*max(dist,1.0),0.5)
    stripchart(ax, data, pos, mean, median, 0.8*w)
    violinplot(ax, data, pos, False, cut)


if __name__=="__main__":
    pos = range(5)
    data = [normal(size=100) for i in pos]
    fig=figure()
    ax = fig.add_subplot(111)
    beanplot(ax,data,pos)
    show()

------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network 
management toolset available today.  Delivers lowest initial 
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to