On Oct 1, 2010, at 9:40 AM, Benjamin Root wrote:

On Thu, Sep 30, 2010 at 8:44 PM, Tony S Yu <tsy...@gmail.com> wrote:
I'd like to make something in between a box plot [1] and a histogram. Each histogram would be represented by a single, tall, rectangular patch (like the box in a box plot), and the patch would be subdivided by the bin edges of the histogram. The face color of each sub-patch would replace the bar height in the histogram.

If any of that actually made sense:

* Does this type of plot have a name?

* Is there an easy way to do this in Matplotlib?

* If there isn't an easy way, what would be a good starting point? Initial ideas: 1) Use pcolor or imshow and embed this axes in a larger axes, 2) represent the sub-patches as a PolyCollection.

Thoughts?
-Tony

[1] e.g. http://matplotlib.sourceforge.net/examples/pylab_examples/boxplot_demo.html

Tony,

I am not quite sure I understand.  

[snip]

Or maybe something else in the gallery is more like what you want:

http://matplotlib.sourceforge.net/gallery.html

Ben Root


I've checked the gallery, but I don't see anything that appears similar. In any case, I ended up hacking together something that works. I've attached an image of what I had in mind (created with the code at the very bottom of this reply).

I ended up using mpl Rectangle objects and stringing them together using a PatchCollection. Maybe there's a more efficient way to do this, but this approach worked well-enough.

Best,
-Tony

"""
First attempt at a histogram strip chart (made up name).

if-main block taken from [1] except that I've replaced uniform distributions
with normal distributions.

"""

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import collections


NORM_TYPES = dict(max=max, sum=sum)

class BinCollection(collections.PatchCollection):

    def __init__(self, hist, bin_edges, x=0, width=1, cmap=plt.cm.gray_r, 
                 norm_type='max', **kwargs):
        yy = (bin_edges[:-1] + bin_edges[1:])/2.
        heights = np.diff(bin_edges)
        bins = [plt.Rectangle((x, y), width, h) for y, h in zip(yy, heights)]
        norm = NORM_TYPES[norm_type]
        fc = cmap(np.asarray(hist, dtype=float)/norm(hist))
        super(BinCollection, self).__init__(bins, facecolors=fc, **kwargs)

def histstrip(x, positions=None, widths=None, ax=None):
    if ax is None:
        ax = plt.gca()
    if positions is None:
        positions = range(1, len(x) + 1)
    if widths is None:
        widths = np.min(np.diff(positions)) / 2. * np.ones(len(positions))
    for data, x_pos, w in zip(x, positions, widths):
        x_pos -= w/2.
        hist, bin_edges = np.histogram(data)
        bins = BinCollection(hist, bin_edges, width=w, x=x_pos)
        ax.add_collection(bins, autolim=True)
    ax.set_xticks(positions)
    ax.autoscale_view()

if __name__ == '__main__':
    import matplotlib.pyplot as plt
    import numpy as np

    np.random.seed(2)
    inc = 0.1
    e1 = np.random.normal(0,1, size=(500,))
    e2 = np.random.normal(0,1, size=(500,))
    e3 = np.random.normal(0,1 + inc, size=(500,))
    e4 = np.random.normal(0,1 + 2*inc, size=(500,))

    treatments = [e1,e2,e3,e4]

    fig, ax = plt.subplots()
    pos = np.array(range(len(treatments)))+1

    histstrip(treatments, ax=ax)
    ax.set_xlabel('treatment')
    ax.set_ylabel('response')
    fig.subplots_adjust(right=0.99,top=0.99)
    plt.show()

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to