Skip to content

Commit

Permalink
docs (#48)
Browse files Browse the repository at this point in the history
* docs

* update isort call.

* update pre-commit

* fix isort
  • Loading branch information
dcherian authored Jul 6, 2020
1 parent a562c57 commit 9d53560
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ jobs:
python -m pip install isort
- name: isort check
run: |
isort --recursive --check-only .
isort --check-only .
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
repos:
# isort should run before black as black sometimes tweaks the isort output
- repo: https://github.com/timothycrosley/isort
rev: 4.3.21-2
rev: 5.0.4
hooks:
- id: isort
files: .+\.py$
Expand All @@ -16,7 +16,7 @@ repos:
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.781 # Must match ci/requirements/*.yml
rev: v0.782 # Must match ci/requirements/*.yml
hooks:
- id: mypy
# run this occasionally, ref discussion https://github.com/pydata/xarray/pull/3194
Expand Down
100 changes: 89 additions & 11 deletions cf_xarray/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ def _get_axis_coord(
Parameters
----------
var : DataArray, Dataset
var: DataArray, Dataset
DataArray belonging to the coordinate to be checked
key : str, ["X", "Y", "Z", "T", "longitude", "latitude", "vertical", "time"]
key: str, ["X", "Y", "Z", "T", "longitude", "latitude", "vertical", "time"]
key to check for.
error : bool
error: bool
raise errors when key is not found or interpretable. Use False and provide default
to replicate dict.get(k, None).
default: Any
Expand Down Expand Up @@ -217,7 +217,24 @@ def _get_measure(
da: xr.DataArray, key: str, error: bool = True, default: str = None
) -> Optional[str]:
"""
Interprets 'cell_measures'.
Translate from cell measures ("area" or "volume") to appropriate variable name.
This function interprets the ``cell_measures`` attribute on DataArrays.
Parameters
----------
da: DataArray
DataArray belonging to the coordinate to be checked
key: str, ["area", "volume"]
key to check for.
error: bool
raise errors when key is not found or interpretable. Use False and provide default
to replicate dict.get(k, None).
default: Any
default value to return when error is False.
Returns
-------
List[str], Variable name(s) in parent xarray object that matches axis or coordinate `key`
"""
if not isinstance(da, DataArray):
raise NotImplementedError("Measures not implemented for Datasets yet.")
Expand Down Expand Up @@ -254,6 +271,9 @@ def _get_measure(


#: Default mappers for common keys.
# TODO: Make the values of this a tuple,
# so that multiple mappers can be used for a single key
# We need this for groupby("T.month") and groupby("latitude") for example.
_DEFAULT_KEY_MAPPERS: Mapping[str, Mapper] = {
"dim": _get_axis_coord,
"dims_or_levels": _get_axis_coord, # reset_index
Expand All @@ -280,7 +300,19 @@ def _filter_by_standard_names(ds: xr.Dataset, name: Union[str, List[str]]) -> Li


def _get_list_standard_names(obj: xr.Dataset) -> List[str]:
""" Returns a sorted list of standard names in Dataset. """
"""
Returns a sorted list of standard names in Dataset.
Parameters
----------
obj: DataArray, Dataset
Xarray objec to process
Returns
-------
list of standard names in dataset
"""
names = []
for k, v in obj.variables.items():
if "standard_name" in v.attrs:
Expand Down Expand Up @@ -332,15 +364,18 @@ def wrapper(*args, **kwargs):


class _CFWrappedClass:
"""
This class is used to wrap any class in _WRAPPED_CLASSES.
"""

def __init__(self, towrap, accessor: "CFAccessor"):
"""
This class is used to wrap any class in _WRAPPED_CLASSES.
Parameters
----------
towrap : Resample, GroupBy, Coarsen, Rolling, Weighted
Instance of xarray class that is being wrapped.
accessor : CFAccessor
Parent accessor object
"""
self.wrapped = towrap
self.accessor = accessor
Expand Down Expand Up @@ -369,7 +404,10 @@ def __init__(self, obj, accessor):

def _plot_decorator(self, func):
"""
This decorator is used to set kwargs on plotting functions.
This decorator is used to set default kwargs on plotting functions.
For now, this is setting ``xincrease`` and ``yincrease``. It could set
other arguments in the future.
"""
valid_keys = self.accessor.get_valid_keys()

Expand Down Expand Up @@ -402,6 +440,9 @@ def _plot_wrapper(*args, **kwargs):
return _plot_wrapper

def __call__(self, *args, **kwargs):
"""
Allows .plot()
"""
plot = _getattr(
obj=self._obj,
attr="plot",
Expand All @@ -411,6 +452,9 @@ def __call__(self, *args, **kwargs):
return self._plot_decorator(plot)(*args, **kwargs)

def __getattr__(self, attr):
"""
Wraps .plot.contour() for example.
"""
return _getattr(
obj=self._obj.plot,
attr=attr,
Expand All @@ -423,10 +467,21 @@ def __getattr__(self, attr):


class CFAccessor:
"""
Common Dataset and DataArray accessor functionality.
"""

def __init__(self, da):
self._obj = da

def _process_signature(self, func, args, kwargs, key_mappers):
def _process_signature(self, func: Callable, args, kwargs, key_mappers):
"""
Processes a function's signature, args, kwargs:
1. Binds *args so that everthing is a Mapping from kwarg name to values
2. Calls _rewrite_values to rewrite any special CF names to normal xarray names.
This uses key_mappers
3. Unpacks arguments if necessary before returning them.
"""
sig = inspect.signature(func, follow_wrapped=False)

# Catch things like .isel(T=5).
Expand Down Expand Up @@ -456,7 +511,24 @@ def _process_signature(self, func, args, kwargs, key_mappers):
return arguments

def _rewrite_values(self, kwargs, key_mappers: dict, var_kws):
""" rewrites 'dim' for example using 'mapper' """
"""
Rewrites the values in a Mapping from kwarg to value.
Parameters
----------
kwargs: Mapping
Mapping from kwarg name to value
key_mappers: Mapping
Mapping from kwarg name to a Mapper function that will convert a
given CF "special" name to an xarray name.
var_kws: List[str]
List of variable kwargs that need special treatment.
e.g. **indexers_kwargs in isel
Returns
-------
dict of kwargs with fully rewritten values.
"""
updates: dict = {}

# allow multiple return values here.
Expand Down Expand Up @@ -558,11 +630,17 @@ def _describe(self):
return text

def describe(self):
"""
Print a string repr to screen.
"""
print(self._describe())

def get_valid_keys(self) -> Set[str]:
"""
Returns valid keys for .cf[]
Utility function that returns valid keys for .cf[].
This is useful for checking whether a key is valid for indexing, i.e.
that the attributes necessary to allow indexing by that key exist.
Returns
-------
Expand Down
2 changes: 1 addition & 1 deletion cf_xarray/tests/test_accessor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import matplotlib as mpl
import matplotlib.pyplot as plt
import pytest
import xarray as xr
from matplotlib import pyplot as plt
from xarray.testing import assert_identical

import cf_xarray # noqa
Expand Down
18 changes: 18 additions & 0 deletions cf_xarray/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,21 @@ def either_dict_or_kwargs(

def is_dict_like(value: Any) -> bool:
return hasattr(value, "keys") and hasattr(value, "__getitem__")


# copied from xarray
class UncachedAccessor:
""" Acts like a property, but on both classes and class instances
This class is necessary because some tools (e.g. pydoc and sphinx)
inspect classes for which property returns itself and not the
accessor.
"""

def __init__(self, accessor):
self._accessor = accessor

def __get__(self, obj, cls):
if obj is None:
return self._accessor

return self._accessor(obj)
4 changes: 1 addition & 3 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ DataArray
:toctree: generated/
:template: autosummary/accessor_attribute.rst


DataArray.cf.plot

.. autosummary::
:toctree: generated/
Expand All @@ -26,8 +26,6 @@ Dataset
:toctree: generated/
:template: autosummary/accessor_attribute.rst



.. autosummary::
:toctree: generated/
:template: autosummary/accessor_method.rst
Expand Down
56 changes: 50 additions & 6 deletions doc/contributing.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,59 @@
.. currentmodule:: cf_xarray

.. ipython:: python
:suppress:
import cf_xarray.accessor
Contributing
--------------

This section will be expanded later.

.. autodata:: cf_xarray.accessor.coordinate_criteria
.. autodata:: cf_xarray.accessor._WRAPPED_CLASSES
This section will be expanded later. For now it lists docstrings for a number of internal variables, classes and functions.

The following names are "special"
Variables
~~~~~~~~~

.. autodata:: cf_xarray.accessor._AXIS_NAMES
.. autodata:: cf_xarray.accessor._COORD_NAMES
.. autodata:: cf_xarray.accessor._CELL_MEASURES
.. autodata:: cf_xarray.accessor._COORD_NAMES
.. autodata:: cf_xarray.accessor._WRAPPED_CLASSES


Attribute parsing
+++++++++++++++++

This dictionary contains criteria for identifying axis and coords using CF attributes. It was copied from MetPy

.. autosummary::
:toctree: generated/

~accessor.coordinate_criteria

Classes
~~~~~~~

.. autosummary::
:toctree: generated/
:template: autosummary/accessor_class.rst


~accessor.CFAccessor
~accessor._CFWrappedClass
~accessor._CFWrappedPlotMethods

Functions
~~~~~~~~~


Primarily for developer reference. Some of these could become public API if necessary.

.. autosummary::
:toctree: generated/

~accessor._getattr
~accessor._get_axis_coord
~accessor._get_axis_coord_single
~accessor._get_list_standard_names
~accessor._get_measure
~accessor._get_measure_variable
accessor._CFWrappedPlotMethods._plot_decorator

0 comments on commit 9d53560

Please sign in to comment.