Index: axes.py
===================================================================
--- axes.py	(revision 8196)
+++ axes.py	(working copy)
@@ -6975,6 +6975,172 @@
         ax2.yaxis.set_visible(False)
         return ax2
 
+    def breakx(self, xbounds, break_frac=0.02, cross_frac=0.008):
+        """
+        call signature::
+
+          left, right = ax.breakx([xmin1, xmax1, xmin2, xmax2])
+          ax1, ax2, ... = ax.breakx([xmin1, xmax1, xmin2, xmax2, ...])
+
+        replace the content of the current axes with a set of subaxes with
+        breakmarks between them.  The subaxes all share the main y-axis, but
+        have different x-axes, with limits defined by xbounds.
+
+        break_frac determines what fraction of the axes width a breakmark
+        takes up, while cross_frac determines how far into the axes the
+        breakmark extends.
+
+        **TODO**: figure out a way to push the x-axis label of the main axes
+        out far enough to clear the tick labels on the subaxes.
+        
+        **TODO**: if the fractions taken up by the subaxes are significantly
+        different, then they may not all have equivalent tick marks, so we need
+        a way to ensure uniform tick mark spacing across subaxes.
+        """
+
+        if len(xbounds) % 2 != 0:
+            raise ValueError("xbounds cannot be of odd length")
+
+        def add_breakmarks(axes, position, break_frac, cross_frac):
+            x1, y1, x2, y2 = axes.get_position().get_points().flatten().tolist()
+            segment_frac = break_frac * (x2 - x1) / 3.
+            yoffsets = [0, +cross_frac, -cross_frac, 0]
+            xvalues  = [position - (i * segment_frac) for i in range(4)]
+            for loc, spine in axes.spines.iteritems():
+                if loc  == 'bottom':
+                    color = spine.get_edgecolor()
+            for y_position in [y1, y2]:
+                line = matplotlib.lines.Line2D(
+                    xvalues, [y_position + offset for offset in yoffsets],
+                    transform=axes.figure.transFigure,
+                    clip_on=False, solid_capstyle='butt', color=color)
+                axes.add_line(line)
+
+        x1, y1, x2, y2 = self.get_position().get_points().flatten().tolist()
+        height = y2 - y1
+        xmins = xbounds[0::2]
+        xmaxs = xbounds[1::2]
+        naxes = len(xmins)
+        nbreaks = naxes - 1
+        widths_data = [float(xmaxs[i] - xmins[i]) for i in range(naxes)]
+
+        subaxes = []
+        lower_bounds = []
+        lower_bound = x1
+        for i in range(naxes):
+            width_frac = widths_data[i] / sum(widths_data)
+            width_figure = (x2 - x1) * width_frac * (1 - nbreaks * break_frac)
+            width_axes = width_figure / (x2 - x1)
+            axes = Axes(self.figure, [lower_bound, y1, width_figure, height],
+                        axisbg='None', sharey=self)
+            subaxes.append(axes)
+            self.figure.add_axes(axes)
+            lower_bound += (width_figure + (x2 - x1) * break_frac)
+            lower_bounds.append(lower_bound)
+            axes.set_xlim(xmins[i], xmaxs[i])
+            axes.set_autoscalex_on(False)
+            axes.get_yaxis().set_ticks_position('none')
+            for label in axes.get_yticklabels():
+                label.set_visible(False)
+            for loc, spine in axes.spines.iteritems():
+                if loc in ['left', 'right']:
+                    spine.set_color('none')
+                    
+        for i in range(nbreaks):
+            add_breakmarks(self, lower_bounds[i], break_frac, cross_frac)
+
+        # Make self invisible
+        self.set_xticks([])
+        for loc, spine in self.spines.iteritems():
+            if loc in ['top', 'bottom']:
+                spine.set_color('none')
+        self.set_axis_bgcolor('None')
+
+        return subaxes
+
+    def breaky(self, ybounds, break_frac=0.02, cross_frac=0.008):
+        """
+        call signature::
+
+          upper, lower = ax.breaky([ymin1, ymax1, ymin2, ymax2])
+          ax1, ax2, ... = ax.breaky([ymin1, ymax1, ymin2, ymax2, ...])
+
+        replace the content of the current axes with a set of subaxes with
+        breakmarks between them.  The subaxes all share the main x-axis, but
+        have different y-axes, with limits defined by ybounds.
+
+        break_frac determines what fraction of the axes height a breakmark
+        takes up, while cross_frac determines how far into the axes the
+        breakmark extends.
+
+        **TODO**: figure out a way to push the y-axis label of the main axes
+        out far enough to clear the tick labels on the subaxes.
+        
+        **TODO**: if the fractions taken up by the subaxes are significantly
+        different, then they may not all have equivalent tick marks, so we need
+        a way to ensure uniform tick mark spacing across subaxes.
+        """
+
+        if len(ybounds) % 2 != 0:
+            raise ValueError("ybounds cannot be of odd length")
+
+        def add_breakmarks(axes, position, break_frac, cross_frac):
+            x1, y1, x2, y2 = axes.get_position().get_points().flatten().tolist()
+            segment_frac = break_frac * (y2 - y1) / 3.
+            xoffsets = [0, +cross_frac, -cross_frac, 0]
+            yvalues  = [position - (i * segment_frac) for i in range(4)]
+            for loc, spine in axes.spines.iteritems():
+                if loc  == 'left':
+                    color = spine.get_edgecolor()
+            for x_position in [x1, x2]:
+                line = matplotlib.lines.Line2D(
+                    [x_position + offset for offset in xoffsets], yvalues,
+                    transform=axes.figure.transFigure,
+                    clip_on=False, solid_capstyle='butt', color=color)
+                axes.add_line(line)
+
+        x1, y1, x2, y2 = self.get_position().get_points().flatten().tolist()
+        width = x2 - x1
+        ymins = ybounds[0::2]
+        ymaxs = ybounds[1::2]
+        naxes = len(ymins)
+        nbreaks = naxes - 1
+        heights_data = [float(ymaxs[i] - ymins[i]) for i in range(naxes)]
+
+        subaxes = []
+        lower_bounds = []
+        lower_bound = y1
+        for i in range(naxes):
+            height_frac = heights_data[i] / sum(heights_data)
+            height_figure = (y2 - y1) * height_frac * (1 - nbreaks * break_frac)
+            height_axes = height_figure / (y2 - y1)
+            axes = Axes(self.figure, [x1, lower_bound, width, height_figure],
+                        axisbg='None', sharex=self)
+            subaxes.append(axes)
+            self.figure.add_axes(axes)
+            lower_bound += (height_figure + (y2 - y1) * break_frac)
+            lower_bounds.append(lower_bound)
+            axes.set_ylim(ymins[i], ymaxs[i])
+            axes.set_autoscaley_on(False)
+            axes.get_xaxis().set_ticks_position('none')
+            for label in axes.get_xticklabels():
+                label.set_visible(False)
+            for loc, spine in axes.spines.iteritems():
+                if loc in ['top', 'bottom']:
+                    spine.set_color('none')
+                    
+        for i in range(nbreaks):
+            add_breakmarks(self, lower_bounds[i], break_frac, cross_frac)
+
+        # Make self invisible
+        self.set_yticks([])
+        for loc, spine in self.spines.iteritems():
+            if loc in ['left', 'right']:
+                spine.set_color('none')
+        self.set_axis_bgcolor('None')
+
+        return subaxes
+
     def get_shared_x_axes(self):
         'Return a copy of the shared axes Grouper object for x axes'
         return self._shared_x_axes
