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

allow multiindex levels in plots #3938

Merged
merged 18 commits into from
May 25, 2020

Conversation

mathause
Copy link
Collaborator

@mathause mathause commented Apr 5, 2020

Copy link
Collaborator Author

@mathause mathause left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the doc enough or should I add something to plotting.rst?

After this change the error messages are not entirely accurate any more.

  • For the 2D plots seem to be not entirely correct but ok - I'd be fine to leave them, but maybe someone has a suggestion.
  • For the 1D plot they become wrong (when the da has a MultiIndex), see below:
import xarray as xr
import numpy as np

da_1D = xr.DataArray(
    np.arange(5),
    dims="x",
    coords=dict(a=("x", np.arange(5)), b=("x", np.arange(5, 10))),
)
da_1D = da_1D.set_index(x=["a", "b"])

da_1D.plot(x="not_valid")

returns

ValueError: x must be either None or one of ('x')

(but x="x" does not work, you cannot specify a MultiIndex, only its levels). Should I

ValueError: x must be either None or one of ('a', 'b')

or

ValueError: x must be None, a dimension name, coordinate variable or coordinate level

xarray/plot/utils.py Outdated Show resolved Hide resolved
xarray/plot/utils.py Outdated Show resolved Hide resolved
xarray/plot/utils.py Outdated Show resolved Hide resolved
xarray/tests/test_plot.py Show resolved Hide resolved
@mathause
Copy link
Collaborator Author

I think this is ready for review. I simplified the error messages for the 1D case - let me know if this ok.
@max-sixty @dcherian

@dcherian
Copy link
Contributor

This seems potentially confusing because I don't think any other xarray operation works with multiindex levels.

Would it be more intuitive to allow plotting with multiindexes by converting the multiindex to a vector of strings and passing that to MPL?

@mathause
Copy link
Collaborator Author

This should of course not lead to confusion, however, there are operations that work with levels, e.g. da["level"] returns a mutltiindex level as virtual coordinate* and da.sel(level=5) works.

In my case I had Coordinates that looked something like this

Coordinates:
  * time     (time) datetime64[ns] ...
  * ens      (ens) MultiIndex
  - model    (ens) "CESM", "MIROC", ...
  - number   (ens) 0, 1, ...

and I wanted to do da.plot(x="time", y="number"), but this does currently not work. What I could do is ds.reset_index("ens") and use the resulting "non-dimension coordinate" for plotting.

(Both "non-dimension coordinate" and "MultiIndex" have some issues, so depending on what I want to do I need one ore the other.)

*which is why I only needed to change the valitity check for x and y and not the plotting itself

Copy link
Contributor

@dcherian dcherian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mathause . I don't use MultiIndexes often so I didn't know that the individual levels are usable. This looks like a good idea to me. Minor suggestions below.

raise ValueError("x " + error_msg)
if (
x is not None
and x not in darray.dims
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make valid_xy = set(darray.dims) + set(darray.coords) + set(darray._level_coords) and then print those values in the error message. It would make the if conditions on x and y pretty clean too.

Could do the same below too.

Is it possible to refactor out the x and y checking?

@dcherian
Copy link
Contributor

👍 on adding something to plotting.rst. Just a single example with a multiindex would do.

xarray/plot/utils.py Outdated Show resolved Hide resolved
xarray/plot/utils.py Outdated Show resolved Hide resolved
xarray/tests/test_plot.py Outdated Show resolved Hide resolved
doc/plotting.rst Outdated Show resolved Hide resolved
xarray/plot/plot.py Outdated Show resolved Hide resolved
@mathause
Copy link
Collaborator Author

mathause commented May 3, 2020

This would be ready for review ;)

@dcherian dcherian mentioned this pull request May 5, 2020
23 tasks
Copy link
Contributor

@dcherian dcherian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks @mathause. Also thanks for being patient here.

@mathause
Copy link
Collaborator Author

mathause commented May 11, 2020

No problem. Thanks for the helpful feedback and your dedication to xarray!

@mathause
Copy link
Collaborator Author

@dcherian do you think you could merge for me?

@dcherian
Copy link
Contributor

Thanks @mathause!

@dcherian dcherian merged commit bdb1d33 into pydata:master May 25, 2020
dcherian added a commit to dcherian/xarray that referenced this pull request May 25, 2020
* upstream/master:
  Improve interp performance (pydata#4069)
  Auto chunk (pydata#4064)
  xr.cov() and xr.corr() (pydata#4089)
  allow multiindex levels in plots (pydata#3938)
  Fix bool weights (pydata#4075)
  fix dangerous default arguments (pydata#4006)
@mathause mathause deleted the plot_use_multiindex_as_coord branch August 19, 2020 13:11
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 this pull request may close these issues.

use level of a MultiIndex for plotting?
2 participants