'Called when the mouse moves during a pan operation.
*button* is the mouse button number:
* 1: LEFT
* 2: MIDDLE
* 3: RIGHT
*key* is a "shift" key
*x*, *y* are the mouse coordinates in display coords.
.. note::
Intended to be overridden by new projection types.'

def drag_pan(self, button, key, x, y):

    def format_deltas(key, dx, dy):
        if (key == u'control'):
            if (abs(dx) > abs(dy)):
                dy = dx
            else:
                dx = dy
        elif (key == u'x'):
            dy = 0
        elif (key == u'y'):
            dx = 0
        elif (key == u'shift'):
            if ((2 * abs(dx)) < abs(dy)):
                dx = 0
            elif ((2 * abs(dy)) < abs(dx)):
                dy = 0
            elif (abs(dx) > abs(dy)):
                dy = ((dy / abs(dy)) * abs(dx))
            else:
                dx = ((dx / abs(dx)) * abs(dy))
        return (dx, dy)
    p = self._pan_start
    dx = (x - p.x)
    dy = (y - p.y)
    if ((dx == 0) and (dy == 0)):
        return
    if (button == 1):
        (dx, dy) = format_deltas(key, dx, dy)
        result = p.bbox.translated((- dx), (- dy)).transformed(p.trans_inverse)
    elif (button == 3):
        try:
            dx = ((- dx) / float(self.bbox.width))
            dy = ((- dy) / float(self.bbox.height))
            (dx, dy) = format_deltas(key, dx, dy)
            if (self.get_aspect() != u'auto'):
                dx = (0.5 * (dx + dy))
                dy = dx
            alpha = np.power(10.0, (dx, dy))
            start = np.array([p.x, p.y])
            oldpoints = p.lim.transformed(p.trans)
            newpoints = (start + (alpha * (oldpoints - start)))
            result = mtransforms.Bbox(newpoints).transformed(p.trans_inverse)
        except OverflowError:
            warnings.warn(u'Overflow    while    panning')
            return
    self.set_xlim(*result.intervalx)
    self.set_ylim(*result.intervaly)
