Calculate boundaries of geometry object

        Uses Strategy

def collide(cls, data, params):
        """
        Calculate boundaries of geometry object

        Uses Strategy
        """
        xminmax = ['xmin', 'xmax']
        data, width = cls._collide_setup(data, params)
        if params.get('width', None) is None:
            params['width'] = width

        # Reorder by x position then on group, relying on stable sort to
        # preserve existing ordering. The default stacking order reverses
        # the group in order to match the legend order.
        if params and 'reverse' in params and params['reverse']:
            idx = data.sort_values(
                ['xmin', 'group'], kind='mergesort').index
        else:
            data['-group'] = -data['group']
            idx = data.sort_values(
                ['xmin', '-group'], kind='mergesort').index
            del data['-group']

        data = data.loc[idx, :]

        # Check for overlap
        intervals = data[xminmax].drop_duplicates().values.flatten()
        intervals = intervals[~np.isnan(intervals)]

        if (len(np.unique(intervals)) > 1 and
                any(np.diff(intervals - intervals.mean()) < -1e-6)):
            msg = "{} requires non-overlapping x intervals"
            warn(msg.format(cls.__name__), PlotnineWarning)

        if 'ymax' in data:
            data = groupby_apply(data, 'xmin', cls.strategy, params)
        elif 'y' in data:
            data['ymax'] = data['y']
            data = groupby_apply(data, 'xmin', cls.strategy, params)
            data['y'] = data['ymax']
        else:
            raise PlotnineError('Neither y nor ymax defined')

        return data