@@ -22,6 +22,7 @@ class _CFWrapped:
22
22
def __init__ (self , towrap , accessor ):
23
23
self .wrapped = towrap
24
24
self .accessor = accessor
25
+ self ._can_wrap_classes = False
25
26
26
27
def __repr__ (self ):
27
28
return "--- CF-xarray wrapped \n " + repr (self .wrapped )
@@ -38,14 +39,49 @@ def wrapper(*args, **kwargs):
38
39
return wrapper
39
40
40
41
42
+ class _CFWrappedPlotMethods :
43
+ def __init__ (self , obj , accessor ):
44
+ self ._obj = obj
45
+ self .accessor = accessor
46
+ self ._can_wrap_classes = False
47
+
48
+ def __call__ (self , * args , ** kwargs ):
49
+ func = self ._obj .plot # (*args, **kwargs)
50
+
51
+ @functools .wraps (func )
52
+ def wrapper (* args , ** kwargs ):
53
+ arguments = self .accessor ._process_signature (
54
+ func , args , kwargs , keys = ("x" , "y" , "hue" , "col" , "row" )
55
+ )
56
+ print (arguments )
57
+ rv = func (** arguments )
58
+ return rv
59
+
60
+ return wrapper (* args , ** kwargs )
61
+
62
+ def __getattr__ (self , attr ):
63
+ func = getattr (self ._obj .plot , attr )
64
+
65
+ @functools .wraps (func )
66
+ def wrapper (* args , ** kwargs ):
67
+ arguments = self .accessor ._process_signature (
68
+ func , args , kwargs , keys = ("x" , "y" , "hue" , "col" , "row" )
69
+ )
70
+ rv = func (** arguments )
71
+ return rv
72
+
73
+ return wrapper
74
+
75
+
41
76
@xr .register_dataarray_accessor ("cf" )
42
77
class CFAccessor :
43
78
def __init__ (self , da ):
44
79
self ._obj = da
45
80
self ._coords = _get_axis_name_mapping (da )
81
+ self ._can_wrap_classes = True
46
82
47
- def _process_signature (self , func , args , kwargs ):
48
- sig = inspect .signature (func )
83
+ def _process_signature (self , func , args , kwargs , keys = ( "dim" ,) ):
84
+ sig = inspect .signature (func , follow_wrapped = False )
49
85
50
86
# Catch things like .isel(T=5).
51
87
# This assigns indexers_kwargs=dict(T=5).
@@ -55,10 +91,13 @@ def _process_signature(self, func, args, kwargs):
55
91
if sig .parameters [param ].kind is inspect .Parameter .VAR_KEYWORD :
56
92
var_kws .append (param )
57
93
58
- bound = sig .bind (* args , ** kwargs )
59
- arguments = self ._rewrite_values_with_axis_names (
60
- bound .arguments , ["dim" ,] + var_kws
61
- )
94
+ if args or kwargs :
95
+ bound = sig .bind (* args , ** kwargs )
96
+ arguments = self ._rewrite_values_with_axis_names (
97
+ bound .arguments , keys , tuple (var_kws )
98
+ )
99
+ else :
100
+ arguments = {}
62
101
63
102
if arguments :
64
103
# now unwrap the **indexers_kwargs type arguments
@@ -69,10 +108,10 @@ def _process_signature(self, func, args, kwargs):
69
108
70
109
return arguments
71
110
72
- def _rewrite_values_with_axis_names (self , kwargs , keys ):
111
+ def _rewrite_values_with_axis_names (self , kwargs , keys , var_kws ):
73
112
""" rewrites 'dim' for example. """
74
113
updates = {}
75
- for key in keys :
114
+ for key in tuple ( keys ) + tuple ( var_kws ) :
76
115
value = kwargs .get (key , None )
77
116
if value :
78
117
if isinstance (value , str ):
@@ -88,6 +127,18 @@ def _rewrite_values_with_axis_names(self, kwargs, keys):
88
127
updates [key ] = updates [key ][0 ]
89
128
90
129
kwargs .update (updates )
130
+
131
+ # maybe the keys I'm looking for are in kwargs.
132
+ # This happens with DataArray.plot() for example, where the signature is obscured.
133
+ for vkw in var_kws :
134
+ if vkw in kwargs :
135
+ maybe_update = {
136
+ k : self ._coords .get (v , v )
137
+ for k , v in kwargs [vkw ].items ()
138
+ if k in keys
139
+ }
140
+ kwargs [vkw ].update (maybe_update )
141
+
91
142
return kwargs
92
143
93
144
def __getattr__ (self , name ):
@@ -104,11 +155,6 @@ def wrapper(*args, **kwargs):
104
155
105
156
return wrapper
106
157
107
- def plot (self , * args , ** kwargs ):
108
- if args :
109
- raise ValueError ("cf.plot can only be called with keyword arguments." )
110
-
111
- kwargs = self ._rewrite_values_with_axis_names (
112
- kwargs , ("x" , "y" , "hue" , "col" , "row" )
113
- )
114
- return self ._obj .plot (* args , ** kwargs )
158
+ @property
159
+ def plot (self ):
160
+ return _CFWrappedPlotMethods (self ._obj , self )
0 commit comments