py2ls 0.1.6.2__py3-none-any.whl → 0.1.6.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
py2ls/plot.py ADDED
@@ -0,0 +1,1109 @@
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+ from matplotlib.colors import to_rgba
4
+ from scipy.stats import gaussian_kde
5
+
6
+ def catplot(data, *args, **kwargs):
7
+ """
8
+ catplot(data, opt=None, ax=None)
9
+
10
+ Args:
11
+ data (array): data matrix
12
+ """
13
+ def plot_bars(data_m, opt_b, xloc, ax):
14
+ bar_positions = get_positions(xloc, opt_b['loc'], opt_b['x_width'], data.shape[0])
15
+ bar_positions=np.nanmean(bar_positions,axis=0)
16
+ for i, (x, y) in enumerate(zip(bar_positions, data_m)):
17
+ color = to_rgba(opt_b['FaceColor'][i % len(opt_b['FaceColor'])])
18
+ ax.bar(x, y,
19
+ width=opt_b['x_width'],
20
+ color=color,
21
+ edgecolor=opt_b['EdgeColor'],
22
+ alpha=opt_b['FaceAlpha'])
23
+
24
+ def plot_errors(data, data_m, opt_e, xloc, ax):
25
+ error_positions = get_positions(xloc, opt_e['loc'], opt_e['x_width'], data.shape[0])
26
+ error_positions=np.nanmean(error_positions,axis=0)
27
+ errors = np.nanstd(data, axis=0)
28
+ if opt_e['error'] == 'sem':
29
+ errors /= np.sqrt(np.sum(~np.isnan(data),axis=0))
30
+
31
+ if not isinstance(opt_e['FaceColor'],list):
32
+ opt_e['FaceColor']=[opt_e['FaceColor']]
33
+ if not isinstance(opt_e['MarkerEdgeColor'],list):
34
+ opt_e['MarkerEdgeColor']=[opt_e['MarkerEdgeColor']]
35
+ for i, (x, y, err) in enumerate(zip(error_positions, data_m, errors)):
36
+ ax.errorbar(x, y, yerr=err,
37
+ fmt=opt_e['Marker'],
38
+ ecolor=opt_e['LineColor'],
39
+ elinewidth=opt_e['LineWidth'],
40
+ lw=opt_e['LineWidth'],
41
+ ls=opt_e['LineStyle'],
42
+ capsize=opt_e['CapSize'],
43
+ capthick=opt_e['CapLineWidth'],
44
+ markersize=opt_e['MarkerSize'],
45
+ mec=opt_e['MarkerEdgeColor'][i % len(opt_e['MarkerEdgeColor'])],
46
+ mfc=opt_e['FaceColor'][i % len(opt_e['FaceColor'])],
47
+ visible=opt_e['Visible']
48
+ )
49
+
50
+ def plot_scatter(data, opt_s, xloc, ax):
51
+ scatter_positions = get_positions(xloc, opt_s['loc'], opt_s['x_width'], data.shape[0])
52
+ for i, (x, y) in enumerate(zip(scatter_positions.T, data.T)):
53
+ color = to_rgba(opt_s['FaceColor'][i % len(opt_s['FaceColor'])])
54
+ ax.scatter(x, y,
55
+ color=color,
56
+ alpha=opt_s['FaceAlpha'],
57
+ edgecolor=opt_s['MarkerEdgeColor'],
58
+ s=opt_s['MarkerSize'],
59
+ marker=opt_s['Marker']
60
+ )
61
+
62
+ def plot_boxplot(data, bx_opt, xloc,ax):
63
+ if 'l' in bx_opt['loc']:
64
+ X_bx = xloc - bx_opt['x_width']
65
+ elif 'r' in bx_opt['loc']:
66
+ X_bx = xloc + bx_opt['x_width']
67
+ elif 'i' in bx_opt['loc']:
68
+ X_bx = xloc
69
+ X_bx[:, 0] += bx_opt['x_width']
70
+ X_bx[:, -1] -= bx_opt['x_width']
71
+ elif 'o' in bx_opt['loc']:
72
+ X_bx = xloc
73
+ X_bx[:, 0] -= bx_opt['x_width']
74
+ X_bx[:, -1] += bx_opt['x_width']
75
+ elif 'c' in bx_opt['loc'] or 'm' in bx_opt['loc']:
76
+ X_bx = xloc
77
+ else:
78
+ X_bx = xloc
79
+
80
+
81
+ boxprops = dict(color=bx_opt['EdgeColor'],
82
+ linewidth=bx_opt['BoxLineWidth'])
83
+ flierprops = dict(marker=bx_opt['OutlierMarker'],
84
+ markerfacecolor=bx_opt['OutlierColor'],
85
+ markersize=bx_opt['OutlierSize'])
86
+ whiskerprops = dict(linestyle=bx_opt['WhiskerLineStyle'],
87
+ color=bx_opt['WhiskerLineColor'],
88
+ linewidth=bx_opt['WhiskerLineWidth'])
89
+ capprops = dict(color=bx_opt['CapLineColor'],
90
+ linewidth=bx_opt['CapLineWidth'],)
91
+ medianprops = dict(linestyle=bx_opt['MedianLineStyle'],
92
+ color=bx_opt['MedianLineColor'],
93
+ linewidth=bx_opt['MedianLineWidth'])
94
+ meanprops = dict(linestyle=bx_opt['MeanLineStyle'],
95
+ color=bx_opt['MeanLineColor'],
96
+ linewidth=bx_opt['MeanLineWidth'])
97
+ bxp = ax.boxplot(data,
98
+ positions=X_bx,
99
+ notch=bx_opt['Notch'],
100
+ patch_artist=True,
101
+ boxprops=boxprops,
102
+ flierprops=flierprops,
103
+ whiskerprops=whiskerprops,
104
+ capwidths=bx_opt['CapSize'],
105
+ showfliers = bx_opt['Outliers'],
106
+ showcaps = bx_opt['Caps'],
107
+ capprops=capprops,
108
+ medianprops=medianprops,
109
+ meanline=bx_opt['MeanLine'],
110
+ showmeans=bx_opt['MeanLine'],
111
+ meanprops =meanprops,
112
+ widths=bx_opt['x_width'])
113
+
114
+ if bx_opt['BoxLineWidth'] < 0.1:
115
+ bx_opt['EdgeColor'] = 'none'
116
+ else:
117
+ bx_opt['EdgeColor'] = bx_opt['EdgeColor']
118
+
119
+ for patch, color in zip(bxp['boxes'], bx_opt['FaceColor']):
120
+ patch.set_facecolor(to_rgba(color, bx_opt['FaceAlpha']))
121
+
122
+ if bx_opt['MedianLineTop']:
123
+ ax.set_children(ax.get_children()[::-1]) # move median line forward
124
+
125
+ def plot_violin(data, opt_v, xloc, ax):
126
+ violin_positions = get_positions(xloc, opt_v['loc'], opt_v['x_width'], data.shape[0])
127
+ violin_positions = np.nanmean(violin_positions, axis=0)
128
+ for i, (x, ys) in enumerate(zip(violin_positions, data.T)):
129
+ ys = ys[~np.isnan(ys)]
130
+ if len(ys) > 1:
131
+ kde = gaussian_kde(ys, bw_method=opt_v['BandWidth'])
132
+ min_val, max_val = ys.min(), ys.max()
133
+ y_vals = np.linspace(min_val, max_val, opt_v['NumPoints'])
134
+ kde_vals = kde(y_vals)
135
+ kde_vals = kde_vals / kde_vals.max() * opt_v['x_width']
136
+ if 'r' in opt_v['loc'].lower():
137
+ ax.fill_betweenx(y_vals, x, x + kde_vals,
138
+ color=opt_v['FaceColor'][i % len(opt_v['FaceColor'])],
139
+ alpha=opt_v['FaceAlpha'],
140
+ edgecolor=opt_v['EdgeColor'])
141
+ elif 'l' in opt_v['loc'].lower() and not 'f' in opt_v['loc'].lower() :
142
+ ax.fill_betweenx(y_vals, x - kde_vals, x,
143
+ color=opt_v['FaceColor'][i % len(opt_v['FaceColor'])],
144
+ alpha=opt_v['FaceAlpha'],
145
+ edgecolor=opt_v['EdgeColor'])
146
+ elif 'o' in opt_v['loc'].lower() or 'both' in opt_v['loc'].lower() :
147
+ ax.fill_betweenx(y_vals, x - kde_vals, x + kde_vals,
148
+ color=opt_v['FaceColor'][i % len(opt_v['FaceColor'])],
149
+ alpha=opt_v['FaceAlpha'],
150
+ edgecolor=opt_v['EdgeColor'])
151
+ elif 'i' in opt_v['loc'].lower():
152
+ if i % 2 == 1: # odd number
153
+ ax.fill_betweenx(y_vals, x -kde_vals, x,
154
+ color=opt_v['FaceColor'][i % len(opt_v['FaceColor'])],
155
+ alpha=opt_v['FaceAlpha'],
156
+ edgecolor=opt_v['EdgeColor'])
157
+ else:
158
+ ax.fill_betweenx(y_vals, x, x+kde_vals,
159
+ color=opt_v['FaceColor'][i % len(opt_v['FaceColor'])],
160
+ alpha=opt_v['FaceAlpha'],
161
+ edgecolor=opt_v['EdgeColor'])
162
+ elif 'f' in opt_v['loc'].lower():
163
+ ax.fill_betweenx(y_vals, x - kde_vals, x + kde_vals,
164
+ color=opt_v['FaceColor'][i % len(opt_v['FaceColor'])],
165
+ alpha=opt_v['FaceAlpha'],
166
+ edgecolor=opt_v['EdgeColor'])
167
+
168
+ def plot_lines(data, opt_l, opt_s, ax):
169
+ scatter_positions = get_positions(xloc, opt_s['loc'], opt_s['x_width'], data.shape[0])
170
+ for incol in range(data.shape[1]-1):
171
+ for irow in range(data.shape[0]):
172
+ if not np.isnan(data[irow, incol]):
173
+ if opt_l['LineStyle'] is not None and not opt_l['LineStyle'] =='none':
174
+ x_data = [scatter_positions[irow, incol], scatter_positions[irow, incol + 1]]
175
+ y_data = [data[irow, incol], data[irow, incol + 1]]
176
+
177
+
178
+ ax.plot(x_data, y_data,
179
+ color=opt_l['LineColor'],
180
+ linestyle=opt_l['LineStyle'],
181
+ linewidth=opt_l['LineWidth'],
182
+ alpha=opt_l['LineAlpha'])
183
+
184
+ def get_positions(xloc, loc_type, x_width, n_row=None):
185
+ if 'rand' in loc_type:
186
+ scatter_positions = np.zeros((n_row, len(xloc)))
187
+ np.random.seed(111)
188
+ for i, x in enumerate(xloc):
189
+ scatter_positions[:, i] = np.random.uniform(x - x_width, x + x_width, n_row)
190
+ return scatter_positions
191
+ elif 'l' in loc_type:
192
+ return np.tile(xloc - x_width,(n_row,1))
193
+ elif 'r' in loc_type and not 'd' in loc_type:
194
+ return np.tile(xloc + x_width,(n_row,1))
195
+ elif 'i' in loc_type:
196
+ return np.tile(np.concatenate([xloc[:1] + x_width, xloc[1:-1], xloc[-1:] - x_width]),(n_row,1))
197
+ elif 'o' in loc_type:
198
+ return np.tile(np.concatenate([xloc[:1] - x_width, xloc[1:-1], xloc[-1:] + x_width]),(n_row,1))
199
+ else:
200
+ return np.tile(xloc,(n_row,1))
201
+
202
+ opt = kwargs.get('opt',{})
203
+ ax = kwargs.get('ax',None)
204
+ if 'ax' not in locals() or ax is None:
205
+ ax=plt.gca()
206
+
207
+ default_colors = np.array([
208
+ [0, 0, 0],
209
+ [234, 37, 46],
210
+ [0, 154, 222],
211
+ [175, 89, 186],
212
+ [255, 198, 37],
213
+ [242, 133, 34]
214
+ ]) / 255.0
215
+
216
+ opt.setdefault('c', default_colors)
217
+ if len(opt['c']) < data.shape[1]:
218
+ additional_colors = plt.cm.winter(np.linspace(0, 1, data.shape[1] - len(opt['c'])))
219
+ opt['c'] = np.vstack([opt['c'], additional_colors[:, :3]])
220
+
221
+ opt.setdefault('loc', {})
222
+ opt['loc'].setdefault('go', 0)
223
+ opt['loc'].setdefault('xloc', np.arange(1, data.shape[1] + 1))
224
+
225
+ # export setting
226
+ opt.setdefault('export', False)
227
+ opt['export'].setdefault('path', None)
228
+ print(opt['export'])
229
+
230
+ opt.setdefault('b', {})
231
+ opt['b'].setdefault('go', 0)
232
+ opt['b'].setdefault('EdgeColor', 'k')
233
+ opt['b'].setdefault('FaceAlpha', 1)
234
+ opt['b'].setdefault('EdgeAlpha', 1)
235
+ opt['b'].setdefault('LineStyle', '-')
236
+ opt['b'].setdefault('x_width', 0.5)
237
+ opt['b'].setdefault('ShowBaseLine', 'off')
238
+ opt['b'].setdefault('loc', 'c')
239
+ opt['b'].setdefault('FaceColor', opt['c'])
240
+
241
+ opt.setdefault('e', {})
242
+ opt['e'].setdefault('go', 1)
243
+ opt['e'].setdefault('LineWidth', 1)
244
+ opt['e'].setdefault('CapLineWidth', 1)
245
+ opt['e'].setdefault('CapSize', opt['b']['x_width'] * 100 * 0.1)
246
+ opt['e'].setdefault('Marker', 'none')
247
+ opt['e'].setdefault('LineStyle', 'none')
248
+ opt['e'].setdefault('LineColor', 'k')
249
+ opt['e'].setdefault('LineJoin', 'round')
250
+ opt['e'].setdefault('MarkerSize', 'auto')
251
+ opt['e'].setdefault('FaceColor', opt['c'])
252
+ opt['e'].setdefault('MarkerEdgeColor', 'none')
253
+ opt['e'].setdefault('Visible', True)
254
+ opt['e'].setdefault('Orientation', 'vertical')
255
+ opt['e'].setdefault('error', 'sem')
256
+ opt['e'].setdefault('loc', 'c')
257
+ opt['e'].setdefault('x_width', opt['b']['x_width'] / 5)
258
+ opt['e'].setdefault('cap_dir', 'b')
259
+
260
+ opt.setdefault('s', {})
261
+ opt['s'].setdefault('go', 1)
262
+ opt['s'].setdefault('x_width', opt['b']['x_width'] / 5)
263
+ opt['s'].setdefault('Marker', 'o')
264
+ opt['s'].setdefault('MarkerSize', 6) # Set default size for markers
265
+ opt['s'].setdefault('LineWidth', 1)
266
+ opt['s'].setdefault('FaceColor', opt['c'])
267
+ opt['s'].setdefault('FaceAlpha', 0.6)
268
+ opt['s'].setdefault('loc', 'random')
269
+ opt['s'].setdefault('MarkerEdgeColor', None)
270
+
271
+ opt.setdefault('bx', {})
272
+ opt['bx'].setdefault('go', 0)
273
+ opt['bx'].setdefault('EdgeColor', 'k')
274
+ opt['bx'].setdefault('FaceAlpha', 1)
275
+ opt['bx'].setdefault('EdgeAlpha', 1)
276
+ opt['bx'].setdefault('LineStyle', '-')
277
+ opt['bx'].setdefault('x_width', 0.5)
278
+ opt['bx'].setdefault('ShowBaseLine', 'off')
279
+ opt['bx'].setdefault('loc', 'c')
280
+ opt['bx'].setdefault('FaceColor', opt['c'])
281
+ opt['bx'].setdefault('Notch', False)
282
+ opt['bx'].setdefault('MedianStyle', 'line')
283
+ opt['bx'].setdefault('Outliers', 'on')
284
+ opt['bx'].setdefault('OutlierMarker', '+')
285
+ opt['bx'].setdefault('OutlierColor', 'r')
286
+ opt['bx'].setdefault('OutlierSize', 6)
287
+ opt['bx'].setdefault('PlotStyle', 'traditional')
288
+ opt['bx'].setdefault('FactorDirection', 'auto')
289
+ opt['bx'].setdefault('Whisker', 1.5)
290
+ opt['bx'].setdefault('Orientation', 'vertical')
291
+ opt['bx'].setdefault('BoxLineWidth', 1.5)
292
+ opt['bx'].setdefault('FaceColor', 'k')
293
+ opt['bx'].setdefault('WhiskerLineStyle', '-')
294
+ opt['bx'].setdefault('WhiskerLineColor', 'k')
295
+ opt['bx'].setdefault('WhiskerLineWidth', 1.5)
296
+ opt['bx'].setdefault('Caps', True)
297
+ opt['bx'].setdefault('CapLineColor', 'k')
298
+ opt['bx'].setdefault('CapLineWidth', 1.5)
299
+ opt['bx'].setdefault('CapSize', 0.35)
300
+ opt['bx'].setdefault('MedianLineStyle', '-')
301
+ opt['bx'].setdefault('MedianLineColor', 'k')
302
+ opt['bx'].setdefault('MedianLineWidth', 1.5)
303
+ opt['bx'].setdefault('MedianLineTop', False)
304
+ opt['bx'].setdefault('MeanLine', False)
305
+ opt['bx'].setdefault('showmeans', opt['bx']['MeanLine'])
306
+ opt['bx'].setdefault('MeanLineStyle', '-')
307
+ opt['bx'].setdefault('MeanLineColor', 'b')
308
+ opt['bx'].setdefault('MeanLineWidth', 1.5)
309
+
310
+ # Violin plot options
311
+ opt.setdefault('v', {})
312
+ opt['v'].setdefault('go', 1)
313
+ opt['v'].setdefault('x_width', 0.3)
314
+ opt['v'].setdefault('loc', 'r')
315
+ opt['v'].setdefault('EdgeColor', 'none')
316
+ opt['v'].setdefault('FaceColor', opt['c'])
317
+ opt['v'].setdefault('FaceAlpha', 0.3)
318
+ opt['v'].setdefault('BandWidth', 'scott')
319
+ opt['v'].setdefault('Function', 'pdf')
320
+ opt['v'].setdefault('Kernel', 'gau')
321
+ opt['v'].setdefault('NumPoints', 500)
322
+ opt['v'].setdefault('BoundaryCorrection', 'reflection')
323
+
324
+ # line plot options
325
+ opt.setdefault('l', {})
326
+ opt['l'].setdefault('go', 0)
327
+ opt['l'].setdefault('LineStyle', '-')
328
+ opt['l'].setdefault('LineColor', 'k')
329
+ opt['l'].setdefault('LineWidth', 0.5)
330
+ opt['l'].setdefault('LineAlpha', 0.5)
331
+
332
+ data_m = np.nanmean(data, axis=0)
333
+ nr, nc = data.shape
334
+
335
+ xloc = opt['loc']['xloc']
336
+
337
+ if opt['b']['go']:
338
+ plot_bars(data_m, opt['b'], xloc, ax)
339
+
340
+ if opt['e']['go']:
341
+ plot_errors(data, data_m, opt['e'], xloc, ax)
342
+
343
+ if opt['s']['go']:
344
+ plot_scatter(data, opt['s'], xloc, ax)
345
+
346
+ if opt['bx']['go']:
347
+ plot_boxplot(data, opt['bx'], xloc, ax)
348
+ if opt['v']['go']:
349
+ plot_violin(data, opt['v'], xloc, ax)
350
+ if opt['l']['go'] and opt['s']['go']:
351
+ plot_lines(data, opt['l'], opt['s'], ax)
352
+
353
+ return ax
354
+
355
+ # from py2ls.ips import get_color,figsets
356
+ # opt={}
357
+ # opt = {
358
+ # 'export':{'path':get_cwd()},
359
+ # 'c': get_color(5,cmap='jet',by='linspace'), # Custom colors for 3 categories
360
+ # 'b': {
361
+ # 'go': 0,
362
+ # 'x_width': 0.85,
363
+ # 'FaceAlpha': 0.7,
364
+ # 'EdgeColor':'none'
365
+ # },
366
+ # 'e': {
367
+ # 'loc':'r',
368
+ # 'go': 1,
369
+ # 'error': 'sem',
370
+ # 'Marker':'d',
371
+ # 'CapSize': 1,
372
+ # 'LineWidth':1,
373
+ # 'CapLineWidth':8,
374
+ # 'LineStyle':'--',
375
+ # 'MarkerSize':6,
376
+ # 'LineColor':'k',
377
+ # 'FaceColor':get_color(10),
378
+ # 'MarkerEdgeColor':'none',
379
+ # 'Visible':True
380
+ # },
381
+ # 's': {
382
+ # 'go': 1,
383
+ # 'x_width':0.2,
384
+ # 'loc':'random',
385
+ # 'Marker': 'o',
386
+ # # 'MarkerSize': 20,
387
+ # 'FaceAlpha': 1,
388
+ # 'FaceColor':'k',
389
+ # 'LineWidth':1
390
+
391
+ # },
392
+ # 'bx':{
393
+ # 'go':1,
394
+ # 'FaceAlpha':0.8,
395
+ # 'EdgeColor':'none',
396
+ # 'loc':'c',
397
+ # 'x_width':0.2,
398
+ # 'WhiskerLineWidth':1,
399
+ # 'MedianLineWidth':2,
400
+ # # 'MedianLineColor':'r',
401
+ # 'OutlierMarker':'+',
402
+ # 'OutlierColor':'r',
403
+ # 'CapSize':.2,
404
+ # # 'Caps':False,
405
+ # # 'CapLineColor':'r',
406
+ # # 'CapLineWidth':8,
407
+ # # 'MeanLine':True,
408
+ # # 'FaceColor':['r','g','b','m','c']
409
+ # },
410
+ # 'v':{
411
+ # 'go':0,
412
+ # 'loc':'r',
413
+ # 'x_width':0.2,
414
+ # 'FaceAlpha':0.51,
415
+ # },
416
+ # 'l':{
417
+ # 'go':1,
418
+ # 'LineColor':'k'
419
+ # }
420
+ # }
421
+ # data1 = np.random.rand(10, 5)
422
+ # data2 = np.random.rand(10, 5)
423
+ # fig, axs=plt.subplots(1,2,figsize=(6,2.5))
424
+ # catplot(data1, opt=opt,ax=axs[0])
425
+ # catplot(data2, opt=opt,ax=axs[1])
426
+ # figsets(sp=5,
427
+ # ax=axs[0],
428
+ # xticks=np.arange(1,6,1),
429
+ # xtickslabel=['glua1','glua2','a','b','c'],
430
+ # xlabel='proteins',
431
+ # xangle=90,
432
+ # yticks=np.arange(0,2,0.5),
433
+ # xlim=[0.75, 5.1],
434
+ # ticks=dict(pad=1,c='k'))
435
+
436
+ # figsave("/Users/macjianfeng/Dropbox/Downloads/",'test.pdf')
437
+
438
+
439
+ import numpy as np
440
+ import matplotlib
441
+ import matplotlib.pyplot as plt
442
+ import matplotlib.ticker as tck
443
+ import seaborn as sns
444
+ from cycler import cycler
445
+
446
+
447
+ def get_cmap():
448
+ return plt.colormaps()
449
+
450
+ def read_mplstyle(style_file):
451
+ # Load the style file
452
+ plt.style.use(style_file)
453
+
454
+ # Get the current style properties
455
+ style_dict = plt.rcParams
456
+
457
+ # Convert to dictionary
458
+ style_dict = dict(style_dict)
459
+ # Print the style dictionary
460
+ for i, j in style_dict.items():
461
+ print(f"\n{i}::::{j}")
462
+ return style_dict
463
+ # #example usage:
464
+ # style_file = "/ std-colors.mplstyle"
465
+ # style_dict = read_mplstyle(style_file)
466
+
467
+ def figsets(*args,**kwargs):
468
+ """
469
+ usage:
470
+ figsets(ax=axs[1],
471
+ ylim=[0, 10],
472
+ spine=2,
473
+ xticklabel=['wake','sleep'],
474
+ yticksdddd=np.arange(0,316,60),
475
+ labels_loc=['right','top'],
476
+ ticks=dict(
477
+ ax='x',
478
+ which='minor',
479
+ direction='out',
480
+ width=2,
481
+ length=2,
482
+ c_tick='m',
483
+ pad=5,
484
+ label_size=11),
485
+ grid=dict(which='minor',
486
+ ax='x',
487
+ alpha=.4,
488
+ c='b',
489
+ ls='-.',
490
+ lw=0.75,
491
+ ),
492
+ supertitleddddd=f'sleep druations\n(min)',
493
+ c_spine='r',
494
+ minor_ticks='xy',
495
+ style='paper',
496
+ box=['right','bottom'],
497
+ xrot=-45,
498
+ yangle=20,
499
+ font_sz = 2,
500
+ legend=dict(labels=['group_a','group_b'],
501
+ loc='upper left',
502
+ edgecolor='k',
503
+ facecolor='r',
504
+ title='title',
505
+ fancybox=1,
506
+ shadow=1,
507
+ ncols=4,
508
+ bbox_to_anchor=[-0.5,0.7],
509
+ alignment='left')
510
+ )
511
+ """
512
+ fig = plt.gcf()
513
+ fontsize = 11
514
+ fontname = "Arial"
515
+ sns_themes = ["white", "whitegrid", "dark", "darkgrid", "ticks"]
516
+ sns_contexts = ["notebook", "talk", "poster"] # now available "paper"
517
+ scienceplots_styles = ["science","nature",
518
+ "scatter","ieee","no-latex","std-colors","high-vis","bright","dark_background","science",
519
+ "high-vis","vibrant","muted","retro","grid","high-contrast","light","cjk-tc-font","cjk-kr-font",
520
+ ]
521
+ def set_step_1(ax,key, value):
522
+ if ("fo" in key) and (("size" in key) or ("sz" in key)):
523
+ fontsize=value
524
+ plt.rcParams.update({"font.size": value})
525
+ # style
526
+ if "st" in key.lower() or "th" in key.lower():
527
+ if isinstance(value, str):
528
+ if (value in plt.style.available) or (value in scienceplots_styles):
529
+ plt.style.use(value)
530
+ elif value in sns_themes:
531
+ sns.set_style(value)
532
+ elif value in sns_contexts:
533
+ sns.set_context(value)
534
+ else:
535
+ print(
536
+ f"\nWarning\n'{value}' is not a plt.style,select on below:\n{plt.style.available+sns_themes+sns_contexts+scienceplots_styles}"
537
+ )
538
+ if isinstance(value, list):
539
+ for i in value:
540
+ if (i in plt.style.available) or (i in scienceplots_styles):
541
+ plt.style.use(i)
542
+ elif i in sns_themes:
543
+ sns.set_style(i)
544
+ elif i in sns_contexts:
545
+ sns.set_context(i)
546
+ else:
547
+ print(
548
+ f"\nWarning\n'{i}' is not a plt.style,select on below:\n{plt.style.available+sns_themes+sns_contexts+scienceplots_styles}"
549
+ )
550
+ if "la" in key.lower():
551
+ if "loc" in key.lower() or "po" in key.lower():
552
+ for i in value:
553
+ if "l" in i.lower() and not 'g' in i.lower():
554
+ ax.yaxis.set_label_position("left")
555
+ if "r" in i.lower() and not 'o' in i.lower():
556
+ ax.yaxis.set_label_position("right")
557
+ if "t" in i.lower() and not 'l' in i.lower():
558
+ ax.xaxis.set_label_position("top")
559
+ if "b" in i.lower()and not 'o' in i.lower():
560
+ ax.xaxis.set_label_position("bottom")
561
+ if ("x" in key.lower()) and (
562
+ "tic" not in key.lower() and "tk" not in key.lower()
563
+ ):
564
+ ax.set_xlabel(value, fontname=fontname)
565
+ if ("y" in key.lower()) and (
566
+ "tic" not in key.lower() and "tk" not in key.lower()
567
+ ):
568
+ ax.set_ylabel(value, fontname=fontname)
569
+ if ("z" in key.lower()) and (
570
+ "tic" not in key.lower() and "tk" not in key.lower()
571
+ ):
572
+ ax.set_zlabel(value, fontname=fontname)
573
+ if key=='xlabel' and isinstance(value,dict):
574
+ ax.set_xlabel(**value)
575
+ if key=='ylabel' and isinstance(value,dict):
576
+ ax.set_ylabel(**value)
577
+ # tick location
578
+ if "tic" in key.lower() or "tk" in key.lower():
579
+ if ("loc" in key.lower()) or ("po" in key.lower()):
580
+ if isinstance(value,str):
581
+ value=[value]
582
+ if isinstance(value, list):
583
+ loc = []
584
+ for i in value:
585
+ if ("l" in i.lower()) and ("a" not in i.lower()):
586
+ ax.yaxis.set_ticks_position("left")
587
+ if "r" in i.lower():
588
+ ax.yaxis.set_ticks_position("right")
589
+ if "t" in i.lower():
590
+ ax.xaxis.set_ticks_position("top")
591
+ if "b" in i.lower():
592
+ ax.xaxis.set_ticks_position("bottom")
593
+ if i.lower() in ["a", "both", "all", "al", ":"]:
594
+ ax.xaxis.set_ticks_position("both")
595
+ ax.yaxis.set_ticks_position("both")
596
+ if i.lower() in ["xnone",'xoff',"none"]:
597
+ ax.xaxis.set_ticks_position("none")
598
+ if i.lower() in ["ynone",'yoff','none']:
599
+ ax.yaxis.set_ticks_position("none")
600
+ # ticks / labels
601
+ elif "x" in key.lower():
602
+ if value is None:
603
+ value=[]
604
+ if "la" not in key.lower():
605
+ ax.set_xticks(value)
606
+ if "la" in key.lower():
607
+ ax.set_xticklabels(value)
608
+ elif "y" in key.lower():
609
+ if value is None:
610
+ value=[]
611
+ if "la" not in key.lower():
612
+ ax.set_yticks(value)
613
+ if "la" in key.lower():
614
+ ax.set_yticklabels(value)
615
+ elif "z" in key.lower():
616
+ if value is None:
617
+ value=[]
618
+ if "la" not in key.lower():
619
+ ax.set_zticks(value)
620
+ if "la" in key.lower():
621
+ ax.set_zticklabels(value)
622
+ # rotation
623
+ if "angle" in key.lower() or ("rot" in key.lower()):
624
+ if "x" in key.lower():
625
+ if value in [0,90,180,270]:
626
+ ax.tick_params(axis="x", rotation=value)
627
+ for tick in ax.get_xticklabels():
628
+ tick.set_horizontalalignment('center')
629
+ elif value >0:
630
+ ax.tick_params(axis="x", rotation=value)
631
+ for tick in ax.get_xticklabels():
632
+ tick.set_horizontalalignment('right')
633
+ elif value <0:
634
+ ax.tick_params(axis='x', rotation=value)
635
+ for tick in ax.get_xticklabels():
636
+ tick.set_horizontalalignment('left')
637
+ if "y" in key.lower():
638
+ ax.tick_params(axis="y", rotation=value)
639
+ for tick in ax.get_yticklabels():
640
+ tick.set_horizontalalignment('right')
641
+
642
+ if "bo" in key in key: # box setting, and ("p" in key or "l" in key):
643
+ if isinstance(value, (str, list)):
644
+ locations = []
645
+ for i in value:
646
+ if "l" in i.lower() and not 't' in i.lower():
647
+ locations.append("left")
648
+ if "r" in i.lower()and not 'o' in i.lower(): # right
649
+ locations.append("right")
650
+ if "t" in i.lower() and not 'r' in i.lower(): #top
651
+ locations.append("top")
652
+ if "b" in i.lower() and not 't' in i.lower():
653
+ locations.append("bottom")
654
+ if i.lower() in ["a", "both", "all", "al", ":"]:
655
+ [
656
+ locations.append(x)
657
+ for x in ["left", "right", "top", "bottom"]
658
+ ]
659
+ for i in value:
660
+ if i.lower() in "none":
661
+ locations = []
662
+ # check spines
663
+ for loc, spi in ax.spines.items():
664
+ if loc in locations:
665
+ spi.set_position(("outward", 0))
666
+ else:
667
+ spi.set_color("none") # no spine
668
+ if 'tick' in key.lower(): # tick ticks tick_para ={}
669
+ if isinstance(value, dict):
670
+ for k, val in value.items():
671
+ if "wh" in k.lower():
672
+ ax.tick_params(
673
+ which=val
674
+ ) # {'major', 'minor', 'both'}, default: 'major'
675
+ elif "dir" in k.lower():
676
+ ax.tick_params(direction=val) # {'in', 'out', 'inout'}
677
+ elif "len" in k.lower():# length
678
+ ax.tick_params(length=val)
679
+ elif ("wid" in k.lower()) or ("wd" in k.lower()): # width
680
+ ax.tick_params(width=val)
681
+ elif "ax" in k.lower(): # ax
682
+ ax.tick_params(axis=val) # {'x', 'y', 'both'}, default: 'both'
683
+ elif ("c" in k.lower()) and ("ect" not in k.lower()):
684
+ ax.tick_params(colors=val) # Tick color.
685
+ elif "pad" in k.lower() or 'space' in k.lower():
686
+ ax.tick_params(
687
+ pad=val
688
+ ) # float, distance in points between tick and label
689
+ elif (
690
+ ("lab" in k.lower() or 'text' in k.lower())
691
+ and ("s" in k.lower())
692
+ and ("z" in k.lower())
693
+ ): # label_size
694
+ ax.tick_params(
695
+ labelsize=val
696
+ ) # float, distance in points between tick and label
697
+
698
+ if "mi" in key.lower() and "tic" in key.lower():# minor_ticks
699
+ if "x" in value.lower() or "x" in key.lower():
700
+ ax.xaxis.set_minor_locator(tck.AutoMinorLocator()) # ax.minorticks_on()
701
+ if "y" in value.lower() or "y" in key.lower():
702
+ ax.yaxis.set_minor_locator(
703
+ tck.AutoMinorLocator()
704
+ ) # ax.minorticks_off()
705
+ if value.lower() in ["both", ":", "all", "a", "b", "on"]:
706
+ ax.minorticks_on()
707
+ if key == "colormap" or key == "cmap":
708
+ plt.set_cmap(value)
709
+ def set_step_2(ax,key, value):
710
+ if key == "figsize":
711
+ pass
712
+ if "xlim" in key.lower():
713
+ ax.set_xlim(value)
714
+ if "ylim" in key.lower():
715
+ ax.set_ylim(value)
716
+ if "zlim" in key.lower():
717
+ ax.set_zlim(value)
718
+ if "sc" in key.lower(): #scale
719
+ if "x" in key.lower():
720
+ ax.set_xscale(value)
721
+ if "y" in key.lower():
722
+ ax.set_yscale(value)
723
+ if "z" in key.lower():
724
+ ax.set_zscale(value)
725
+ if key == "grid":
726
+ if isinstance(value, dict):
727
+ for k, val in value.items():
728
+ if "wh" in k.lower(): # which
729
+ ax.grid(
730
+ which=val
731
+ ) # {'major', 'minor', 'both'}, default: 'major'
732
+ elif "ax" in k.lower(): # ax
733
+ ax.grid(axis=val) # {'x', 'y', 'both'}, default: 'both'
734
+ elif ("c" in k.lower()) and ("ect" not in k.lower()): # c: color
735
+ ax.grid(color=val) # Tick color.
736
+ elif "l" in k.lower() and ("s" in k.lower()):# ls:line stype
737
+ ax.grid(linestyle=val)
738
+ elif "l" in k.lower() and ("w" in k.lower()): # lw: line width
739
+ ax.grid(linewidth=val)
740
+ elif "al" in k.lower():# alpha:
741
+ ax.grid(alpha=val)
742
+ else:
743
+ if value == "on" or value is True:
744
+ ax.grid(visible=True)
745
+ elif value == "off" or value is False:
746
+ ax.grid(visible=False)
747
+ if "tit" in key.lower():
748
+ if "sup" in key.lower():
749
+ plt.suptitle(value)
750
+ else:
751
+ ax.set_title(value)
752
+ if key.lower() in ["spine", "adjust", "ad", "sp", "spi", "adj","spines"]:
753
+ if isinstance(value, bool) or (value in ["go", "do", "ja", "yes"]):
754
+ if value:
755
+ adjust_spines(ax) # dafault distance=2
756
+ if isinstance(value, (float, int)):
757
+ adjust_spines(ax=ax, distance=value)
758
+ if "c" in key.lower() and ("sp" in key.lower() or "ax" in key.lower()):# spine color
759
+ for loc, spi in ax.spines.items():
760
+ spi.set_color(value)
761
+ if 'leg' in key.lower(): # legend
762
+ legend_kws = kwargs.get('legend', None)
763
+ if legend_kws:
764
+ # https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html
765
+ ax.legend(**legend_kws)
766
+
767
+ for arg in args:
768
+ if isinstance(arg,matplotlib.axes._axes.Axes):
769
+ ax=arg
770
+ args=args[1:]
771
+ ax = kwargs.get('ax',plt.gca())
772
+ if 'ax' not in locals() or ax is None:
773
+ ax=plt.gca()
774
+ for key, value in kwargs.items():
775
+ set_step_1(ax, key, value)
776
+ set_step_2(ax, key, value)
777
+ for arg in args:
778
+ if isinstance(arg, dict):
779
+ for k, val in arg.items():
780
+ set_step_1(ax,k, val)
781
+ for k, val in arg.items():
782
+ set_step_2(ax,k, val)
783
+ else:
784
+ Nargin = len(args) // 2
785
+ ax.labelFontSizeMultiplier = 1
786
+ ax.titleFontSizeMultiplier = 1
787
+ ax.set_facecolor("w")
788
+
789
+ for ip in range(Nargin):
790
+ key = args[ip * 2].lower()
791
+ value = args[ip * 2 + 1]
792
+ set_step_1(ax,key, value)
793
+ for ip in range(Nargin):
794
+ key = args[ip * 2].lower()
795
+ value = args[ip * 2 + 1]
796
+ set_step_2(ax,key, value)
797
+ colors = [
798
+ "#474747",
799
+ "#FF2C00",
800
+ "#0C5DA5",
801
+ "#845B97",
802
+ "#58BBCC",
803
+ "#FF9500",
804
+ "#D57DBE",
805
+ ]
806
+ matplotlib.rcParams["axes.prop_cycle"] = cycler(color=colors)
807
+ if len(fig.get_axes()) > 1:
808
+ plt.tight_layout()
809
+ plt.gcf().align_labels()
810
+
811
+
812
+
813
+ from cycler import cycler
814
+
815
+ # set up the colorlist, give the number, or the colormap's name
816
+ def get_color(n=1, cmap="auto", by="start"):
817
+ # Extract the colormap as a list
818
+ def cmap2hex(cmap_name):
819
+ cmap_ = matplotlib.pyplot.get_cmap(cmap_name)
820
+ colors = [cmap_(i) for i in range(cmap_.N)]
821
+ return [matplotlib.colors.rgb2hex(color) for color in colors]
822
+ # usage: clist = cmap2hex("viridis")
823
+ # cycle times, total number is n (defaultn=10)
824
+ def cycle2list(colorlist, n=10):
825
+ cycler_ = cycler(tmp=colorlist)
826
+ clist = []
827
+ for i, c_ in zip(range(n), cycler_()):
828
+ clist.append(c_["tmp"])
829
+ if i > n:
830
+ break
831
+ return clist
832
+ def hue2rgb(hex_colors):
833
+ def hex_to_rgb(hex_color):
834
+ """Converts a hexadecimal color code to RGB values."""
835
+ if hex_colors.startswith("#"):
836
+ hex_color = hex_color.lstrip("#")
837
+ return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
838
+ if isinstance(hex_colors, str):
839
+ return hex_to_rgb(hex_colors)
840
+ elif isinstance(hex_colors, (list)):
841
+ """Converts a list of hexadecimal color codes to a list of RGB values."""
842
+ rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
843
+ return rgb_values
844
+ if "aut" in cmap:
845
+ colorlist = [
846
+ "#474747",
847
+ "#FF2C00",
848
+ "#0C5DA5",
849
+ "#845B97",
850
+ "#58BBCC",
851
+ "#FF9500",
852
+ "#D57DBE",
853
+ ]
854
+ else:
855
+ colorlist = cmap2hex(cmap)
856
+ if "st" in by.lower() or "be" in by.lower():
857
+ # cycle it
858
+ clist = cycle2list(colorlist, n=n)
859
+ if "l" in by.lower() or "p" in by.lower():
860
+ clist = []
861
+ [
862
+ clist.append(colorlist[i])
863
+ for i in [int(i) for i in np.linspace(0, len(colorlist) - 1, n)]
864
+ ]
865
+
866
+ return clist # a color list
867
+ # example usage: clist = get_color(4,cmap="auto", by="start") # get_color(4, cmap="hot", by="linspace")
868
+
869
+ """
870
+ # n = 7
871
+ # clist = get_color(n, cmap="auto", by="linspace") # get_color(100)
872
+ # plt.figure(figsize=[8, 5], dpi=100)
873
+ # x = np.linspace(0, 2 * np.pi, 50) * 100
874
+ # y = np.sin(x)
875
+ # for i in range(1, n + 1):
876
+ # plt.plot(x, y + i, c=clist[i - 1], lw=5, label=str(i))
877
+ # plt.legend()
878
+ # plt.ylim(-2, 20)
879
+ # figsets(plt.gca(), {"style": "whitegrid"}) """
880
+
881
+
882
+
883
+ from scipy.signal import savgol_filter
884
+ import numpy as np
885
+ import matplotlib.pyplot as plt
886
+
887
+ def stdshade(ax=None,*args, **kwargs):
888
+ # Separate kws_line and kws_fill if necessary
889
+ kws_line = kwargs.pop('kws_line', {})
890
+ kws_fill = kwargs.pop('kws_fill', {})
891
+
892
+ # Merge kws_line and kws_fill into kwargs
893
+ kwargs.update(kws_line)
894
+ kwargs.update(kws_fill)
895
+ def str2list(str_):
896
+ l = []
897
+ [l.append(x) for x in str_]
898
+ return l
899
+ def hue2rgb(hex_colors):
900
+ def hex_to_rgb(hex_color):
901
+ """Converts a hexadecimal color code to RGB values."""
902
+ if hex_colors.startswith("#"):
903
+ hex_color = hex_color.lstrip("#")
904
+ return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
905
+ if isinstance(hex_colors, str):
906
+ return hex_to_rgb(hex_colors)
907
+ elif isinstance(hex_colors, (list)):
908
+ """Converts a list of hexadecimal color codes to a list of RGB values."""
909
+ rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
910
+ return rgb_values
911
+ if (
912
+ isinstance(ax, np.ndarray)
913
+ and ax.ndim == 2
914
+ and min(ax.shape) > 1
915
+ and max(ax.shape) > 1
916
+ ):
917
+ y = ax
918
+ ax = plt.gca()
919
+ if ax is None:
920
+ ax = plt.gca()
921
+ alpha = 0.5
922
+ acolor = "k"
923
+ paraStdSem = "sem"
924
+ plotStyle = "-"
925
+ plotMarker = "none"
926
+ smth = 1
927
+ l_c_one = ["r", "g", "b", "m", "c", "y", "k", "w"]
928
+ l_style2 = ["--", "-."]
929
+ l_style1 = ["-", ":"]
930
+ l_mark = ["o", "+", "*", ".", "x", "_", "|", "s", "d", "^", "v", ">", "<", "p", "h"]
931
+ # Check each argument
932
+ for iarg in range(len(args)):
933
+ if (
934
+ isinstance(args[iarg], np.ndarray)
935
+ and args[iarg].ndim == 2
936
+ and min(args[iarg].shape) > 1
937
+ and max(args[iarg].shape) > 1
938
+ ):
939
+ y = args[iarg]
940
+ # Except y, continuous data is 'F'
941
+ if (isinstance(args[iarg], np.ndarray) and args[iarg].ndim == 1) or isinstance(
942
+ args[iarg], range
943
+ ):
944
+ x = args[iarg]
945
+ if isinstance(x, range):
946
+ x = np.arange(start=x.start, stop=x.stop, step=x.step)
947
+ # Only one number( 0~1), 'alpha' / color
948
+ if isinstance(args[iarg], (int, float)):
949
+ if np.size(args[iarg]) == 1 and 0 <= args[iarg] <= 1:
950
+ alpha = args[iarg]
951
+ if isinstance(args[iarg], (list, tuple)) and np.size(args[iarg]) == 3:
952
+ acolor = args[iarg]
953
+ acolor = tuple(acolor) if isinstance(acolor, list) else acolor
954
+ # Color / plotStyle /
955
+ if (
956
+ isinstance(args[iarg], str)
957
+ and len(args[iarg]) == 1
958
+ and args[iarg] in l_c_one
959
+ ):
960
+ acolor = args[iarg]
961
+ else:
962
+ if isinstance(args[iarg], str):
963
+ if args[iarg] in ["sem", "std"]:
964
+ paraStdSem = args[iarg]
965
+ if args[iarg].startswith("#"):
966
+ acolor=hue2rgb(args[iarg])
967
+ if str2list(args[iarg])[0] in l_c_one:
968
+ if len(args[iarg]) == 3:
969
+ k = [i for i in str2list(args[iarg]) if i in l_c_one]
970
+ if k != []:
971
+ acolor = k[0]
972
+ st = [i for i in l_style2 if i in args[iarg]]
973
+ if st != []:
974
+ plotStyle = st[0]
975
+ elif len(args[iarg]) == 2:
976
+ k = [i for i in str2list(args[iarg]) if i in l_c_one]
977
+ if k != []:
978
+ acolor = k[0]
979
+ mk = [i for i in str2list(args[iarg]) if i in l_mark]
980
+ if mk != []:
981
+ plotMarker = mk[0]
982
+ st = [i for i in l_style1 if i in args[iarg]]
983
+ if st != []:
984
+ plotStyle = st[0]
985
+ if len(args[iarg]) == 1:
986
+ k = [i for i in str2list(args[iarg]) if i in l_c_one]
987
+ if k != []:
988
+ acolor = k[0]
989
+ mk = [i for i in str2list(args[iarg]) if i in l_mark]
990
+ if mk != []:
991
+ plotMarker = mk[0]
992
+ st = [i for i in l_style1 if i in args[iarg]]
993
+ if st != []:
994
+ plotStyle = st[0]
995
+ if len(args[iarg]) == 2:
996
+ st = [i for i in l_style2 if i in args[iarg]]
997
+ if st != []:
998
+ plotStyle = st[0]
999
+ # smth
1000
+ if (
1001
+ isinstance(args[iarg], (int, float))
1002
+ and np.size(args[iarg]) == 1
1003
+ and args[iarg] >= 1
1004
+ ):
1005
+ smth = args[iarg]
1006
+ smth = kwargs.get('smth', smth)
1007
+ if "x" not in locals() or x is None:
1008
+ x = np.arange(1, y.shape[1] + 1)
1009
+ elif len(x) < y.shape[1]:
1010
+ y = y[:, x]
1011
+ nRow = y.shape[0]
1012
+ nCol = y.shape[1]
1013
+ print(f"y was corrected, please confirm that {nRow} row, {nCol} col")
1014
+ else:
1015
+ x = np.arange(1, y.shape[1] + 1)
1016
+
1017
+ if x.shape[0] != 1:
1018
+ x = x.T
1019
+ yMean = np.nanmean(y, axis=0)
1020
+ if smth > 1:
1021
+ yMean = savgol_filter(np.nanmean(y, axis=0), smth, 1)
1022
+ else:
1023
+ yMean = np.nanmean(y, axis=0)
1024
+ if paraStdSem == "sem":
1025
+ if smth > 1:
1026
+ wings = savgol_filter(np.nanstd(y, axis=0) / np.sqrt(y.shape[0]), smth, 1)
1027
+ else:
1028
+ wings = np.nanstd(y, axis=0) / np.sqrt(y.shape[0])
1029
+ elif paraStdSem == "std":
1030
+ if smth > 1:
1031
+ wings = savgol_filter(np.nanstd(y, axis=0), smth, 1)
1032
+ else:
1033
+ wings = np.nanstd(y, axis=0)
1034
+
1035
+ # fill_kws = kwargs.get('fill_kws', {})
1036
+ # line_kws = kwargs.get('line_kws', {})
1037
+
1038
+ # setting form kwargs
1039
+ lw = kwargs.get('lw', 1.5)
1040
+ ls= kwargs.get('ls', plotStyle)
1041
+ marker=kwargs.get("marker",plotMarker)
1042
+ label=kwargs.get("label",None)
1043
+ label_line = kwargs.get("label_line",None)
1044
+ label_fill = kwargs.get('label_fill',None)
1045
+ alpha=kwargs.get('alpha',alpha)
1046
+ color=kwargs.get('color', acolor)
1047
+ if not label_line and label:
1048
+ label_line = label
1049
+ kwargs['lw'] = lw
1050
+ kwargs['ls'] = ls
1051
+ kwargs['label_line'] = label_line
1052
+ kwargs['label_fill'] = label_fill
1053
+
1054
+ # set kws_line
1055
+ if 'color' not in kws_line:
1056
+ kws_line['color']=color
1057
+ if 'lw' not in kws_line:
1058
+ kws_line['lw']=lw
1059
+ if 'ls' not in kws_line:
1060
+ kws_line['ls']=ls
1061
+ if 'marker' not in kws_line:
1062
+ kws_line['marker']=marker
1063
+ if 'label' not in kws_line:
1064
+ kws_line['label']=label_line
1065
+
1066
+ # set kws_line
1067
+ if 'color' not in kws_fill:
1068
+ kws_fill['color']=color
1069
+ if 'alpha' not in kws_fill:
1070
+ kws_fill['alpha']=alpha
1071
+ if 'lw' not in kws_fill:
1072
+ kws_fill['lw']=0
1073
+ if 'label' not in kws_fill:
1074
+ kws_fill['label']=label_fill
1075
+
1076
+ fill = ax.fill_between(x, yMean + wings, yMean - wings, **kws_fill)
1077
+ line = ax.plot(x, yMean, **kws_line)
1078
+ return line[0], fill
1079
+
1080
+
1081
+ """
1082
+ ########## Usage 1 ##########
1083
+ plot.stdshade(data,
1084
+ 'b',
1085
+ ':',
1086
+ 'd',
1087
+ 0.1,
1088
+ 4,
1089
+ label='ddd',
1090
+ label_line='label_line',
1091
+ label_fill="label-fill")
1092
+ plt.legend()
1093
+
1094
+ ########## Usage 2 ##########
1095
+ plot.stdshade(data,
1096
+ 'm-',
1097
+ alpha=0.1,
1098
+ lw=2,
1099
+ ls=':',
1100
+ marker='d',
1101
+ color='b',
1102
+ smth=4,
1103
+ label='ddd',
1104
+ label_line='label_line',
1105
+ label_fill="label-fill")
1106
+ plt.legend()
1107
+
1108
+ """
1109
+