pydata / xarray

N-D labeled arrays and datasets in Python
https://xarray.dev
Apache License 2.0
3.62k stars 1.09k forks source link

Label row and column titles with units #3534

Open kuchaale opened 5 years ago

kuchaale commented 5 years ago

According to this plotting example, xlabels and ylabels are labeled with units. However, row labels and column labels omit the units.

MCVE Code Sample

import xarray as xr
ds = xr.tutorial.scatter_example_dataset()
ds.plot.scatter(x='A', y='B', col='x', row='z', hue='w', hue_style='discrete')

Expected Output

Should xr.FacetGrid include the functionality for plotting row labels and column labels when provided? image

Problem Description

It could be solved with the following included in plot/facetgrid.py#L486:

if self.data[self._row_var].attrs.get('units'):
   units =  self.data[self._row_var].attrs['units']   
   template="{coord} = {value} [{units}]"

title = nicetitle(coord=self._row_var, value=row_name, \
                          maxchar=maxchar, template = template, units = unit

and with the following included in plot/facetgrid.py#L499:

if self.data[self._col_var].attrs.get('units'):
   units =  self.data[self._col_var].attrs['units']   
   template="{coord} = {value} [{units}]"

title = nicetitle(coord=self._col_var, value=col_name, \
                          maxchar=maxchar, template = template, units = units)

and with the modification of _nicetitle:

def _nicetitle(coord, value, maxchar, template, units = None):
    """
    Put coord, value in template and truncate at maxchar
    """
    prettyvalue = format_item(value, quote_strings=False)
    if units is not None:
        title = template.format(coord=coord, value=prettyvalue, units = units)
    else:
        title = template.format(coord=coord, value=prettyvalue)

    if len(title) > maxchar:
        title = title[: (maxchar - 3)] + "..."

    return title

Output of xr.show_versions()

INSTALLED VERSIONS ------------------ commit: None python: 3.6.8 (default, Oct 7 2019, 12:59:55) [GCC 8.3.0] python-bits: 64 OS: Linux OS-release: 4.15.0-65-generic machine: x86_64 processor: x86_64 byteorder: little LC_ALL: None LANG: en_US.UTF-8 LOCALE: en_US.UTF-8 libhdf5: 1.10.2 libnetcdf: 4.6.3 xarray: 0.14.0 pandas: 0.24.2 numpy: 1.17.3 scipy: 1.2.1 netCDF4: 1.5.1.2 pydap: installed h5netcdf: 0.7.4 h5py: 2.9.0 Nio: None zarr: 2.3.2 cftime: 1.0.3.4 nc_time_axis: 1.2.0 PseudoNetCDF: None rasterio: 1.0.5 cfgrib: 0.9.6.2 iris: None bottleneck: 1.2.1 dask: 2.6.0 distributed: 2.6.0 matplotlib: 3.0.3 cartopy: 0.16.0 seaborn: 0.9.0 numbagg: None setuptools: 41.0.1 pip: 19.3.1 conda: None pytest: 4.4.1 IPython: 7.1.1 sphinx: 2.0.1
TomNicholas commented 5 years ago

Good spot. Do you want to put these changes into a pull request? You probably want to be calling the label_from_attrs function too.

kuchaale commented 5 years ago

@TomNicholas Is it really necessary to use the label_from_attrs function? It would label row and column titles with standard or long name in addition to units. It seems redundant to me. Nonetheless, there may be also an option how to switch on/off such a functionality.

TomNicholas commented 5 years ago

@kuchaale maybe not? But if you plot against a coordinate rather than a dimension you would want to label according to the coordinate's name surely? I just wanted to make sure you were aware of it at least. If you make a pull request we can discuss in detail :relaxed: