cf-xarray icon indicating copy to clipboard operation
cf-xarray copied to clipboard

wrap facetgrid objects

Open dcherian opened this issue 3 years ago • 10 comments

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

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

dcherian avatar Aug 21 '20 19:08 dcherian

@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 avatar Sep 17 '20 20:09 jukent

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)

dcherian avatar Sep 18 '20 16:09 dcherian

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.

jukent avatar Sep 18 '20 17:09 jukent

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.

dcherian avatar Sep 18 '20 18:09 dcherian

Thanks this helps clear it up a lot.

jukent avatar Sep 18 '20 19:09 jukent

@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?

jukent avatar Sep 24 '20 20:09 jukent

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)

dcherian avatar Sep 24 '20 20:09 dcherian

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.

jukent avatar Sep 24 '20 21:09 jukent

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

dcherian avatar Sep 24 '20 21:09 dcherian

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

jukent avatar Sep 24 '20 21:09 jukent