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

col_wrap arg to da.plot() can be a string? #5614

Open
dschneiderch opened this issue Jul 16, 2021 · 2 comments
Open

col_wrap arg to da.plot() can be a string? #5614

dschneiderch opened this issue Jul 16, 2021 · 2 comments

Comments

@dschneiderch
Copy link

What happened:
if you try to plot a data array with 3 dimensions but the third dim has length 1, then col_wrap accepts a dim name and plots facets with pcolormesh. according to the documentation col_wrap argument should be an int so I assume this is unintentional http://xarray.pydata.org/en/stable/generated/xarray.DataArray.plot.html

if dim 3 has length >1, then col_wrap still takes a str but uses hist()

What you expected to happen:
I expected an error if col_wrap is not an int. I also expected da.plot(col='3rd_dim') to give me one facet if the dim has length 1 - this (mis)behavior is described in #620

all a bit confusing :). I thought I understood plotting but then ran into bug #620 and started fumbling around. I am trying to plot a dataarray in a function but I don't know ahead of time how many values 3rd dim has. I also wanted to avoid limiting my function to pcolormesh() only. da.plot.pcolormesh(col='3rd_dim') works to plot the images regardless of dim length.

Minimal Complete Verifiable Example:

da_list = []
for i in np.arange(1,3):
    data = np.ones((64, 48), dtype = 'uint8') * (200-i*15)
    oneframe = xr.DataArray(
        data=data[..., None],
        dims=('x', 'y','measurement'),
        coords={'measurement':[f't{i*40}']}
    )

    da_list.append(oneframe)

twoframes = xr.concat(da_list, 'measurement')
oneframe.plot(col_wrap='measurement') # Oddly, facets with pcolormesh()
twoframes.plot(col_wrap='measurement') # Oddly, a single facet with hist()
oneframe.plot(col='measurement') # ValueError: IndexVariable objects must be 1-dimensional ala issue #620
twoframes.plot(col='measurement') # facets with pcolormesh()
oneframe.plot.pcolormesh(col='measurement') # facets with pcolormesh()
twoframes.plot.pcolormesh(col='measurement') #facets with pcolormesh()

Anything else we need to know?:
@nfahlgren noted a workaround using FacetGrid directly

from xarray.plot.facetgrid import FacetGrid
gd = FacetGrid(data=oneframe, col="measurement")
gd.map_dataarray(xr.plot.imshow, "x", "y")

is consistent with:

gd = FacetGrid(data=twoframes, col="measurement")
gd.map_dataarray(xr.plot.imshow, "x", "y")

Environment:
Windows 10, python 3.7

Output of xr.show_versions()

INSTALLED VERSIONS

commit: None
python: 3.7.10 | packaged by conda-forge | (default, Feb 19 2021, 15:37:01) [MSC v.1916 64 bit (AMD64)]
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 158 Stepping 10, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None
libhdf5: None
libnetcdf: None

xarray: 0.17.0
pandas: 1.2.3
numpy: 1.20.1
scipy: 1.6.0
netCDF4: None
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: 2.7.0
cftime: None
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: None
dask: 2021.02.0
distributed: 2021.02.0
matplotlib: 3.3.4
cartopy: None
seaborn: None
numbagg: None
pint: None
setuptools: 49.6.0.post20210108
pip: 21.1.2
conda: 4.10.1
pytest: 6.2.2
IPython: 7.24.1
sphinx: None

@dcherian
Copy link
Contributor

dcherian commented Jul 16, 2021

col_wrap should be an int. So we should raise an error there if col_wrap is not None and (col is None or row is None) as you say. And another if not isinstance(col_wrap, int). Pull requests are very welcome!

We will have to go through a deprecation cycle to fix #620

@dschneiderch
Copy link
Author

small correction above, this first 2 cases are not being facetted and I think col_wrap is just being ignored.
oneframe.plot(col_wrap='measurement') outputs:
<matplotlib.collections.QuadMesh at 0x16ea840f7c8>
compared with
oneframe.plot.pcolormesh(col='measurement') outputs:
<xarray.plot.facetgrid.FacetGrid at 0x1b26a1f5ec8>

i'll see if i can make sense of the code base and submit a PR.

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

No branches or pull requests

2 participants