def get_agg_data(cls, obj, category=None):
        """
        Reduces any Overlay or NdOverlay of Elements into a single
        xarray Dataset that can be aggregated.
        """
        paths = []
        if isinstance(obj, Graph):
            obj = obj.edgepaths
        kdims = list(obj.kdims)
        vdims = list(obj.vdims)
        dims = obj.dimensions()[:2]
        if isinstance(obj, Path):
            glyph = 'line'
            for p in obj.split(datatype='dataframe'):
                paths.append(p)
        elif isinstance(obj, CompositeOverlay):
            element = None
            for key, el in obj.data.items():
                x, y, element, glyph = cls.get_agg_data(el)
                dims = (x, y)
                df = PandasInterface.as_dframe(element)
                if isinstance(obj, NdOverlay):
                    df = df.assign(**dict(zip(obj.dimensions('key', True), key)))
                paths.append(df)
            if element is None:
                dims = None
            else:
                kdims += element.kdims
                vdims = element.vdims
        elif isinstance(obj, Element):
            glyph = 'line' if isinstance(obj, Curve) else 'points'
            paths.append(PandasInterface.as_dframe(obj))

        if dims is None or len(dims) != 2:
            return None, None, None, None
        else:
            x, y = dims

        if len(paths) > 1:
            if glyph == 'line':
                path = paths[0][:1]
                if isinstance(path, dd.DataFrame):
                    path = path.compute()
                empty = path.copy()
                empty.iloc[0, :] = (np.NaN,) * empty.shape[1]
                paths = [elem for p in paths for elem in (p, empty)][:-1]
            if all(isinstance(path, dd.DataFrame) for path in paths):
                df = dd.concat(paths)
            else:
                paths = [p.compute() if isinstance(p, dd.DataFrame) else p for p in paths]
                df = pd.concat(paths)
        else:
            df = paths[0] if paths else pd.DataFrame([], columns=[x.name, y.name])
        if category and df[category].dtype.name != 'category':
            df[category] = df[category].astype('category')

        is_dask = isinstance(df, dd.DataFrame)
        if any((not is_dask and len(df[d.name]) and isinstance(df[d.name].values[0], cftime_types)) or
               df[d.name].dtype.kind == 'M' for d in (x, y)):
            df = df.copy()

        for d in (x, y):
            vals = df[d.name]
            if not is_dask and len(vals) and isinstance(vals.values[0], cftime_types):
                vals = cftime_to_timestamp(vals, 'ns')
            elif df[d.name].dtype.kind == 'M':
                vals = vals.astype('datetime64[ns]')
            else:
                continue
            df[d.name] = vals.astype('int64')
        return x, y, Dataset(df, kdims=kdims, vdims=vdims), glyph
def get_agg_data ( cls , obj , category = None ) : paths = [ ] if isinstance ( obj , Graph ) : obj = obj . edgepaths kdims = list ( obj . kdims ) vdims = list ( obj . vdims ) dims = obj . dimensions ( ) [ : 2 ] if isinstance ( obj , Path ) : glyph = 'line' for p in obj . split ( datatype = 'dataframe' ) : paths . append ( p ) elif isinstance ( obj , CompositeOverlay ) : element = None for key , el in obj . data . items ( ) : x , y , element , glyph = cls . get_agg_data ( el ) dims = ( x , y ) df = PandasInterface . as_dframe ( element ) if isinstance ( obj , NdOverlay ) : df = df . assign ( ** dict ( zip ( obj . dimensions ( 'key' , True ) , key ) ) ) paths . append ( df ) if element is None : dims = None else : kdims += element . kdims vdims = element . vdims elif isinstance ( obj , Element ) : glyph = 'line' if isinstance ( obj , Curve ) else 'points' paths . append ( PandasInterface . as_dframe ( obj ) ) if dims is None or len ( dims ) != 2 : return None , None , None , None else : x , y = dims if len ( paths ) > 1 : if glyph == 'line' : path = paths [ 0 ] [ : 1 ] if isinstance ( path , dd . DataFrame ) : path = path . compute ( ) empty = path . copy ( ) empty . iloc [ 0 , : ] = ( np . NaN , ) * empty . shape [ 1 ] paths = [ elem for p in paths for elem in ( p , empty ) ] [ : - 1 ] if all ( isinstance ( path , dd . DataFrame ) for path in paths ) : df = dd . concat ( paths ) else : paths = [ p . compute ( ) if isinstance ( p , dd . DataFrame ) else p for p in paths ] df = pd . concat ( paths ) else : df = paths [ 0 ] if paths else pd . DataFrame ( [ ] , columns = [ x . name , y . name ] ) if category and df [ category ] . dtype . name != 'category' : df [ category ] = df [ category ] . astype ( 'category' ) is_dask = isinstance ( df , dd . DataFrame ) if any ( ( not is_dask and len ( df [ d . name ] ) and isinstance ( df [ d . name ] . values [ 0 ] , cftime_types ) ) or df [ d . name ] . dtype . kind == 'M' for d in ( x , y ) ) : df = df . copy ( ) for d in ( x , y ) : vals = df [ d . name ] if not is_dask and len ( vals ) and isinstance ( vals . values [ 0 ] , cftime_types ) : vals = cftime_to_timestamp ( vals , 'ns' ) elif df [ d . name ] . dtype . kind == 'M' : vals = vals . astype ( 'datetime64[ns]' ) else : continue df [ d . name ] = vals . astype ( 'int64' ) return x , y , Dataset ( df , kdims = kdims , vdims = vdims ) , glyph
Reduces any Overlay or NdOverlay of Elements into a single
        xarray Dataset that can be aggregated.