Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use CF conventions to enhance plot labels #2135

Closed
rabernat opened this issue May 15, 2018 · 4 comments · Fixed by #2151
Closed

use CF conventions to enhance plot labels #2135

rabernat opened this issue May 15, 2018 · 4 comments · Fixed by #2151

Comments

@rabernat
Copy link
Contributor

Elsewhere in xarray we use CF conventions to help with automatic decoding of datasets. Here I propose we consider using CF metadata conventions to improve the automatic labelling of plots. If datasets declare long_name, standard_name, and units attributes, we could use these instead of the variable name to label the relevant axes / colorbars. This feature would have helped me avoid several past mistakes due to my failure to examine the units attribute (e.g. data given in cm when I assumed m).

Code Sample, a copy-pastable example if possible

Here I create some data with relevant attributes

import xarray as xr
import numpy as np
ds = xr.Dataset({'foo': ('x', np.random.rand(10),
                         {'long_name': 'height',
                          'units': 'm'})},
                coords={'x': ('x', np.arange(10),
                              {'long_name': 'distance',
                               'units': 'km'})})
ds.foo.plot()

image

Problem description

We have neglected the variable attributes, which would provide better axis labels.

Expected Output

Consider this instead:

def label_from_attrs(da):
    attrs = da.attrs
    if 'long_name' in attrs:
        name = attrs['long_name']
    elif 'standard_name' in attrs:
        name = attrs['standard_name']
    else:
        name = da.name
    if 'units' in da.attrs:
        units = ' [{}]'.format(da.attrs['units'])
    label = name + units
    return label
ds.foo.plot()
plt.xlabel(label_from_attrs(ds.x))
plt.ylabel(label_from_attrs(ds.foo))

image

I feel like this would be a sensible default. But it would be a breaking change. We could make it optional with a keyword like labels_from_attrs=True.

Output of xr.show_versions()

INSTALLED VERSIONS ------------------ commit: None python: 3.6.5.final.0 python-bits: 64 OS: Linux OS-release: 4.4.111+ machine: x86_64 processor: x86_64 byteorder: little LC_ALL: en_US.UTF-8 LANG: en_US.UTF-8 LOCALE: en_US.UTF-8

xarray: 0.10.3+dev13.g98373f0
pandas: 0.22.0
numpy: 1.14.3
scipy: 1.0.1
netCDF4: 1.3.1
h5netcdf: 0.5.1
h5py: 2.7.1
Nio: None
zarr: 2.2.1.dev2
bottleneck: 1.2.1
cyordereddict: None
dask: 0.17.4
distributed: 1.21.8
matplotlib: 2.2.2
cartopy: None
seaborn: None
setuptools: 39.1.0
pip: 9.0.1
conda: 4.3.29
pytest: 3.5.1
IPython: 6.3.1
sphinx: None

@shoyer
Copy link
Member

shoyer commented May 15, 2018

Default labels are intended more for convenience than anything else. For publication/production purposes, I suspect labels are almost always been explicitly set, anyways.

So I think this convention makes sense. Let's just document it directly in the plotting docs, maybe even by including your label_from_attrs() function to make it fully explicit. That way non-weather/climate users can also make use of it, without referring to the full CF conventions spec.

@rabernat
Copy link
Contributor Author

It would take me some time to wrap my head around the plotting code again, and as a result I don't anticipate having time to work on this any time soon.

I know @dcherian has been digging into the plotting functions a lot. I imagine that he would be able to implement this much faster than I would. Just leaving that suggestion out there... ;)

Obviously this is not an urgent issue.

@fmaussion
Copy link
Member

@dcherian
Copy link
Contributor

I can do it. are we agreed that long_name, standard_name, and units are the attributes we want to follow? I think we should also add support for upper-case versions of these (I think I've seen those in the wild)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants