# Integrating with duck arrays

Warning

This is a experimental feature.

Xarray can wrap custom duck array objects as long as they define numpy’s `shape`, `dtype` and `ndim` properties and the `__array__`, `__array_ufunc__` and `__array_function__` methods.

In certain situations (e.g. when printing the collapsed preview of variables of a `Dataset`), xarray will display the repr of a duck array in a single line, truncating it to a certain number of characters. If that would drop too much information, the duck array may define a `_repr_inline_` method that takes `max_width` (number of characters) as an argument:

    class MyDuckArray:
        ...

        def _repr_inline_(self, max_width):
            """format to a single line with at most max_width characters"""
            ...

        ...

To avoid duplicated information, this method must omit information about the shape and dtype. For example, the string representation of a `dask` array or a `sparse` matrix would be:

    In [1]: import dask.array as da

    In [2]: import xarray as xr

    In [3]: import sparse
    ---------------------------------------------------------------------------
    ModuleNotFoundError                       Traceback (most recent call last)
    <ipython-input-3-5d03fa13bb7b> in <module>
    ----> 1 import sparse

    ModuleNotFoundError: No module named 'sparse'

    In [4]: a = da.linspace(0, 1, 20, chunks=2)

    In [5]: a
    Out[5]: dask.array<linspace, shape=(20,), dtype=float64, chunksize=(2,), chunktype=numpy.ndarray>

    In [6]: b = np.eye(10)

    In [7]: b[[5, 7, 3, 0], [6, 8, 2, 9]] = 2

    In [8]: b = sparse.COO.from_numpy(b)
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-8-18c3e8fce5d8> in <module>
    ----> 1 b = sparse.COO.from_numpy(b)

    NameError: name 'sparse' is not defined

    In [9]: b
    Out[9]:
    array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 2.],
           [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
           [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
           [0., 0., 2., 1., 0., 0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0., 1., 2., 0., 0., 0.],
           [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
           [0., 0., 0., 0., 0., 0., 0., 1., 2., 0.],
           [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
           [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]])

    In [10]: xr.Dataset(dict(a=("x", a), b=(("y", "z"), b)))
    Out[10]:
    <xarray.Dataset>
    Dimensions:  (x: 20, y: 10, z: 10)
    Dimensions without coordinates: x, y, z
    Data variables:
        a        (x) float64 dask.array<chunksize=(2,), meta=np.ndarray>
        b        (y, z) float64 1.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 1.0