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

2d plots may fail for some choices of x and y #5097

Closed
johnomotani opened this issue Mar 31, 2021 · 1 comment · Fixed by #5099
Closed

2d plots may fail for some choices of x and y #5097

johnomotani opened this issue Mar 31, 2021 · 1 comment · Fixed by #5099

Comments

@johnomotani
Copy link
Contributor

johnomotani commented Mar 31, 2021

What happened:
When making a 2d plot with a 1d x argument and a 2d y, if the two dimensions have the same size and are in the wrong order, no plot is produced - the third plot in the MCVE is blank.

What you expected to happen:
All three plots in the MCVE should be identical.

Minimal Complete Verifiable Example:

from matplotlib import pyplot as plt
import numpy as np
import xarray as xr

ds = xr.Dataset({"z": (["x", "y"], np.random.rand(4,4))})

x2d, y2d = np.meshgrid(ds["x"], ds["y"])

ds = ds.assign_coords(x2d=(["x", "y"], x2d.T), y2d=(["x", "y"], y2d.T))

fig, axes = plt.subplots(1,3)

h0 = ds["z"].plot.pcolormesh(x="y2d", y="x2d", ax=axes[0])
h1 = ds["z"].plot.pcolormesh(x="y", y="x", ax=axes[1])
h2 = ds["z"].plot.pcolormesh(x="y", y="x2d", ax=axes[2])

plt.show()

result:
test2d

Anything else we need to know?:

The bug is present in both the 0.17.0 release and current master.

I came across this while starting to work on #5084. I think the problem is here

xarray/xarray/plot/plot.py

Lines 678 to 684 in ddc352f

# check if we need to broadcast one dimension
if xval.ndim < yval.ndim:
dims = darray[ylab].dims
if xval.shape[0] == yval.shape[0]:
xval = np.broadcast_to(xval[:, np.newaxis], yval.shape)
else:
xval = np.broadcast_to(xval[np.newaxis, :], yval.shape)

as the check xval.shape[0] == yval.shape[0] doesn't work if the single dimension of x is actually the second dimension of y, but happened to have the same size as the first dimension of y? I think it needs to check the actual dimensions of x and y.

Why don't we just do something like

xval = xval.broadcast_like(darray)
yval = yval.broadcast_like(darray)

if either coordinate is 2d before using .values to convert to numpy arrays?

Environment:

Output of xr.show_versions()

INSTALLED VERSIONS

commit: None
python: 3.8.6 | packaged by conda-forge | (default, Oct 7 2020, 19:08:05)
[GCC 7.5.0]
python-bits: 64
OS: Linux
OS-release: 5.4.0-70-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_GB.UTF-8
LOCALE: en_GB.UTF-8
libhdf5: 1.10.6
libnetcdf: 4.7.4

xarray: 0.17.0
pandas: 1.1.5
numpy: 1.19.4
scipy: 1.5.3
netCDF4: 1.5.5.1
pydap: None
h5netcdf: None
h5py: 3.1.0
Nio: None
zarr: None
cftime: 1.3.0
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: None
dask: 2020.12.0
distributed: 2020.12.0
matplotlib: 3.3.3
cartopy: None
seaborn: None
numbagg: None
pint: 0.16.1
setuptools: 49.6.0.post20201009
pip: 20.3.3
conda: 4.9.2
pytest: 6.2.1
IPython: 7.19.0
sphinx: 3.4.0

@dcherian
Copy link
Contributor

👍 for making this change.

IIRC the "resolving intervals" section later will break and is somewhat annoying to fix. This is why the current ugly code exists.

johnomotani added a commit to johnomotani/xarray that referenced this issue Mar 31, 2021
Use broadcast_like if either `x` or `y` inputs are 2d to ensure that
both have dimensions in the same order as the DataArray being plotted.
Convert to numpy arrays after possibly using broadcast_like. Simplifies
code, and fixes pydata#5097 (bug when dimensions have the same size).
mathause added a commit that referenced this issue Apr 22, 2021
* Use broadcast_like for 2d plot coordinates

Use broadcast_like if either `x` or `y` inputs are 2d to ensure that
both have dimensions in the same order as the DataArray being plotted.
Convert to numpy arrays after possibly using broadcast_like. Simplifies
code, and fixes #5097 (bug when dimensions have the same size).

* Update whats-new

* Test for issue 5097

* Fix typo in doc/whats-new.rst

Co-authored-by: Mathias Hauser <[email protected]>

* Update doc/whats-new.rst

Co-authored-by: Mathias Hauser <[email protected]>
mathause added a commit that referenced this issue May 3, 2021
* Use broadcast_like for 2d plot coordinates

Use broadcast_like if either `x` or `y` inputs are 2d to ensure that
both have dimensions in the same order as the DataArray being plotted.
Convert to numpy arrays after possibly using broadcast_like. Simplifies
code, and fixes #5097 (bug when dimensions have the same size).

* Update whats-new

* Implement 'surface()' plot function

Wraps mpl_toolkits.mplot3d.axes3d.plot_surface

* Make surface plots work with facet grids

* Unit tests for surface plot

* Minor fixes for surface plots

* Add surface plots to api.rst and api-hidden.rst

* Update whats-new

* Fix tests

* mypy fix

* seaborn doesn't work with matplotlib 3d toolkit

* Remove cfdatetime surface plot test

Does not work because the datetime.timedelta does not work with
surface's 'shading'.

* Ignore type checks for mpl_toolkits module

* Check matplotlib version is new enough for surface plots

* version check requires matplotlib

* Handle matplotlib not installed for TestSurface version check

* fix flake8 error

* Don't run test_plot_transposed_nondim_coord for surface plots

Too complicated to check matplotlib version is high enough just for
surface plots.

* Apply suggestions from code review

Co-authored-by: Mathias Hauser <[email protected]>

* More suggestions from code review

* black

* isort and flake8

* Make surface plots more backward compatible

Following suggestion from Illviljan

* Clean up matplotlib requirement

* Update xarray/plot/plot.py

Co-authored-by: Mathias Hauser <[email protected]>

* Apply suggestions from code review

Co-authored-by: Mathias Hauser <[email protected]>

* Use None as default value

* black

* More 2D plotting method examples in docs

* Fix docs

* [skip-ci] Make example surface plot look a bit nicer

Co-authored-by: Mathias Hauser <[email protected]>
Co-authored-by: Mathias Hauser <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants