Ejemplo n.º 1
0
def scatter(*args, **kwargs):
    """
    This will plot a scatterplot of x and y, iterating over the ColorBrewer
    "Set2" color cycle unless a color is specified. The symbols produced are
    empty circles, with the outline in the color specified by either 'color'
    or 'edgecolor'. If you want to fill the circle, specify 'facecolor'.

    Besides the matplotlib scatter(), will also take the parameter
    @param show_ticks: Whether or not to show the x and y axis ticks
    """
    # Force 'color' to indicate the edge color, so the middle of the
    # scatter patches are empty. Can specify
    ax, args, kwargs = utils.maybe_get_ax(*args, **kwargs)

    if 'color' not in kwargs:
        # Assume that color means the edge color. You can assign the
        color_cycle = ax._get_lines.color_cycle
        kwargs['color'] = next(color_cycle)
    if 'edgecolor' not in kwargs:
        kwargs['edgecolor'] = almost_black
    if 'alpha' not in kwargs:
        kwargs['alpha'] = 0.5

    lw = utils.maybe_get_linewidth(**kwargs)
    kwargs['lw'] = lw

    show_ticks = kwargs.pop('show_ticks', False)

    scatterpoints = ax.scatter(*args, **kwargs)
    utils.remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return ax
Ejemplo n.º 2
0
def plot(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    show_ticks = kwargs.pop('show_ticks', False)

    lines = ax.plot(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return lines
Ejemplo n.º 3
0
def scatter(*args, **kwargs):
    """
    This will plot a scatterplot of x and y, iterating over the ColorBrewer
    "Set2" color cycle unless a color is specified. The symbols produced are
    empty circles, with the outline in the color specified by either 'color'
    or 'edgecolor'. If you want to fill the circle, specify 'facecolor'.

    Besides the matplotlib scatter(), will also take the parameter
    @param show_ticks: Whether or not to show the x and y axis ticks
    """
    # Force 'color' to indicate the edge color, so the middle of the
    # scatter patches are empty. Can specify
    ax, args, kwargs = utils.maybe_get_ax(*args, **kwargs)

    if 'color' not in kwargs:
        # Assume that color means the edge color. You can assign the
        color_cycle = cycle(mpl.rcParams['axes.color_cycle'])
        kwargs['color'] = next(color_cycle)
    kwargs.setdefault('edgecolor', almost_black)
    kwargs.setdefault('alpha', 0.5)

    lw = utils.maybe_get_linewidth(**kwargs)
    kwargs['lw'] = lw

    show_ticks = kwargs.pop('show_ticks', False)

    scatterpoints = ax.scatter(*args, **kwargs)
    utils.remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return ax
Ejemplo n.º 4
0
def hist(*args, **kwargs):
    """
    Plots a histogram of the provided data. Can provide optional argument
    "grid='x'" or "grid='y'" to draw a white grid over the histogram. Almost like "erasing" some of the plot,
     but it adds more information!
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    color_cycle = ax._get_lines.color_cycle
    color = next(color_cycle)
    # Reassign the default colors to Set2 by Colorbrewer
    if 'color' not in kwargs:
        kwargs['color'] = color
    if 'facecolor' not in kwargs:
        kwargs['facecolor'] = color
    if 'edgecolor' not in kwargs:
        kwargs['edgecolor'] = 'white'
    show_ticks = kwargs.pop('show_ticks', False)

    # If no grid specified, don't draw one.
    grid = kwargs.pop('grid', None)

    # print 'hist kwargs', kwargs
    patches = ax.hist(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], grid=grid, show_ticks=show_ticks)
    return ax
Ejemplo n.º 5
0
def hist(*args, **kwargs):
    """
    Plots a histogram of the provided data. Can provide optional argument
    "grid='x'" or "grid='y'" to draw a white grid over the histogram. Almost like "erasing" some of the plot,
     but it adds more information!
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    color_cycle = ax._get_lines.color_cycle
    # Reassign the default colors to Set2 by Colorbrewer
    if iterable(args[0]):
        if isinstance(args[0], list):
            ncolors = len(args[0])
        else:
            if len(args[0].shape) == 2:
                ncolors = args[0].shape[1]
            else:
                ncolors = 1
        kwargs.setdefault('color', [next(color_cycle) for _ in range(ncolors)])
    else:
        kwargs.setdefault('color', next(color_cycle))
    kwargs.setdefault('edgecolor', 'white')
    show_ticks = kwargs.pop('show_ticks', False)

    # If no grid specified, don't draw one.
    grid = kwargs.pop('grid', None)

    # print 'hist kwargs', kwargs
    patches = ax.hist(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], grid=grid, show_ticks=show_ticks)
    return ax
Ejemplo n.º 6
0
def stackplot(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    lw = maybe_get_linewidth(**kwargs)
    kwargs['linewidths'] = lw

    kwargs.setdefault('edgecolor', almost_black)
    show_ticks = kwargs.pop('show_ticks', False)

    lines = ax.stackplot(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return lines
Ejemplo n.º 7
0
def stackplot(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    lw = maybe_get_linewidth(**kwargs)
    kwargs['linewidths'] = lw

    kwargs.setdefault('edgecolor', almost_black)
    show_ticks = kwargs.pop('show_ticks', False)

    lines = ax.stackplot(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return lines 
Ejemplo n.º 8
0
def trendlines(queries, norm=False):
    """Plot query results"""
    for q in queries:
        counts = queries[q]
        x = counts[:, 0]
        y = np.copy(counts[:, 1])
        if norm:
            y = y / counts[:, 2]
        plt.plot(x, y * 100, label=q, lw=4, alpha=0.8)
    plt.xlim(np.min(x), np.max(x))
    plt.xlabel('Year')
    plt.ylabel('Percent of Refereed\nPublications Mentioning')
    plt.legend(loc='upper left', frameon=False)
    remove_chartjunk(plt.gca(), ['top', 'right'])
Ejemplo n.º 9
0
def plot(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    if 'color' not in kwargs:
        # if no color is specified, cycle over the ones in this axis
        color_cycle = ax._get_lines.color_cycle
        kwargs['color'] = next(color_cycle)
    if 'linewidth' not in kwargs:
        kwargs['linewidth'] = 0.75

    show_ticks = kwargs.pop('show_ticks', False)

    lines = ax.plot(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return lines
Ejemplo n.º 10
0
def boxplot(*args, **kwargs):
    """
    Create a box-and-whisker plot showing the mean, 25th percentile, and 75th
    percentile. The difference from matplotlib is only the left axis line is
    shown, and ticklabels labeling each category of data can be added.

    @param ax:
    @param x:
    @param kwargs: Besides xticklabels, which is a prettyplotlib-specific
    argument which will label each individual boxplot, any argument for
    matplotlib.pyplot.boxplot will be accepted:
    http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.boxplot
    @return:
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    # If no ticklabels are specified, don't draw any
    xticklabels = kwargs.pop('xticklabels', None)
    fontsize = kwargs.pop('fontsize', 10)

    kwargs.setdefault('widths', 0.15)

    bp = ax.boxplot(*args, **kwargs)

    if xticklabels:
        ax.xaxis.set_ticklabels(xticklabels, fontsize=fontsize)

    show_caps = kwargs.pop('show_caps', True)
    show_ticks = kwargs.pop('show_ticks', False)

    remove_chartjunk(ax, ['top', 'right', 'bottom'], show_ticks=show_ticks)
    linewidth = 0.75

    blue = colors.set1[1]
    red = colors.set1[0]
    plt.setp(bp['boxes'], color=blue, linewidth=linewidth)
    plt.setp(bp['medians'], color=red)
    plt.setp(bp['whiskers'],
             color=blue,
             linestyle='solid',
             linewidth=linewidth)
    plt.setp(bp['fliers'], color=blue)
    if show_caps:
        plt.setp(bp['caps'], color=blue, linewidth=linewidth)
    else:
        plt.setp(bp['caps'], color='none')
    ax.spines['left']._linewidth = 0.5
    return ax
Ejemplo n.º 11
0
def fill_betweenx(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    lw = maybe_get_linewidth(**kwargs)
    kwargs['linewidths'] = lw

    if 'color' not in kwargs:
        # if no color is specified, cycle over the ones in this axis
        color_cycle = cycle(mpl.rcParams['axes.color_cycle'])
        kwargs['color'] = next(color_cycle)
    kwargs.setdefault('edgecolor', almost_black)

    show_ticks = kwargs.pop('show_ticks', False)

    lines = ax.fill_betweenx(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return ax
Ejemplo n.º 12
0
def fill_between(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    lw = maybe_get_linewidth(**kwargs)
    kwargs['linewidths'] = lw

    if 'color' not in kwargs:
        # if no color is specified, cycle over the ones in this axis
        color_cycle = ax._get_lines.color_cycle
        kwargs['color'] = next(color_cycle)
    kwargs.setdefault('edgecolor', almost_black)

    show_ticks = kwargs.pop('show_ticks', False)

    lines = ax.fill_between(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return lines 
Ejemplo n.º 13
0
def boxplot(*args, **kwargs):
    """
    Create a box-and-whisker plot showing the mean, 25th percentile, and 75th
    percentile. The difference from matplotlib is only the left axis line is
    shown, and ticklabels labeling each category of data can be added.

    @param ax:
    @param x:
    @param kwargs: Besides xticklabels, which is a prettyplotlib-specific
    argument which will label each individual boxplot, any argument for
    matplotlib.pyplot.boxplot will be accepted:
    http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.boxplot
    @return:
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    # If no ticklabels are specified, don't draw any
    xticklabels = kwargs.pop('xticklabels', None)
    fontsize = kwargs.pop('fontsize', 10)

    if 'widths' not in kwargs:
        kwargs['widths'] = 0.15

    bp = ax.boxplot(*args, **kwargs)

    if xticklabels:
        ax.xaxis.set_ticklabels(xticklabels, fontsize=fontsize)

    show_caps = kwargs.pop('show_caps', True)
    show_ticks = kwargs.pop('show_ticks', False)

    remove_chartjunk(ax, ['top', 'right', 'bottom'], show_ticks=show_ticks)
    linewidth = 0.75

    blue = colors.set1[1]
    red = colors.set1[0]
    plt.setp(bp['boxes'], color=blue, linewidth=linewidth)
    plt.setp(bp['medians'], color=red)
    plt.setp(bp['whiskers'], color=blue, linestyle='solid',
             linewidth=linewidth)
    plt.setp(bp['fliers'], color=blue)
    if show_caps:
        plt.setp(bp['caps'], color=blue, linewidth=linewidth)
    else:
        plt.setp(bp['caps'], color='none')
    ax.spines['left']._linewidth = 0.5
    return ax
Ejemplo n.º 14
0
def fill_between(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    lw = maybe_get_linewidth(**kwargs)
    kwargs["linewidths"] = lw

    if "color" not in kwargs:
        # if no color is specified, cycle over the ones in this axis
        color_cycle = ax._get_lines.color_cycle
        kwargs["color"] = next(color_cycle)
    if "edgecolor" not in kwargs:
        kwargs["edgecolor"] = almost_black

    show_ticks = kwargs.pop("show_ticks", False)

    lines = ax.fill_between(*args, **kwargs)
    remove_chartjunk(ax, ["top", "right"], show_ticks=show_ticks)
    return ax
Ejemplo n.º 15
0
def boxplot(*args, **kwargs):
    """
    Create a box-and-whisker plot showing the mean, 25th percentile, and 75th
    percentile. The difference from matplotlib is only the left axis line is
    shown, and ticklabels labeling each category of data can be added.

    @param ax:
    @param x:
    @param kwargs: Besides xticklabels, which is a prettyplotlib-specific
    argument which will label each individual boxplot, any argument for
    matplotlib.pyplot.boxplot will be accepted:
    http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.boxplot
    @return:
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    # If no ticklabels are specified, don't draw any
    xticklabels = kwargs.pop("xticklabels", None)
    fontsize = kwargs.pop("fontsize", 10)

    kwargs.setdefault("widths", 0.15)

    bp = ax.boxplot(*args, **kwargs)

    if xticklabels:
        ax.xaxis.set_ticklabels(xticklabels, fontsize=fontsize)

    show_caps = kwargs.pop("show_caps", True)
    show_ticks = kwargs.pop("show_ticks", False)

    remove_chartjunk(ax, ["top", "right", "bottom"], show_ticks=show_ticks)
    linewidth = 0.75

    blue = colors.set1[1]
    red = colors.set1[0]
    plt.setp(bp["boxes"], color=blue, linewidth=linewidth)
    plt.setp(bp["medians"], color=red)
    plt.setp(bp["whiskers"], color=blue, linestyle="solid", linewidth=linewidth)
    plt.setp(bp["fliers"], color=blue)
    if show_caps:
        plt.setp(bp["caps"], color=blue, linewidth=linewidth)
    else:
        plt.setp(bp["caps"], color="none")
    ax.spines["left"]._linewidth = 0.5
    return bp
Ejemplo n.º 16
0
def eventplot(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    show_ticks = kwargs.pop('show_ticks', False)
    alpha = kwargs.pop('alpha', 1.0)

    if len(args) > 0:
        positions = args[0]
    else:
        positions = kwargs['positions']

    if any(iterable(p) for p in positions):
        size = len(positions)
    else:
        size = 1

    kwargs.setdefault('colors', [c + (alpha, ) for c in set2[:size]])

    event_collections = ax.eventplot(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return event_collections
Ejemplo n.º 17
0
def eventplot(*args, **kwargs):
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    show_ticks = kwargs.pop('show_ticks', False)
    alpha = kwargs.pop('alpha', 1.0)

    if len(args) > 0:
        positions = args[0]
    else:
        positions = kwargs['positions']

    if any(iterable(p) for p in positions):
        size = len(positions)
    else:
        size = 1

    kwargs.setdefault('colors', [c + (alpha,) for c in set2[:size]])

    event_collections = ax.eventplot(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
    return event_collections
Ejemplo n.º 18
0
def pcolormesh(*args, **kwargs):
    """
    Use for large datasets

    Non-traditional `pcolormesh` kwargs are:
    - xticklabels, which will put x tick labels exactly in the center of the
    heatmap block
    - yticklables, which will put y tick labels exactly aligned in the center
     of the heatmap block
     - xticklabels_rotation, which can be either 'horizontal' or 'vertical'
     depending on how you want the xticklabels rotated. The default is
     'horizontal', but if you have xticklabels that are longer, you may want
     to do 'vertical' so they don't overlap.
     - yticklabels_rotation, which can also be either 'horizontal' or
     'vertical'. The default is 'horizontal' and in most cases,
     that's what you'll want to stick with. But the option is there if you
     want.
    - center_value, which will be the centered value for a divergent
    colormap, for example if you have data above and below zero, but you want
    the white part of the colormap to be equal to 10 rather than 0,
    then specify 'center_value=10'.
    """
    # Deal with arguments in kwargs that should be there, or need to be taken
    #  out
    fig, ax, args, kwargs = maybe_get_fig_ax(*args, **kwargs)

    # If x and y axis are passed in arguments, gets correct data
    # Ticks will work with x and y data, although it would be pointless to use
    # both x/y and custom ticks
    if len(args) == 3:
        x = args[0]
        y = args[1]
        data = args[2]
    elif len(args) == 1:
        data = args[0]

    kwargs.setdefault('vmax', data.max())
    kwargs.setdefault('vmin', data.min())

    center_value = kwargs.pop('center_value', 0)

    # If
    divergent_data = False
    if kwargs['vmax'] > 0 and kwargs['vmin'] < 0:
        divergent_data = True
        kwargs['vmax'] += center_value
        kwargs['vmin'] += center_value

    # If we have both negative and positive values, use a divergent colormap
    if 'cmap' not in kwargs:
        # Check if this is divergent
        if divergent_data:
            kwargs['cmap'] = blue_red
        elif kwargs['vmax'] <= 0:
            kwargs['cmap'] = blues_r
        elif kwargs['vmax'] > 0:
            kwargs['cmap'] = reds

    if 'xticklabels' in kwargs:
        xticklabels = kwargs['xticklabels']
        kwargs.pop('xticklabels')
    else:
        xticklabels = None
    if 'yticklabels' in kwargs:
        yticklabels = kwargs['yticklabels']
        kwargs.pop('yticklabels')
    else:
        yticklabels = None

    if 'xticklabels_rotation' in kwargs:
        xticklabels_rotation = kwargs['xticklabels_rotation']
        kwargs.pop('xticklabels_rotation')
    else:
        xticklabels_rotation = 'horizontal'
    if 'yticklabels_rotation' in kwargs:
        yticklabels_rotation = kwargs['yticklabels_rotation']
        kwargs.pop('yticklabels_rotation')
    else:
        yticklabels_rotation = 'horizontal'

    ax_colorbar = kwargs.pop('ax_colorbar', None)
    orientation_colorbar = kwargs.pop('orientation_colorbar', 'vertical')

    p = ax.pcolormesh(*args, **kwargs)
    # ax.set_ylim(0, x.shape[0])
    # ax.set_xlim(0, x.shape[1])

    # Get rid of ALL axes
    remove_chartjunk(ax, ['top', 'right', 'left', 'bottom'])

    if xticklabels is not None and any(xticklabels):
        if len(args) == 1:
            xticks = np.arange(1, data.shape[1] + 1)
        else:
            xticks = []
            for i in np.arange(len(x) - 1):
                half = float(x[i + 1] - x[i]) / 2. + x[i]
                xticks.append(half)
        xticks = np.array(xticks)
        ax.set_xticks(xticks)
        ax.set_xticklabels(xticklabels, rotation=xticklabels_rotation)

    if yticklabels is not None and any(yticklabels):
        if len(args) == 1:
            yticks = np.arange(1, data.shape[2] + 1)
        else:
            yticks = []
            for i in np.arange(len(y) - 1):
                half = float(y[i + 1] - y[i]) / 2. + y[i]
                yticks.append(half)
        yticks = np.array(yticks)
        ax.set_yticks(yticks)
        ax.set_yticklabels(yticklabels, rotation=yticklabels_rotation)

    # Show the scale of the colorbar
    cbar = fig.colorbar(p,
                        cax=ax_colorbar,
                        use_gridspec=True,
                        orientation=orientation_colorbar)
    return p, cbar
Ejemplo n.º 19
0
def bar(*args, **kwargs):
    """
    Creates a bar plot, with white outlines and a fill color that defaults to
     the first teal-ish green in ColorBrewer's Set2. Optionally accepts
     grid='y' or grid='x' to draw a white grid over the bars,
     to show the scale. Almost like "erasing" some of the plot,
     but it adds more information!

    Can also add an annotation of the height of the barplots directly onto
    the bars with the `annotate` parameter, which can either be True,
    which will annotate the values, or a list of strings, which will annotate
    with the supplied strings.

    Can support stacked bars with the value of each stack shown on the stack
    (Added by Salil Banerjee)

    @param ax: matplotlib.axes instance
    @param left: Vector of values of where to put the left side of the bar
    @param height: Vector of values of the bar heights
    @param kwargs: Besides xticklabels, which is a prettyplotlib-specific
    argument, any additional arguments to matplotlib.bar(): http://matplotlib
    .org/api/axes_api.html#matplotlib.axes.Axes.bar is accepted.
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    kwargs.setdefault('color', set2[0])
    kwargs.setdefault('edgecolor', 'white')
    middle = 0.4 if 'width' not in kwargs else kwargs['width']/2.0

    # Check if data contains stacks
    stacked = kwargs.pop('stacked',False)
    # Check if stack text should be included
    stack_text = kwargs.pop('stack_text',False)
    # Get legend if available
    legend = kwargs.pop('legend',False)

    left = args[0]
    height = np.array(args[1])

    # Label each individual bar, if xticklabels is provided
    xtickabels = kwargs.pop('xticklabels', None)
    # left+0.4 is the center of the bar
    xticks = np.array(left) + middle

    # Whether or not to annotate each bar with the height value
    annotate = kwargs.pop('annotate', False)

    show_ticks = kwargs.pop('show_ticks', False)

    # If no grid specified, don't draw one.
    grid = kwargs.pop('grid', None)

    cmap = kwargs.pop('cmap', False)
    if cmap:
        kwargs['edgecolor'] = almost_black
        if not stacked:
            kwargs['color'] = getcolors(cmap, height, 0)

    # Check if stacked and plot data accordingly
    color = kwargs.get('color', None)
    if stacked:
        num_stacks, num_data = height.shape
        bottom = np.zeros(num_data)
        for i in np.arange(num_stacks):
            lst = list(args)
            lst[1] = height[i]
            args = tuple(lst)
            # make sure number of user specified colors equals to the stacks 
            if not color or len(color) != num_stacks:
                if cmap:
                    kwargs['color'] = getcolors(cmap, height[i], i)
                else:
                    kwargs['color'] = set2[i]
            else:
                kwargs['color'] = color[i]
            kwargs['bottom'] = bottom
            rectangles = ax.bar(*args, **kwargs)
            bottom += height[i]
    else:
        rectangles = ax.bar(*args, **kwargs)
   
    # add legend
    if isinstance(legend, collections.Iterable):
        ax.legend(legend,loc='upper center',bbox_to_anchor=(0.5,1.11), ncol=5)

    # add whitespace padding on left
    xmin, xmax = ax.get_xlim()
    xmin -= 0.2
    if stacked:
        xmax = num_data
    ax.set_xlim(xmin, xmax)

    # If the user is only plotting one bar, make it an iterable
    if not isinstance(height, collections.Iterable):
        height = [height]


    # If there are negative counts, remove the bottom axes
    # and add a line at y=0
    if any(h < 0 for h in height.tolist()):
        axes_to_remove = ['top', 'right', 'bottom']
        ax.hlines(y=0, xmin=xmin, xmax=xmax,
                      linewidths=0.75)
    else:
        axes_to_remove = ['top', 'right']

    # Remove excess axes
    remove_chartjunk(ax, axes_to_remove, grid=grid, show_ticks=show_ticks)

    if stacked:
        data = height
        height = height.sum(axis=0)

    # Add the xticklabels if they are there
    if xtickabels is not None:
        ax.set_xticks(xticks)
        ax.set_xticklabels(xtickabels)

    if annotate or isinstance(annotate, collections.Iterable):
        annotate_yrange_factor = 0.025
        ymin, ymax = ax.get_ylim()
        yrange = ymax - ymin

        # Reset ymax and ymin so there's enough room to see the annotation of
        # the top-most
        if ymax > 0:
            ymax += yrange * 0.1
        if ymin < 0:
            ymin -= yrange * 0.1
        ax.set_ylim(ymin, ymax)
        yrange = ymax - ymin

        offset_ = yrange * annotate_yrange_factor
        if isinstance(annotate, collections.Iterable):
            annotations = map(str, annotate)
        else:
            annotations = ['%.3f' % h if type(h) is np.float_ else str(h)
                               for h in height]

        for x, h, annotation in zip(xticks, height, annotations):
            # Adjust the offset to account for negative bars
            offset = offset_ if h >= 0 else -1 * offset_
            verticalalignment = 'bottom' if h >= 0 else 'top'

            # Finally, add the text to the axes
            ax.annotate(annotation, (x, h + offset),
                        verticalalignment=verticalalignment,
                        horizontalalignment='center',
                        color=almost_black)

    # Text for each block of stack
    # This was partially inspired by the following article by Tableau software
    # http://www.tableausoftware.com/about/blog/2014/1/new-whitepaper-survey-data-less-ugly-more-understandable-27812
    if stack_text:
        bottom = np.zeros(num_data)
        max_h = max(height)
        for i in np.arange(num_stacks):
            for x, d, b in zip(xticks, data[i], bottom):
                if (d*100.0/max_h) > 4.0:
                    ax.text(x,b+d/2.0,d, ha='center', va='center', color=almost_black)
            bottom += data[i]
    return rectangles
Ejemplo n.º 20
0
def test_remove_chartjunk():
    fig, ax = plt.subplots(1)
    np.random.seed(14)
    ax.bar(np.arange(10), np.abs(np.random.randn(10)), color=set2[0],
           edgecolor='white')
    remove_chartjunk(ax, ['top', 'right'], grid='y', ticklabels='x')
Ejemplo n.º 21
0
def pcolormesh(*args, **kwargs):
    """
    Use for large datasets

    Non-traditional `pcolormesh` kwargs are:
    - xticklabels, which will put x tick labels exactly in the center of the
    heatmap block
    - yticklables, which will put y tick labels exactly aligned in the center
     of the heatmap block
     - xticklabels_rotation, which can be either 'horizontal' or 'vertical'
     depending on how you want the xticklabels rotated. The default is
     'horizontal', but if you have xticklabels that are longer, you may want
     to do 'vertical' so they don't overlap.
     - yticklabels_rotation, which can also be either 'horizontal' or
     'vertical'. The default is 'horizontal' and in most cases,
     that's what you'll want to stick with. But the option is there if you
     want.
    - center_value, which will be the centered value for a divergent
    colormap, for example if you have data above and below zero, but you want
    the white part of the colormap to be equal to 10 rather than 0,
    then specify 'center_value=10'.
    """
    # Deal with arguments in kwargs that should be there, or need to be taken
    #  out
    fig, ax, args, kwargs = maybe_get_fig_ax(*args, **kwargs)

    # If x and y axis are passed in arguments, gets correct data
    # Ticks will work with x and y data, although it would be pointless to use
    # both x/y and custom ticks
    if len(args) == 3:
        x = args[0]
        y = args[1]
        data = args[2]
    elif len(args) == 1:
        data = args[0]

    kwargs.setdefault('vmax', data.max())
    kwargs.setdefault('vmin', data.min())

    center_value = kwargs.pop('center_value', 0)

    # If
    divergent_data = False
    if kwargs['vmax'] > 0 and kwargs['vmin'] < 0:
        divergent_data = True
        kwargs['vmax'] += center_value
        kwargs['vmin'] += center_value

    # If we have both negative and positive values, use a divergent colormap
    if 'cmap' not in kwargs:
        # Check if this is divergent
        if divergent_data:
            kwargs['cmap'] = blue_red
        elif kwargs['vmax'] <= 0:
            kwargs['cmap'] = blues_r
        elif kwargs['vmax'] > 0:
            kwargs['cmap'] = reds

    if 'xticklabels' in kwargs:
        xticklabels = kwargs['xticklabels']
        kwargs.pop('xticklabels')
    else:
        xticklabels = None
    if 'yticklabels' in kwargs:
        yticklabels = kwargs['yticklabels']
        kwargs.pop('yticklabels')
    else:
        yticklabels = None

    if 'xticklabels_rotation' in kwargs:
        xticklabels_rotation = kwargs['xticklabels_rotation']
        kwargs.pop('xticklabels_rotation')
    else:
        xticklabels_rotation = 'horizontal'
    if 'yticklabels_rotation' in kwargs:
        yticklabels_rotation = kwargs['yticklabels_rotation']
        kwargs.pop('yticklabels_rotation')
    else:
        yticklabels_rotation = 'horizontal'

    ax_colorbar = kwargs.pop('ax_colorbar', None)
    orientation_colorbar = kwargs.pop('orientation_colorbar', 'vertical')

    p = ax.pcolormesh(*args, **kwargs)
    # ax.set_ylim(0, x.shape[0])
    # ax.set_xlim(0, x.shape[1])

    # Get rid of ALL axes
    remove_chartjunk(ax, ['top', 'right', 'left', 'bottom'])

    if xticklabels is not None and any(xticklabels):
        if len(args) == 1:
            xticks = np.arange(0.5, data.shape[1] + 0.5)
        else:
            xticks = []
            for i in np.arange(len(x) - 1):
                half = float(x[i + 1] - x[i]) / 2. + x[i]
                xticks.append(half)
        xticks = np.array(xticks)
        ax.set_xticks(xticks)
        ax.set_xticklabels(xticklabels, rotation=xticklabels_rotation)

    if yticklabels is not None and any(yticklabels):
        if len(args) == 1:
            yticks = np.arange(0.5, data.shape[1] + 0.5)
        else:
            yticks = []
            for i in np.arange(len(y) - 1):
                half = float(y[i + 1] - y[i]) / 2. + y[i]
                yticks.append(half)
        yticks = np.array(yticks)
        ax.set_yticks(yticks)
        ax.set_yticklabels(yticklabels, rotation=yticklabels_rotation)

    # Show the scale of the colorbar
    cbar = fig.colorbar(p, cax=ax_colorbar, use_gridspec=True,
                 orientation=orientation_colorbar)
    return p, cbar
Ejemplo n.º 22
0
def beeswarm(*args, **kwargs):
    """
    Create a R-like beeswarm plot showing the mean and datapoints. 
    The difference from matplotlib is only the left axis line is
    shown, and ticklabels labeling each category of data can be added.

    @param ax:
    @param x:
    @param kwargs: Besides xticklabels, which is a prettyplotlib-specific
    argument which will label each individual beeswarm, many arguments for
    matplotlib.pyplot.boxplot will be accepted:
    http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.boxplot
    Additional arguments include:
    
       *median_color* : (default gray)
        The color of median lines   
    
       *median_width* : (default 2)
        Median line width

       *colors* : (default None)
        Colors to use when painting a dataseries, for example
        
          list1 = [1,2,3]
          list2 = [5,6,7]
          ppl.beeswarm([list1, list2], colors=["red", "blue"], xticklabels=["data1", "data2"])

    @return:
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    # If no ticklabels are specified, don't draw any
    xticklabels = kwargs.pop('xticklabels', None)
    colors = kwargs.pop('colors', None)
    fontsize = kwargs.pop('fontsize', 10)
    
    gray = _colors.set1[8]
    red = _colors.set1[0]
    blue = kwargs.pop('color', _colors.set1[1])

    kwargs.setdefault('widths', 0.25)
    kwargs.setdefault('sym', "o")
    
    bp = _beeswarm(ax, *args, **kwargs)
    
    kwargs.setdefault("median_color", gray)
    kwargs.setdefault("median_linewidth", 2)
    
    
    if xticklabels:
        ax.xaxis.set_ticklabels(xticklabels, fontsize=fontsize)

    show_caps = kwargs.pop('show_caps', True)
    show_ticks = kwargs.pop('show_ticks', False)

    remove_chartjunk(ax, ['top', 'right', 'bottom'], show_ticks=show_ticks)
    linewidth = 0.75

    plt.setp(bp['boxes'], color=blue, linewidth=linewidth)
    plt.setp(bp['medians'], color=kwargs.pop("median_color"), linewidth=kwargs.pop("median_linewidth"))
    #plt.setp(bp['whiskers'], color=blue, linestyle='solid',
    #         linewidth=linewidth)
    for color, flier in zip(colors, bp['fliers']):
        plt.setp(flier, color=color)
    #if show_caps:
    #    plt.setp(bp['caps'], color=blue, linewidth=linewidth)
    #else:
    #    plt.setp(bp['caps'], color='none')
    ax.spines['left']._linewidth = 0.5
    return bp 
Ejemplo n.º 23
0
def beeswarm(*args, **kwargs):
    """
    Create a R-like beeswarm plot showing the mean and datapoints. 
    The difference from matplotlib is only the left axis line is
    shown, and ticklabels labeling each category of data can be added.

    @param ax:
    @param x:
    @param kwargs: Besides xticklabels, which is a prettyplotlib-specific
    argument which will label each individual beeswarm, many arguments for
    matplotlib.pyplot.boxplot will be accepted:
    http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.boxplot
    Additional arguments include:
    
       *median_color* : (default gray)
        The color of median lines   
    
       *median_width* : (default 2)
        Median line width

       *colors* : (default None)
        Colors to use when painting a dataseries, for example
        
          list1 = [1,2,3]
          list2 = [5,6,7]
          ppl.beeswarm([list1, list2], colors=["red", "blue"], xticklabels=["data1", "data2"])

    @return:
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    # If no ticklabels are specified, don't draw any
    xticklabels = kwargs.pop('xticklabels', None)
    colors = kwargs.pop('colors', None)
    fontsize = kwargs.pop('fontsize', 10)

    gray = _colors.set1[8]
    red = _colors.set1[0]
    blue = kwargs.pop('color', _colors.set1[1])

    kwargs.setdefault('widths', 0.25)
    kwargs.setdefault('sym', "o")

    bp = _beeswarm(ax, *args, **kwargs)

    kwargs.setdefault("median_color", gray)
    kwargs.setdefault("median_linewidth", 2)

    if xticklabels:
        ax.xaxis.set_ticklabels(xticklabels, fontsize=fontsize)

    show_caps = kwargs.pop('show_caps', True)
    show_ticks = kwargs.pop('show_ticks', False)

    remove_chartjunk(ax, ['top', 'right', 'bottom'], show_ticks=show_ticks)
    linewidth = 0.75

    plt.setp(bp['boxes'], color=blue, linewidth=linewidth)
    plt.setp(bp['medians'],
             color=kwargs.pop("median_color"),
             linewidth=kwargs.pop("median_linewidth"))
    #plt.setp(bp['whiskers'], color=blue, linestyle='solid',
    #         linewidth=linewidth)
    for color, flier in zip(colors, bp['fliers']):
        plt.setp(flier, color=color)
    #if show_caps:
    #    plt.setp(bp['caps'], color=blue, linewidth=linewidth)
    #else:
    #    plt.setp(bp['caps'], color='none')
    ax.spines['left']._linewidth = 0.5
    return bp
Ejemplo n.º 24
0
def pcolormesh(*args, **kwargs):
    """
    Use for large datasets

    Non-traditional `pcolormesh` kwargs are:
    - xticklabels, which will put x tick labels exactly in the center of the
    heatmap block
    - yticklables, which will put y tick labels exactly aligned in the center
     of the heatmap block
     - xticklabels_rotation, which can be either 'horizontal' or 'vertical'
     depending on how you want the xticklabels rotated. The default is
     'horizontal', but if you have xticklabels that are longer, you may want
     to do 'vertical' so they don't overlap.
     - yticklabels_rotation, which can also be either 'horizontal' or
     'vertical'. The default is 'horizontal' and in most cases,
     that's what you'll want to stick with. But the option is there if you
     want.
    - center_value, which will be the centered value for a divergent
    colormap, for example if you have data above and below zero, but you want
    the white part of the colormap to be equal to 10 rather than 0,
    then specify 'center_value=10'.
    """
    # Deal with arguments in kwargs that should be there, or need to be taken
    #  out
    fig, ax, args, kwargs = maybe_get_fig_ax(*args, **kwargs)

    x = args[0]

    kwargs.setdefault('vmax', x.max())
    kwargs.setdefault('vmin', x.min())

    center_value = kwargs.pop('center_value', 0)

    # If
    divergent_data = False
    if kwargs['vmax'] > 0 and kwargs['vmin'] < 0:
        divergent_data = True
        kwargs['vmax'] += center_value
        kwargs['vmin'] += center_value

    # If we have both negative and positive values, use a divergent colormap
    if 'cmap' not in kwargs:
        # Check if this is divergent
        if divergent_data:
            kwargs['cmap'] = blue_red
        elif kwargs['vmax'] <= 0:
            kwargs['cmap'] = blues_r
        elif kwargs['vmax'] > 0:
            kwargs['cmap'] = reds

    if 'xticklabels' in kwargs:
        xticklabels = kwargs['xticklabels']
        kwargs.pop('xticklabels')
    else:
        xticklabels = None
    if 'yticklabels' in kwargs:
        yticklabels = kwargs['yticklabels']
        kwargs.pop('yticklabels')
    else:
        yticklabels = None

    if 'xticklabels_rotation' in kwargs:
        xticklabels_rotation = kwargs['xticklabels_rotation']
        kwargs.pop('xticklabels_rotation')
    else:
        xticklabels_rotation = 'horizontal'
    if 'yticklabels_rotation' in kwargs:
        yticklabels_rotation = kwargs['yticklabels_rotation']
        kwargs.pop('yticklabels_rotation')
    else:
        yticklabels_rotation = 'horizontal'

    ax_colorbar = kwargs.pop('ax_colorbar', None)
    orientation_colorbar = kwargs.pop('orientation_colorbar', 'vertical')

    p = ax.pcolormesh(*args, **kwargs)
    ax.set_ylim(0, x.shape[0])

    # Get rid of ALL axes
    remove_chartjunk(ax, ['top', 'right', 'left', 'bottom'])

    if any(xticklabels):
        xticks = np.arange(0.5, x.shape[1] + 0.5)
        ax.set_xticks(xticks)
        ax.set_xticklabels(xticklabels, rotation=xticklabels_rotation)
    if any(yticklabels):
        yticks = np.arange(0.5, x.shape[0] + 0.5)
        ax.set_yticks(yticks)
        ax.set_yticklabels(yticklabels, rotation=yticklabels_rotation)

    # Show the scale of the colorbar
    fig.colorbar(p,
                 cax=ax_colorbar,
                 use_gridspec=True,
                 orientation=orientation_colorbar)
    return fig
Ejemplo n.º 25
0
def barh(*args, **kwargs):
    """
    Creates a bar plot, with white outlines and a fill color that defaults to
     the first teal-ish green in ColorBrewer's Set2. Optionally accepts
     grid='y' or grid='x' to draw a white grid over the bars,
     to show the scale. Almost like "erasing" some of the plot,
     but it adds more information!

    Can also add an annotation of the width of the barplots directly onto
    the bars with the `annotate` parameter, which can either be True,
    which will annotate the values, or a list of strings, which will annotate
    with the supplied strings.

    Can support stacked bars with the value of each stack shown on the stack
    (Added by Salil Banerjee)

    @param ax: matplotlib.axes instance
    @param top: Vector of values of where to put the top side of the bar
    @param width: Vector of values of the bar widths
    @param ytickabels: Vector of labels of the bar widths
    @param kwargs: Any additional arguments to matplotlib.bar()
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    if 'color' not in kwargs:
        kwargs['color'] = set2[0]
    if 'edgecolor' not in kwargs:
        kwargs['edgecolor'] = 'white'
    if 'width' in kwargs:
        # Find the middle of the bar
        middle = kwargs['width']/2.0
    else:
        middle = 0.4

    # Check if data contains stacks
    stacked = kwargs.pop('stacked',False)
    # Check if stack text should be included
    stack_text = kwargs.pop('stack_text',False)
    # Get legend if available
    legend = kwargs.pop('legend',False)

    top = args[0]
    width = np.array(args[1])

    # Label each individual bar, if xticklabels is provided
    ytickabels = kwargs.pop('yticklabels', None)
    # left+0.4 is the center of the bar
    yticks = np.array(top) + middle

    # Whether or not to annotate each bar with the width value
    annotate = kwargs.pop('annotate', False)

    # If no grid specified, don't draw one.
    grid = kwargs.pop('grid', None)

    # Check if stacked and plot data accordingly
    if stacked:
        num_stacks, num_data = width.shape
        left = np.zeros(num_data)
        for i in np.arange(num_stacks):
            lst = list(args)
            lst[1] = width[i]
            args = tuple(lst)
            kwargs['color'] = set2[i]
            kwargs['left'] = left
            rectangles = ax.barh(*args, **kwargs)
            left += width[i]
    else:
        rectangles = ax.barh(*args, **kwargs)

    # add legend
    if isinstance(legend, collections.Iterable):
        ax.legend(legend,loc='upper center',bbox_to_anchor=(0.5,1.11), ncol=5)

    # add whitespace padding on left
    ymin, ymax = ax.get_ylim()
    ymin -= 0.2
    if stacked:
        ymax = num_data
    ax.set_ylim(ymin, ymax)

    # If there are negative counts, remove the bottom axes
    # and add a line at y=0
    if any(w < 0 for w in width.tolist()):
        axes_to_remove = ['top', 'right', 'bottom']
        ax.vlines(x=0, ymin=ymin, ymax=ymax,
                  linewidths=0.75)
       #ax.hlines(y=0, xmin=xmin, xmax=xmax,
       #       linewidths=0.75)
    else:
        axes_to_remove = ['top', 'right']

    #Remove excess axes
    remove_chartjunk(ax, axes_to_remove, grid=grid)

    if stacked:
        data = width
        width = width.sum(axis=0)

    # Add the yticklabels if they are there
    if ytickabels is not None:
        ax.set_yticks(yticks)
        ax.set_yticklabels(ytickabels)

    if annotate or isinstance(annotate, collections.Iterable):
        annotate_xrange_factor = 0.050
        xmin, xmax = ax.get_xlim()
        xrange = xmax - xmin

        # Reset ymax and ymin so there's enough room to see the annotation of
        # the top-most
        if xmax > 0:
            xmax += xrange * 0.1
        if xmin < 0:
            xmin -= xrange * 0.1
        ax.set_xlim(xmin, xmax)
        xrange = xmax - xmin

        offset_ = xrange * annotate_xrange_factor
        if isinstance(annotate, collections.Iterable):
            annotations = map(str, annotate)
        else:
            annotations = ['%.3f' % w if type(w) is np.float_ else str(w)
                           for w in width]
        for y, w, annotation in zip(yticks, width, annotations):
            # Adjust the offset to account for negative bars
            offset = offset_ if w >= 0 else -1 * offset_
            # Finally, add the text to the axes
            ax.annotate(annotation, (w + offset, y),
                        verticalalignment='center',
                        horizontalalignment='center',
                        color=almost_black)

    # Text for each block of stack
    # This was partially inspired by the following article by Tableau software
    # http://www.tableausoftware.com/about/blog/2014/1/new-whitepaper-survey-data-less-ugly-more-understandable-27812
    if stack_text:
        left = np.zeros(num_data)
        max_w = max(width)
        for i in np.arange(num_stacks):
            for y, d, l in zip(yticks, data[i], left):
                if (d*100.0/max_w) > 2.0:
                    ax.text(l+d/2.0,y,d, ha='center', va='center', color=almost_black)
            left += data[i]

    return rectangles
Ejemplo n.º 26
0
def pcolormesh(*args, **kwargs):
    """
    Use for large datasets

    Non-traditional `pcolormesh` kwargs are:
    - xticklabels, which will put x tick labels exactly in the center of the
    heatmap block
    - yticklables, which will put y tick labels exactly aligned in the center
     of the heatmap block
     - xticklabels_rotation, which can be either 'horizontal' or 'vertical'
     depending on how you want the xticklabels rotated. The default is
     'horizontal', but if you have xticklabels that are longer, you may want
     to do 'vertical' so they don't overlap.
     - yticklabels_rotation, which can also be either 'horizontal' or
     'vertical'. The default is 'horizontal' and in most cases,
     that's what you'll want to stick with. But the option is there if you
     want.
    - center_value, which will be the centered value for a divergent
    colormap, for example if you have data above and below zero, but you want
    the white part of the colormap to be equal to 10 rather than 0,
    then specify 'center_value=10'.
    """
    # Deal with arguments in kwargs that should be there, or need to be taken
    #  out
    fig, ax, args, kwargs = maybe_get_fig_ax(*args, **kwargs)

    x = args[0]

    if 'vmax' not in kwargs:
        kwargs['vmax'] = x.max()
    if 'vmin' not in kwargs:
        kwargs['vmin'] = x.min()

    center_value = kwargs.pop('center_value', 0)

    # If
    divergent_data = False
    if kwargs['vmax'] > 0 and kwargs['vmin'] < 0:
        divergent_data = True
        kwargs['vmax'] += center_value
        kwargs['vmin'] += center_value

    # If we have both negative and positive values, use a divergent colormap
    if 'cmap' not in kwargs:
        # Check if this is divergent
        if divergent_data:
            kwargs['cmap'] = blue_red
        elif kwargs['vmax'] <= 0:
                kwargs['cmap'] = blues_r
        elif kwargs['vmax'] > 0:
            kwargs['cmap'] = reds

    if 'xticklabels' in kwargs:
        xticklabels = kwargs['xticklabels']
        kwargs.pop('xticklabels')
    else:
        xticklabels = None
    if 'yticklabels' in kwargs:
        yticklabels = kwargs['yticklabels']
        kwargs.pop('yticklabels')
    else:
        yticklabels = None

    if 'xticklabels_rotation' in kwargs:
        xticklabels_rotation = kwargs['xticklabels_rotation']
        kwargs.pop('xticklabels_rotation')
    else:
        xticklabels_rotation = 'horizontal'
    if 'yticklabels_rotation' in kwargs:
        yticklabels_rotation = kwargs['yticklabels_rotation']
        kwargs.pop('yticklabels_rotation')
    else:
        yticklabels_rotation = 'horizontal'

    ax_colorbar = kwargs.pop('ax_colorbar', None)
    orientation_colorbar = kwargs.pop('orientation_colorbar', 'vertical')

    p = ax.pcolormesh(*args, **kwargs)
    ax.set_ylim(0, x.shape[0])

    # Get rid of ALL axes
    remove_chartjunk(ax, ['top', 'right', 'left', 'bottom'])

    if xticklabels:
        xticks = np.arange(0.5, x.shape[1] + 0.5)
        ax.set_xticks(xticks)
        ax.set_xticklabels(xticklabels, rotation=xticklabels_rotation)
    if yticklabels:
        yticks = np.arange(0.5, x.shape[0] + 0.5)
        ax.set_yticks(yticks)
        ax.set_yticklabels(yticklabels, rotation=yticklabels_rotation)

    # Show the scale of the colorbar
    fig.colorbar(p, cax=ax_colorbar, use_gridspec=True,
                 orientation=orientation_colorbar)
    return fig
Ejemplo n.º 27
0
def barh(*args, **kwargs):
    """
    Creates a bar plot, with white outlines and a fill color that defaults to
     the first teal-ish green in ColorBrewer's Set2. Optionally accepts
     grid='y' or grid='x' to draw a white grid over the bars,
     to show the scale. Almost like "erasing" some of the plot,
     but it adds more information!

    Can also add an annotation of the width of the barplots directly onto
    the bars with the `annotate` parameter, which can either be True,
    which will annotate the values, or a list of strings, which will annotate
    with the supplied strings.

    Can support stacked bars with the value of each stack shown on the stack
    (Added by Salil Banerjee)

    @param ax: matplotlib.axes instance
    @param top: Vector of values of where to put the top side of the bar
    @param width: Vector of values of the bar widths
    @param ytickabels: Vector of labels of the bar widths
    @param kwargs: Any additional arguments to matplotlib.bar()
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)
    if 'color' not in kwargs:
        kwargs['color'] = set2[0]
    if 'edgecolor' not in kwargs:
        kwargs['edgecolor'] = 'white'
    if 'width' in kwargs:
        # Find the middle of the bar
        middle = kwargs['width'] / 2.0
    else:
        middle = 0.4

    # Check if data contains stacks
    stacked = kwargs.pop('stacked', False)
    # Check if stack text should be included
    stack_text = kwargs.pop('stack_text', False)
    # Get legend if available
    legend = kwargs.pop('legend', False)

    top = args[0]
    width = np.array(args[1])

    # Label each individual bar, if xticklabels is provided
    ytickabels = kwargs.pop('yticklabels', None)
    # left+0.4 is the center of the bar
    yticks = np.array(top) + middle

    # Whether or not to annotate each bar with the width value
    annotate = kwargs.pop('annotate', False)

    # If no grid specified, don't draw one.
    grid = kwargs.pop('grid', None)

    # Check if stacked and plot data accordingly
    if stacked:
        num_stacks, num_data = width.shape
        left = np.zeros(num_data)
        for i in np.arange(num_stacks):
            lst = list(args)
            lst[1] = width[i]
            args = tuple(lst)
            kwargs['color'] = set2[i]
            kwargs['left'] = left
            rectangles = ax.barh(*args, **kwargs)
            left += width[i]
    else:
        rectangles = ax.barh(*args, **kwargs)

    # add legend
    if isinstance(legend, collections.Iterable):
        ax.legend(legend,
                  loc='upper center',
                  bbox_to_anchor=(0.5, 1.11),
                  ncol=5)

    # add whitespace padding on left
    ymin, ymax = ax.get_ylim()
    ymin -= 0.2
    if stacked:
        ymax = num_data
    ax.set_ylim(ymin, ymax)

    # If there are negative counts, remove the bottom axes
    # and add a line at y=0
    if any(w < 0 for w in width.tolist()):
        axes_to_remove = ['top', 'right', 'bottom']
        ax.vlines(x=0, ymin=ymin, ymax=ymax, linewidths=0.75)
    #ax.hlines(y=0, xmin=xmin, xmax=xmax,
    #       linewidths=0.75)
    else:
        axes_to_remove = ['top', 'right']

    #Remove excess axes
    remove_chartjunk(ax, axes_to_remove, grid=grid)

    if stacked:
        data = width
        width = width.sum(axis=0)

    # Add the yticklabels if they are there
    if ytickabels is not None:
        ax.set_yticks(yticks)
        ax.set_yticklabels(ytickabels)

    if annotate or isinstance(annotate, collections.Iterable):
        annotate_xrange_factor = 0.050
        xmin, xmax = ax.get_xlim()
        xrange = xmax - xmin

        # Reset ymax and ymin so there's enough room to see the annotation of
        # the top-most
        if xmax > 0:
            xmax += xrange * 0.1
        if xmin < 0:
            xmin -= xrange * 0.1
        ax.set_xlim(xmin, xmax)
        xrange = xmax - xmin

        offset_ = xrange * annotate_xrange_factor
        if isinstance(annotate, collections.Iterable):
            annotations = map(str, annotate)
        else:
            annotations = [
                '%.3f' % w if type(w) is np.float_ else str(w) for w in width
            ]
        for y, w, annotation in zip(yticks, width, annotations):
            # Adjust the offset to account for negative bars
            offset = offset_ if w >= 0 else -1 * offset_
            # Finally, add the text to the axes
            ax.annotate(annotation, (w + offset, y),
                        verticalalignment='center',
                        horizontalalignment='center',
                        color=almost_black)

    # Text for each block of stack
    # This was partially inspired by the following article by Tableau software
    # http://www.tableausoftware.com/about/blog/2014/1/new-whitepaper-survey-data-less-ugly-more-understandable-27812
    if stack_text:
        left = np.zeros(num_data)
        max_w = max(width)
        for i in np.arange(num_stacks):
            for y, d, l in zip(yticks, data[i], left):
                if (d * 100.0 / max_w) > 2.0:
                    ax.text(l + d / 2.0,
                            y,
                            d,
                            ha='center',
                            va='center',
                            color=almost_black)
            left += data[i]

    return rectangles