cf-xarray
cf-xarray copied to clipboard
wrap facetgrid objects
This will allow fg.cf.map_dataarray(x="longitude", ...)
Adding xr.plot.FacetGrid
to _WRAPPED_CLASSES
and some tests should be enough (?)
@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?
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)
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)
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
.
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.
Thanks this helps clear it up a lot.
@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?
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)
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.
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
For pcolormesh
, type(fg)
is still xr.plot.facetgrid.Facetgrid
instead of the target cf_xarray.accessor._CFWrappedClass