@@ -137,7 +137,7 @@ def make_mapping(args, variable):
137
137
)
138
138
139
139
140
- def make_trace_kwargs (args , trace_spec , g , mapping_labels , sizeref ):
140
+ def make_trace_kwargs (args , trace_spec , trace_data , mapping_labels , sizeref ):
141
141
"""Populates a dict with arguments to update trace
142
142
143
143
Parameters
@@ -147,7 +147,7 @@ def make_trace_kwargs(args, trace_spec, g, mapping_labels, sizeref):
147
147
trace_spec : NamedTuple
148
148
which kind of trace to be used (has constructor, marginal etc.
149
149
attributes)
150
- g : pandas DataFrame
150
+ trace_data : pandas DataFrame
151
151
data
152
152
mapping_labels : dict
153
153
to be used for hovertemplate
@@ -156,87 +156,92 @@ def make_trace_kwargs(args, trace_spec, g, mapping_labels, sizeref):
156
156
157
157
Returns
158
158
-------
159
- result : dict
159
+ trace_patch : dict
160
160
dict to be used to update trace
161
161
fit_results : dict
162
162
fit information to be used for trendlines
163
163
"""
164
164
if "line_close" in args and args ["line_close" ]:
165
- g = g .append (g .iloc [0 ])
166
- result = trace_spec .trace_patch .copy () or {}
165
+ trace_data = trace_data .append (trace_data .iloc [0 ])
166
+ trace_patch = trace_spec .trace_patch .copy () or {}
167
167
fit_results = None
168
168
hover_header = ""
169
169
custom_data_len = 0
170
- for k in trace_spec .attrs :
171
- v = args [k ]
172
- v_label = get_decorated_label (args , v , k )
173
- if k == "dimensions" :
170
+ for attr_name in trace_spec .attrs :
171
+ attr_value = args [attr_name ]
172
+ attr_label = get_decorated_label (args , attr_value , attr_name )
173
+ if attr_name == "dimensions" :
174
174
dims = [
175
175
(name , column )
176
- for (name , column ) in g .iteritems ()
177
- if ((not v ) or (name in v ))
176
+ for (name , column ) in trace_data .iteritems ()
177
+ if ((not attr_value ) or (name in attr_value ))
178
178
and (
179
179
trace_spec .constructor != go .Parcoords
180
180
or args ["data_frame" ][name ].dtype .kind in "bifc"
181
181
)
182
182
and (
183
183
trace_spec .constructor != go .Parcats
184
- or (v is not None and name in v )
184
+ or (attr_value is not None and name in attr_value )
185
185
or len (args ["data_frame" ][name ].unique ())
186
186
<= args ["dimensions_max_cardinality" ]
187
187
)
188
188
]
189
- result ["dimensions" ] = [
189
+ trace_patch ["dimensions" ] = [
190
190
dict (label = get_label (args , name ), values = column .values )
191
191
for (name , column ) in dims
192
192
]
193
193
if trace_spec .constructor == go .Splom :
194
- for d in result ["dimensions" ]:
194
+ for d in trace_patch ["dimensions" ]:
195
195
d ["axis" ] = dict (matches = True )
196
196
mapping_labels ["%{xaxis.title.text}" ] = "%{x}"
197
197
mapping_labels ["%{yaxis.title.text}" ] = "%{y}"
198
198
199
199
elif (
200
- v is not None
201
- or (trace_spec .constructor == go .Histogram and k in ["x" , "y" ])
200
+ attr_value is not None
201
+ or (trace_spec .constructor == go .Histogram and attr_name in ["x" , "y" ])
202
202
or (
203
203
trace_spec .constructor in [go .Histogram2d , go .Histogram2dContour ]
204
- and k == "z"
204
+ and attr_name == "z"
205
205
)
206
206
):
207
- if k == "size" :
208
- if "marker" not in result :
209
- result ["marker" ] = dict ()
210
- result ["marker" ]["size" ] = g [ v ]
211
- result ["marker" ]["sizemode" ] = "area"
212
- result ["marker" ]["sizeref" ] = sizeref
213
- mapping_labels [v_label ] = "%{marker.size}"
214
- elif k == "marginal_x" :
207
+ if attr_name == "size" :
208
+ if "marker" not in trace_patch :
209
+ trace_patch ["marker" ] = dict ()
210
+ trace_patch ["marker" ]["size" ] = trace_data [ attr_value ]
211
+ trace_patch ["marker" ]["sizemode" ] = "area"
212
+ trace_patch ["marker" ]["sizeref" ] = sizeref
213
+ mapping_labels [attr_label ] = "%{marker.size}"
214
+ elif attr_name == "marginal_x" :
215
215
if trace_spec .constructor == go .Histogram :
216
216
mapping_labels ["count" ] = "%{y}"
217
- elif k == "marginal_y" :
217
+ elif attr_name == "marginal_y" :
218
218
if trace_spec .constructor == go .Histogram :
219
219
mapping_labels ["count" ] = "%{x}"
220
- elif k == "trendline" :
221
- if v in ["ols" , "lowess" ] and args ["x" ] and args ["y" ] and len (g ) > 1 :
220
+ elif attr_name == "trendline" :
221
+ if (
222
+ attr_value in ["ols" , "lowess" ]
223
+ and args ["x" ]
224
+ and args ["y" ]
225
+ and len (trace_data ) > 1
226
+ ):
222
227
import statsmodels .api as sm
223
228
224
229
# sorting is bad but trace_specs with "trendline" have no other attrs
225
- g2 = g .sort_values (by = args ["x" ])
226
- y = g2 [args ["y" ]]
227
- x = g2 [args ["x" ]]
228
- result ["x" ] = x
230
+ sorted_trace_data = trace_data .sort_values (by = args ["x" ])
231
+ y = sorted_trace_data [args ["y" ]]
232
+ x = sorted_trace_data [args ["x" ]]
233
+ trace_patch ["x" ] = x
229
234
230
235
if x .dtype .type == np .datetime64 :
231
236
x = x .astype (int ) / 10 ** 9 # convert to unix epoch seconds
232
237
233
- if v == "lowess" :
238
+ if attr_value == "lowess" :
234
239
trendline = sm .nonparametric .lowess (y , x )
235
- result ["y" ] = trendline [:, 1 ]
240
+ trace_patch ["y" ] = trendline [:, 1 ]
236
241
hover_header = "<b>LOWESS trendline</b><br><br>"
237
- elif v == "ols" :
242
+ elif attr_value == "ols" :
238
243
fit_results = sm .OLS (y .values , sm .add_constant (x .values )).fit ()
239
- result ["y" ] = fit_results .predict ()
244
+ trace_patch ["y" ] = fit_results .predict ()
240
245
hover_header = "<b>OLS trendline</b><br>"
241
246
hover_header += "%s = %g * %s + %g<br>" % (
242
247
args ["y" ],
@@ -250,120 +255,127 @@ def make_trace_kwargs(args, trace_spec, g, mapping_labels, sizeref):
250
255
mapping_labels [get_label (args , args ["x" ])] = "%{x}"
251
256
mapping_labels [get_label (args , args ["y" ])] = "%{y} <b>(trend)</b>"
252
257
253
- elif k .startswith ("error" ):
254
- error_xy = k [:7 ]
255
- arr = "arrayminus" if k .endswith ("minus" ) else "array"
256
- if error_xy not in result :
257
- result [error_xy ] = {}
258
- result [error_xy ][arr ] = g [ v ]
259
- elif k == "custom_data" :
260
- result ["customdata" ] = g [ v ].values
261
- custom_data_len = len (v ) # number of custom data columns
262
- elif k == "hover_name" :
258
+ elif attr_name .startswith ("error" ):
259
+ error_xy = attr_name [:7 ]
260
+ arr = "arrayminus" if attr_name .endswith ("minus" ) else "array"
261
+ if error_xy not in trace_patch :
262
+ trace_patch [error_xy ] = {}
263
+ trace_patch [error_xy ][arr ] = trace_data [ attr_value ]
264
+ elif attr_name == "custom_data" :
265
+ trace_patch ["customdata" ] = trace_data [ attr_value ].values
266
+ custom_data_len = len (attr_value ) # number of custom data columns
267
+ elif attr_name == "hover_name" :
263
268
if trace_spec .constructor not in [
264
269
go .Histogram ,
265
270
go .Histogram2d ,
266
271
go .Histogram2dContour ,
267
272
]:
268
- result ["hovertext" ] = g [ v ]
273
+ trace_patch ["hovertext" ] = trace_data [ attr_value ]
269
274
if hover_header == "" :
270
275
hover_header = "<b>%{hovertext}</b><br><br>"
271
- elif k == "hover_data" :
276
+ elif attr_name == "hover_data" :
272
277
if trace_spec .constructor not in [
273
278
go .Histogram ,
274
279
go .Histogram2d ,
275
280
go .Histogram2dContour ,
276
281
]:
277
- for col in v :
282
+ for col in attr_value :
278
283
try :
279
284
position = args ["custom_data" ].index (col )
280
285
except (ValueError , AttributeError , KeyError ):
281
286
position = custom_data_len
282
287
custom_data_len += 1
283
- if "customdata" in result :
284
- result ["customdata" ] = np .hstack (
285
- (result ["customdata" ], g [col ].values [:, None ])
288
+ if "customdata" in trace_patch :
289
+ trace_patch ["customdata" ] = np .hstack (
290
+ (
291
+ trace_patch ["customdata" ],
292
+ trace_data [col ].values [:, None ],
293
+ )
286
294
)
287
295
else :
288
- result ["customdata" ] = g [col ].values [:, None ]
289
- v_label_col = get_decorated_label (args , col , None )
290
- mapping_labels [v_label_col ] = "%%{customdata[%d]}" % (position )
291
- elif k == "color" :
296
+ trace_patch ["customdata" ] = trace_data [col ].values [
297
+ :, None
298
+ ]
299
+ attr_label_col = get_decorated_label (args , col , None )
300
+ mapping_labels [attr_label_col ] = "%%{customdata[%d]}" % (
301
+ position
302
+ )
303
+ elif attr_name == "color" :
292
304
if trace_spec .constructor in [go .Choropleth , go .Choroplethmapbox ]:
293
- result ["z" ] = g [ v ]
294
- result ["coloraxis" ] = "coloraxis1"
295
- mapping_labels [v_label ] = "%{z}"
305
+ trace_patch ["z" ] = trace_data [ attr_value ]
306
+ trace_patch ["coloraxis" ] = "coloraxis1"
307
+ mapping_labels [attr_label ] = "%{z}"
296
308
elif trace_spec .constructor in [
297
309
go .Sunburst ,
298
310
go .Treemap ,
299
311
go .Pie ,
300
312
go .Funnelarea ,
301
313
]:
302
- if "marker" not in result :
303
- result ["marker" ] = dict ()
314
+ if "marker" not in trace_patch :
315
+ trace_patch ["marker" ] = dict ()
304
316
305
317
if args .get ("color_is_continuous" ):
306
- result ["marker" ]["colors" ] = g [ v ]
307
- result ["marker" ]["coloraxis" ] = "coloraxis1"
308
- mapping_labels [v_label ] = "%{color}"
318
+ trace_patch ["marker" ]["colors" ] = trace_data [ attr_value ]
319
+ trace_patch ["marker" ]["coloraxis" ] = "coloraxis1"
320
+ mapping_labels [attr_label ] = "%{color}"
309
321
else :
310
- result ["marker" ]["colors" ] = []
322
+ trace_patch ["marker" ]["colors" ] = []
311
323
mapping = {}
312
- for cat in g [ v ]:
324
+ for cat in trace_data [ attr_value ]:
313
325
if mapping .get (cat ) is None :
314
326
mapping [cat ] = args ["color_discrete_sequence" ][
315
327
len (mapping ) % len (args ["color_discrete_sequence" ])
316
328
]
317
- result ["marker" ]["colors" ].append (mapping [cat ])
329
+ trace_patch ["marker" ]["colors" ].append (mapping [cat ])
318
330
else :
319
331
colorable = "marker"
320
332
if trace_spec .constructor in [go .Parcats , go .Parcoords ]:
321
333
colorable = "line"
322
- if colorable not in result :
323
- result [colorable ] = dict ()
324
- result [colorable ]["color" ] = g [ v ]
325
- result [colorable ]["coloraxis" ] = "coloraxis1"
326
- mapping_labels [v_label ] = "%%{%s.color}" % colorable
327
- elif k == "animation_group" :
328
- result ["ids" ] = g [ v ]
329
- elif k == "locations" :
330
- result [ k ] = g [ v ]
331
- mapping_labels [v_label ] = "%{location}"
332
- elif k == "values" :
333
- result [ k ] = g [ v ]
334
- _label = "value" if v_label == "values" else v_label
334
+ if colorable not in trace_patch :
335
+ trace_patch [colorable ] = dict ()
336
+ trace_patch [colorable ]["color" ] = trace_data [ attr_value ]
337
+ trace_patch [colorable ]["coloraxis" ] = "coloraxis1"
338
+ mapping_labels [attr_label ] = "%%{%s.color}" % colorable
339
+ elif attr_name == "animation_group" :
340
+ trace_patch ["ids" ] = trace_data [ attr_value ]
341
+ elif attr_name == "locations" :
342
+ trace_patch [ attr_name ] = trace_data [ attr_value ]
343
+ mapping_labels [attr_label ] = "%{location}"
344
+ elif attr_name == "values" :
345
+ trace_patch [ attr_name ] = trace_data [ attr_value ]
346
+ _label = "value" if attr_label == "values" else attr_label
335
347
mapping_labels [_label ] = "%{value}"
336
- elif k == "parents" :
337
- result [ k ] = g [ v ]
338
- _label = "parent" if v_label == "parents" else v_label
348
+ elif attr_name == "parents" :
349
+ trace_patch [ attr_name ] = trace_data [ attr_value ]
350
+ _label = "parent" if attr_label == "parents" else attr_label
339
351
mapping_labels [_label ] = "%{parent}"
340
- elif k == "ids" :
341
- result [ k ] = g [ v ]
342
- _label = "id" if v_label == "ids" else v_label
352
+ elif attr_name == "ids" :
353
+ trace_patch [ attr_name ] = trace_data [ attr_value ]
354
+ _label = "id" if attr_label == "ids" else attr_label
343
355
mapping_labels [_label ] = "%{id}"
344
- elif k == "names" :
356
+ elif attr_name == "names" :
345
357
if trace_spec .constructor in [
346
358
go .Sunburst ,
347
359
go .Treemap ,
348
360
go .Pie ,
349
361
go .Funnelarea ,
350
362
]:
351
- result ["labels" ] = g [ v ]
352
- _label = "label" if v_label == "names" else v_label
363
+ trace_patch ["labels" ] = trace_data [ attr_value ]
364
+ _label = "label" if attr_label == "names" else attr_label
353
365
mapping_labels [_label ] = "%{label}"
354
366
else :
355
- result [ k ] = g [ v ]
367
+ trace_patch [ attr_name ] = trace_data [ attr_value ]
356
368
else :
357
- if v :
358
- result [ k ] = g [ v ]
359
- mapping_labels [v_label ] = "%%{%s}" % k
369
+ if attr_value :
370
+ trace_patch [ attr_name ] = trace_data [ attr_value ]
371
+ mapping_labels [attr_label ] = "%%{%s}" % attr_name
360
372
if trace_spec .constructor not in [
361
373
go .Parcoords ,
362
374
go .Parcats ,
363
375
]:
364
376
hover_lines = [k + "=" + v for k , v in mapping_labels .items ()]
365
- result ["hovertemplate" ] = hover_header + "<br>" .join (hover_lines )
366
- return result , fit_results
377
+ trace_patch ["hovertemplate" ] = hover_header + "<br>" .join (hover_lines )
378
+ return trace_patch , fit_results
367
379
368
380
369
381
def configure_axes (args , constructor , fig , orders ):
@@ -1015,8 +1027,8 @@ def _check_dataframe_all_leaves(df):
1015
1027
null_indices = np .nonzero (null_mask .any (axis = 1 ).values )[0 ]
1016
1028
for null_row_index in null_indices :
1017
1029
row = null_mask .iloc [null_row_index ]
1018
- indices = np .nonzero (row .values )[0 ]
1019
- if not row [indices [ 0 ] :].all ():
1030
+ i = np .nonzero (row .values )[ 0 ] [0 ]
1031
+ if not row [i :].all ():
1020
1032
raise ValueError (
1021
1033
"None entries cannot have not-None children" ,
1022
1034
df_sorted .iloc [null_row_index ],
@@ -1058,6 +1070,7 @@ def process_dataframe_hierarchy(args):
1058
1070
path = [new_col_name if x == col_name else x for x in path ]
1059
1071
df [new_col_name ] = series_to_copy
1060
1072
# ------------ Define aggregation functions --------------------------------
1073
+
1061
1074
def aggfunc_discrete (x ):
1062
1075
uniques = x .unique ()
1063
1076
if len (uniques ) == 1 :
0 commit comments