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

wrap facetgrid objects #79

Open
dcherian opened this issue Aug 21, 2020 · 10 comments
Open

wrap facetgrid objects #79

dcherian opened this issue Aug 21, 2020 · 10 comments
Labels
good second issue help wanted Extra attention is needed

Comments

@dcherian
Copy link
Contributor

dcherian commented Aug 21, 2020

This will allow fg.cf.map_dataarray(x="longitude", ...)

Adding xr.plot.FacetGrid to _WRAPPED_CLASSES and some tests should be enough (?)

@dcherian dcherian added the good first issue Good for newcomers label Aug 21, 2020
@jukent
Copy link
Contributor

jukent commented Sep 17, 2020

@dcherian I am interested in tackling with this issue, but am not familiar with facetgrid yet. Is this seaborn facetgrid? https://www.tutorialspoint.com/seaborn/seaborn_facet_grid.htm

Is there a line of code that works as fg.cf.map_dataarray(x="longitude", ...) is intended to?

@jukent jukent mentioned this issue Sep 17, 2020
@dcherian
Copy link
Contributor Author

dcherian commented Sep 18, 2020

Thanks @jukent . This is xarray's facetgrid which is inspired by seaborn: https://xarray.pydata.org/en/stable/plotting.html#faceting

Here's some example code with output. We want the last commented out line to work. It's pretty similar to groupby and other classes...

import xarray as xr
import cf_xarray

ds = xr.tutorial.load_dataset("air_temperature")

fg = ds.air.isel(time=slice(6)).cf.plot(col="T", col_wrap=3)  # note .cf.plot; so we can wrap the returned object.
fg.map_dataarray(xr.plot.contour, x="lon", y="lat", colors='w', add_colorbar=False)
# fg.map_dataarray(xr.plot.contour, x="longitude", y="latitude", colors='w', add_colorbar=False)

image

This may be a little complicated so let me know if you want to chat (i'm a little fuzzy on how this stuff is working right now)

@jukent
Copy link
Contributor

jukent commented Sep 18, 2020

Thanks @dcherian! I think what I need to understand the most is the map_dataarray function. After some work yesterday (where I discovered that FacetGrid does not work with the most up-to-date version of pandas fyi), I followed through a simple FacetGrid example and found that cf-xarray already worked.

airtemps = xr.tutorial.open_dataset("air_temperature")
air = airtemps.air - 273.15
air.attrs = airtemps.air.attrs
air.attrs["units"] = "deg C"

t = air.isel(time=slice(0, 365 * 4, 250))
t.coords

where both versions of plotting (with and without cf-xarray)already worked even before adding xr.plot.FacetGrid to the wrapped classes.
g_simple = t.plot(x="lon", y="lat", col="time", col_wrap=3)
and
g_simple = t.cf.plot(x="longitude", y="latitude", col="time", col_wrap=3).

Thank you for this example on how to use map_dataarray.

@dcherian
Copy link
Contributor Author

ah sorry this issue isn't clear at all.

.cf.plot will work. This issue is about making fg.map_dataarray work. Also I made a mistake in the previous example; what we want to work is
fg.map_dataarray(xr.plot.contour, x="longitude", y="latitude", colors='w', add_colorbar=False)

AFTER fg = da.cf.plot(...). so fg is now an object wrapped by cf_xarray magic.

This is similar to gb = da.cf.groupby("T") and then gb.mean("T") works.

@jukent
Copy link
Contributor

jukent commented Sep 18, 2020

Thanks this helps clear it up a lot.

@jukent
Copy link
Contributor

jukent commented Sep 24, 2020

@dcherian I am confused by the mistake you mention. You are already defining fg (fg = ds.air.isel(time=slice(6)).cf.plot(col="T", col_wrap=3)) before the map_dataarray call.

And we're after fg.cf.map_dataarray(x="longitude", ...) or fg.map_dataarray(x="longitude", ...)? Should we need the second .cf if the fg is already wrapped by cf_xarray?

@dcherian
Copy link
Contributor Author

Sorry for the confusion. I edited the "mistake" to fix it.

This is the sequence we want to work

fg = ds.air.isel(time=slice(6)).cf.plot(col="T", col_wrap=3)  # note .cf.plot; so we can wrap the returned object.
fg.map_dataarray(xr.plot.contour, x="longitude", y="latitude", colors='w', add_colorbar=False)

@jukent
Copy link
Contributor

jukent commented Sep 24, 2020

So one clue I've found so far is that

gb

returns

--- CF-xarray wrapped 
DataArrayGroupBy, grouped over 'time' 
6 groups with labels 2013-01-01, ..., 2013-01-02T0....

but

fg = da.cf.plot(col="T", col_wrap=3)
fg

returns
<xarray.plot.facetgrid.FacetGrid at 0x11c344550>
without specifying that it is cf-xarray wrapped.

I am looking into the cf-xarray plotting methods now to see why it uses cf-xarray but doesn't maintain the wrap for the next function call, as the other functions (rolling, coarsen, groupby etc) do.

@dcherian
Copy link
Contributor Author

does fg = da.cf.plot.pcolormesh work instead?

if so we want to look at __call__ vs __getattr__ in _CFWrappedPlotMethods. I remember there was some weirdness about this so this may become complicated

@jukent
Copy link
Contributor

jukent commented Sep 24, 2020

For pcolormesh, type(fg) is still xr.plot.facetgrid.Facetgrid instead of the target cf_xarray.accessor._CFWrappedClass

@dcherian dcherian added help wanted Extra attention is needed good second issue and removed good first issue Good for newcomers labels Dec 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good second issue help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants