py2ls 0.1.6.1__py3-none-any.whl → 0.1.6.2__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/ips.py +17 -3
- py2ls/plot/catplot.py +437 -0
- py2ls/{plot.py → plot/figsets.py} +39 -319
- py2ls/plot/get_color.py +68 -0
- py2ls/plot/stdshade.py +227 -0
- {py2ls-0.1.6.1.dist-info → py2ls-0.1.6.2.dist-info}/METADATA +1 -1
- {py2ls-0.1.6.1.dist-info → py2ls-0.1.6.2.dist-info}/RECORD +8 -5
- {py2ls-0.1.6.1.dist-info → py2ls-0.1.6.2.dist-info}/WHEEL +1 -1
py2ls/ips.py
CHANGED
@@ -879,8 +879,9 @@ def fload(fpath, kind=None, **kwargs):
|
|
879
879
|
root = tree.getroot()
|
880
880
|
return etree.tostring(root, pretty_print=True).decode()
|
881
881
|
|
882
|
-
def load_csv(fpath,
|
883
|
-
|
882
|
+
def load_csv(fpath, engine='pyarrow',**kwargs):
|
883
|
+
print(f"engine={engine}")
|
884
|
+
df = pd.read_csv(fpath, engine=engine, **kwargs)
|
884
885
|
return df
|
885
886
|
|
886
887
|
def load_xlsx(fpath, **kwargs):
|
@@ -2169,9 +2170,22 @@ def figsets(*args,**kwargs):
|
|
2169
2170
|
# rotation
|
2170
2171
|
if "angle" in key.lower() or ("rot" in key.lower()):
|
2171
2172
|
if "x" in key.lower():
|
2172
|
-
|
2173
|
+
if value in [0,90,180,270]:
|
2174
|
+
ax.tick_params(axis="x", rotation=value)
|
2175
|
+
for tick in ax.get_xticklabels():
|
2176
|
+
tick.set_horizontalalignment('center')
|
2177
|
+
elif value >0:
|
2178
|
+
ax.tick_params(axis="x", rotation=value)
|
2179
|
+
for tick in ax.get_xticklabels():
|
2180
|
+
tick.set_horizontalalignment('right')
|
2181
|
+
elif value <0:
|
2182
|
+
ax.tick_params(axis='x', rotation=value)
|
2183
|
+
for tick in ax.get_xticklabels():
|
2184
|
+
tick.set_horizontalalignment('left')
|
2173
2185
|
if "y" in key.lower():
|
2174
2186
|
ax.tick_params(axis="y", rotation=value)
|
2187
|
+
for tick in ax.get_yticklabels():
|
2188
|
+
tick.set_horizontalalignment('right')
|
2175
2189
|
|
2176
2190
|
if "bo" in key in key: # box setting, and ("p" in key or "l" in key):
|
2177
2191
|
if isinstance(value, (str, list)):
|
py2ls/plot/catplot.py
ADDED
@@ -0,0 +1,437 @@
|
|
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
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
import numpy as np
|
3
3
|
import matplotlib
|
4
4
|
import matplotlib.pyplot as plt
|
@@ -7,6 +7,9 @@ import seaborn as sns
|
|
7
7
|
from cycler import cycler
|
8
8
|
|
9
9
|
|
10
|
+
def get_cmap():
|
11
|
+
return plt.colormaps()
|
12
|
+
|
10
13
|
def read_mplstyle(style_file):
|
11
14
|
# Load the style file
|
12
15
|
plt.style.use(style_file)
|
@@ -24,317 +27,6 @@ def read_mplstyle(style_file):
|
|
24
27
|
# style_file = "/ std-colors.mplstyle"
|
25
28
|
# style_dict = read_mplstyle(style_file)
|
26
29
|
|
27
|
-
|
28
|
-
# set up the colorlist, give the number, or the colormap's name
|
29
|
-
def get_color(n=1, cmap="auto", by="start"):
|
30
|
-
# Extract the colormap as a list
|
31
|
-
def cmap2hex(cmap_name):
|
32
|
-
cmap_ = matplotlib.pyplot.get_cmap(cmap_name)
|
33
|
-
colors = [cmap_(i) for i in range(cmap_.N)]
|
34
|
-
return [matplotlib.colors.rgb2hex(color) for color in colors]
|
35
|
-
# usage: clist = cmap2hex("viridis")
|
36
|
-
# cycle times, total number is n (defaultn=10)
|
37
|
-
def cycle2list(colorlist, n=10):
|
38
|
-
cycler_ = cycler(tmp=colorlist)
|
39
|
-
clist = []
|
40
|
-
for i, c_ in zip(range(n), cycler_()):
|
41
|
-
clist.append(c_["tmp"])
|
42
|
-
if i > n:
|
43
|
-
break
|
44
|
-
return clist
|
45
|
-
def hue2rgb(hex_colors):
|
46
|
-
def hex_to_rgb(hex_color):
|
47
|
-
"""Converts a hexadecimal color code to RGB values."""
|
48
|
-
if hex_colors.startswith("#"):
|
49
|
-
hex_color = hex_color.lstrip("#")
|
50
|
-
return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
|
51
|
-
if isinstance(hex_colors, str):
|
52
|
-
return hex_to_rgb(hex_colors)
|
53
|
-
elif isinstance(hex_colors, (list)):
|
54
|
-
"""Converts a list of hexadecimal color codes to a list of RGB values."""
|
55
|
-
rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
|
56
|
-
return rgb_values
|
57
|
-
if "aut" in cmap:
|
58
|
-
colorlist = [
|
59
|
-
"#474747",
|
60
|
-
"#FF2C00",
|
61
|
-
"#0C5DA5",
|
62
|
-
"#845B97",
|
63
|
-
"#58BBCC",
|
64
|
-
"#FF9500",
|
65
|
-
"#D57DBE",
|
66
|
-
]
|
67
|
-
else:
|
68
|
-
colorlist = cmap2hex(cmap)
|
69
|
-
if "st" in by.lower() or "be" in by.lower():
|
70
|
-
# cycle it
|
71
|
-
clist = cycle2list(colorlist, n=n)
|
72
|
-
if "l" in by.lower() or "p" in by.lower():
|
73
|
-
clist = []
|
74
|
-
[
|
75
|
-
clist.append(colorlist[i])
|
76
|
-
for i in [int(i) for i in np.linspace(0, len(colorlist) - 1, n)]
|
77
|
-
]
|
78
|
-
|
79
|
-
return clist # a color list
|
80
|
-
# example usage: clist = get_color(4,cmap="auto", by="start") # get_color(4, cmap="hot", by="linspace")
|
81
|
-
|
82
|
-
"""
|
83
|
-
# n = 7
|
84
|
-
# clist = get_color(n, cmap="auto", by="linspace") # get_color(100)
|
85
|
-
# plt.figure(figsize=[8, 5], dpi=100)
|
86
|
-
# x = np.linspace(0, 2 * np.pi, 50) * 100
|
87
|
-
# y = np.sin(x)
|
88
|
-
# for i in range(1, n + 1):
|
89
|
-
# plt.plot(x, y + i, c=clist[i - 1], lw=5, label=str(i))
|
90
|
-
# plt.legend()
|
91
|
-
# plt.ylim(-2, 20)
|
92
|
-
# figsets(plt.gca(), {"style": "whitegrid"}) """
|
93
|
-
|
94
|
-
def stdshade(ax=None,*args, **kwargs):
|
95
|
-
# Separate kws_line and kws_fill if necessary
|
96
|
-
kws_line = kwargs.pop('kws_line', {})
|
97
|
-
kws_fill = kwargs.pop('kws_fill', {})
|
98
|
-
|
99
|
-
# Merge kws_line and kws_fill into kwargs
|
100
|
-
kwargs.update(kws_line)
|
101
|
-
kwargs.update(kws_fill)
|
102
|
-
def str2list(str_):
|
103
|
-
l = []
|
104
|
-
[l.append(x) for x in str_]
|
105
|
-
return l
|
106
|
-
def hue2rgb(hex_colors):
|
107
|
-
def hex_to_rgb(hex_color):
|
108
|
-
"""Converts a hexadecimal color code to RGB values."""
|
109
|
-
if hex_colors.startswith("#"):
|
110
|
-
hex_color = hex_color.lstrip("#")
|
111
|
-
return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
|
112
|
-
if isinstance(hex_colors, str):
|
113
|
-
return hex_to_rgb(hex_colors)
|
114
|
-
elif isinstance(hex_colors, (list)):
|
115
|
-
"""Converts a list of hexadecimal color codes to a list of RGB values."""
|
116
|
-
rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
|
117
|
-
return rgb_values
|
118
|
-
if (
|
119
|
-
isinstance(ax, np.ndarray)
|
120
|
-
and ax.ndim == 2
|
121
|
-
and min(ax.shape) > 1
|
122
|
-
and max(ax.shape) > 1
|
123
|
-
):
|
124
|
-
y = ax
|
125
|
-
ax = plt.gca()
|
126
|
-
if ax is None:
|
127
|
-
ax = plt.gca()
|
128
|
-
alpha = 0.5
|
129
|
-
acolor = "k"
|
130
|
-
paraStdSem = "sem"
|
131
|
-
plotStyle = "-"
|
132
|
-
plotMarker = "none"
|
133
|
-
smth = 1
|
134
|
-
l_c_one = ["r", "g", "b", "m", "c", "y", "k", "w"]
|
135
|
-
l_style2 = ["--", "-."]
|
136
|
-
l_style1 = ["-", ":"]
|
137
|
-
l_mark = ["o", "+", "*", ".", "x", "_", "|", "s", "d", "^", "v", ">", "<", "p", "h"]
|
138
|
-
# Check each argument
|
139
|
-
for iarg in range(len(args)):
|
140
|
-
if (
|
141
|
-
isinstance(args[iarg], np.ndarray)
|
142
|
-
and args[iarg].ndim == 2
|
143
|
-
and min(args[iarg].shape) > 1
|
144
|
-
and max(args[iarg].shape) > 1
|
145
|
-
):
|
146
|
-
y = args[iarg]
|
147
|
-
# Except y, continuous data is 'F'
|
148
|
-
if (isinstance(args[iarg], np.ndarray) and args[iarg].ndim == 1) or isinstance(
|
149
|
-
args[iarg], range
|
150
|
-
):
|
151
|
-
x = args[iarg]
|
152
|
-
if isinstance(x, range):
|
153
|
-
x = np.arange(start=x.start, stop=x.stop, step=x.step)
|
154
|
-
# Only one number( 0~1), 'alpha' / color
|
155
|
-
if isinstance(args[iarg], (int, float)):
|
156
|
-
if np.size(args[iarg]) == 1 and 0 <= args[iarg] <= 1:
|
157
|
-
alpha = args[iarg]
|
158
|
-
if isinstance(args[iarg], (list, tuple)) and np.size(args[iarg]) == 3:
|
159
|
-
acolor = args[iarg]
|
160
|
-
acolor = tuple(acolor) if isinstance(acolor, list) else acolor
|
161
|
-
# Color / plotStyle /
|
162
|
-
if (
|
163
|
-
isinstance(args[iarg], str)
|
164
|
-
and len(args[iarg]) == 1
|
165
|
-
and args[iarg] in l_c_one
|
166
|
-
):
|
167
|
-
acolor = args[iarg]
|
168
|
-
else:
|
169
|
-
if isinstance(args[iarg], str):
|
170
|
-
if args[iarg] in ["sem", "std"]:
|
171
|
-
paraStdSem = args[iarg]
|
172
|
-
if args[iarg].startswith("#"):
|
173
|
-
acolor=hue2rgb(args[iarg])
|
174
|
-
if str2list(args[iarg])[0] in l_c_one:
|
175
|
-
if len(args[iarg]) == 3:
|
176
|
-
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
177
|
-
if k != []:
|
178
|
-
acolor = k[0]
|
179
|
-
st = [i for i in l_style2 if i in args[iarg]]
|
180
|
-
if st != []:
|
181
|
-
plotStyle = st[0]
|
182
|
-
elif len(args[iarg]) == 2:
|
183
|
-
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
184
|
-
if k != []:
|
185
|
-
acolor = k[0]
|
186
|
-
mk = [i for i in str2list(args[iarg]) if i in l_mark]
|
187
|
-
if mk != []:
|
188
|
-
plotMarker = mk[0]
|
189
|
-
st = [i for i in l_style1 if i in args[iarg]]
|
190
|
-
if st != []:
|
191
|
-
plotStyle = st[0]
|
192
|
-
if len(args[iarg]) == 1:
|
193
|
-
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
194
|
-
if k != []:
|
195
|
-
acolor = k[0]
|
196
|
-
mk = [i for i in str2list(args[iarg]) if i in l_mark]
|
197
|
-
if mk != []:
|
198
|
-
plotMarker = mk[0]
|
199
|
-
st = [i for i in l_style1 if i in args[iarg]]
|
200
|
-
if st != []:
|
201
|
-
plotStyle = st[0]
|
202
|
-
if len(args[iarg]) == 2:
|
203
|
-
st = [i for i in l_style2 if i in args[iarg]]
|
204
|
-
if st != []:
|
205
|
-
plotStyle = st[0]
|
206
|
-
# smth
|
207
|
-
if (
|
208
|
-
isinstance(args[iarg], (int, float))
|
209
|
-
and np.size(args[iarg]) == 1
|
210
|
-
and args[iarg] >= 1
|
211
|
-
):
|
212
|
-
smth = args[iarg]
|
213
|
-
smth = kwargs.get('smth', smth)
|
214
|
-
if "x" not in locals() or x is None:
|
215
|
-
x = np.arange(1, y.shape[1] + 1)
|
216
|
-
elif len(x) < y.shape[1]:
|
217
|
-
y = y[:, x]
|
218
|
-
nRow = y.shape[0]
|
219
|
-
nCol = y.shape[1]
|
220
|
-
print(f"y was corrected, please confirm that {nRow} row, {nCol} col")
|
221
|
-
else:
|
222
|
-
x = np.arange(1, y.shape[1] + 1)
|
223
|
-
|
224
|
-
if x.shape[0] != 1:
|
225
|
-
x = x.T
|
226
|
-
yMean = np.nanmean(y, axis=0)
|
227
|
-
if smth > 1:
|
228
|
-
yMean = savgol_filter(np.nanmean(y, axis=0), smth, 1)
|
229
|
-
else:
|
230
|
-
yMean = np.nanmean(y, axis=0)
|
231
|
-
if paraStdSem == "sem":
|
232
|
-
if smth > 1:
|
233
|
-
wings = savgol_filter(np.nanstd(y, axis=0) / np.sqrt(y.shape[0]), smth, 1)
|
234
|
-
else:
|
235
|
-
wings = np.nanstd(y, axis=0) / np.sqrt(y.shape[0])
|
236
|
-
elif paraStdSem == "std":
|
237
|
-
if smth > 1:
|
238
|
-
wings = savgol_filter(np.nanstd(y, axis=0), smth, 1)
|
239
|
-
else:
|
240
|
-
wings = np.nanstd(y, axis=0)
|
241
|
-
|
242
|
-
# fill_kws = kwargs.get('fill_kws', {})
|
243
|
-
# line_kws = kwargs.get('line_kws', {})
|
244
|
-
|
245
|
-
# setting form kwargs
|
246
|
-
lw = kwargs.get('lw', 1.5)
|
247
|
-
ls= kwargs.get('ls', plotStyle)
|
248
|
-
marker=kwargs.get("marker",plotMarker)
|
249
|
-
label=kwargs.get("label",None)
|
250
|
-
label_line = kwargs.get("label_line",None)
|
251
|
-
label_fill = kwargs.get('label_fill',None)
|
252
|
-
alpha=kwargs.get('alpha',alpha)
|
253
|
-
color=kwargs.get('color', acolor)
|
254
|
-
if not label_line and label:
|
255
|
-
label_line = label
|
256
|
-
kwargs['lw'] = lw
|
257
|
-
kwargs['ls'] = ls
|
258
|
-
kwargs['label_line'] = label_line
|
259
|
-
kwargs['label_fill'] = label_fill
|
260
|
-
|
261
|
-
# set kws_line
|
262
|
-
if 'color' not in kws_line:
|
263
|
-
kws_line['color']=color
|
264
|
-
if 'lw' not in kws_line:
|
265
|
-
kws_line['lw']=lw
|
266
|
-
if 'ls' not in kws_line:
|
267
|
-
kws_line['ls']=ls
|
268
|
-
if 'marker' not in kws_line:
|
269
|
-
kws_line['marker']=marker
|
270
|
-
if 'label' not in kws_line:
|
271
|
-
kws_line['label']=label_line
|
272
|
-
|
273
|
-
# set kws_line
|
274
|
-
if 'color' not in kws_fill:
|
275
|
-
kws_fill['color']=color
|
276
|
-
if 'alpha' not in kws_fill:
|
277
|
-
kws_fill['alpha']=alpha
|
278
|
-
if 'lw' not in kws_fill:
|
279
|
-
kws_fill['lw']=0
|
280
|
-
if 'label' not in kws_fill:
|
281
|
-
kws_fill['label']=label_fill
|
282
|
-
|
283
|
-
fill = ax.fill_between(x, yMean + wings, yMean - wings, **kws_fill)
|
284
|
-
line = ax.plot(x, yMean, **kws_line)
|
285
|
-
return line[0], fill
|
286
|
-
|
287
|
-
|
288
|
-
"""
|
289
|
-
########## Usage 1 ##########
|
290
|
-
plot.stdshade(data,
|
291
|
-
'b',
|
292
|
-
':',
|
293
|
-
'd',
|
294
|
-
0.1,
|
295
|
-
4,
|
296
|
-
label='ddd',
|
297
|
-
label_line='label_line',
|
298
|
-
label_fill="label-fill")
|
299
|
-
plt.legend()
|
300
|
-
|
301
|
-
########## Usage 2 ##########
|
302
|
-
plot.stdshade(data,
|
303
|
-
'm-',
|
304
|
-
alpha=0.1,
|
305
|
-
lw=2,
|
306
|
-
ls=':',
|
307
|
-
marker='d',
|
308
|
-
color='b',
|
309
|
-
smth=4,
|
310
|
-
label='ddd',
|
311
|
-
label_line='label_line',
|
312
|
-
label_fill="label-fill")
|
313
|
-
plt.legend()
|
314
|
-
|
315
|
-
"""
|
316
|
-
|
317
|
-
def adjust_spines(ax=None, spines=['left', 'bottom'],distance=2):
|
318
|
-
if ax is None:
|
319
|
-
ax = plt.gca()
|
320
|
-
for loc, spine in ax.spines.items():
|
321
|
-
if loc in spines:
|
322
|
-
spine.set_position(('outward', distance)) # outward by 2 points
|
323
|
-
# spine.set_smart_bounds(True)
|
324
|
-
else:
|
325
|
-
spine.set_color('none') # don't draw spine
|
326
|
-
# turn off ticks where there is no spine
|
327
|
-
if 'left' in spines:
|
328
|
-
ax.yaxis.set_ticks_position('left')
|
329
|
-
else:
|
330
|
-
ax.yaxis.set_ticks([])
|
331
|
-
if 'bottom' in spines:
|
332
|
-
ax.xaxis.set_ticks_position('bottom')
|
333
|
-
else:
|
334
|
-
# no xaxis ticks
|
335
|
-
ax.xaxis.set_ticks([])
|
336
|
-
|
337
|
-
|
338
30
|
def figsets(*args,**kwargs):
|
339
31
|
"""
|
340
32
|
usage:
|
@@ -367,7 +59,17 @@ def figsets(*args,**kwargs):
|
|
367
59
|
box=['right','bottom'],
|
368
60
|
xrot=-45,
|
369
61
|
yangle=20,
|
370
|
-
font_sz = 2
|
62
|
+
font_sz = 2,
|
63
|
+
legend=dict(labels=['group_a','group_b'],
|
64
|
+
loc='upper left',
|
65
|
+
edgecolor='k',
|
66
|
+
facecolor='r',
|
67
|
+
title='title',
|
68
|
+
fancybox=1,
|
69
|
+
shadow=1,
|
70
|
+
ncols=4,
|
71
|
+
bbox_to_anchor=[-0.5,0.7],
|
72
|
+
alignment='left')
|
371
73
|
)
|
372
74
|
"""
|
373
75
|
fig = plt.gcf()
|
@@ -431,6 +133,10 @@ def figsets(*args,**kwargs):
|
|
431
133
|
"tic" not in key.lower() and "tk" not in key.lower()
|
432
134
|
):
|
433
135
|
ax.set_zlabel(value, fontname=fontname)
|
136
|
+
if key=='xlabel' and isinstance(value,dict):
|
137
|
+
ax.set_xlabel(**value)
|
138
|
+
if key=='ylabel' and isinstance(value,dict):
|
139
|
+
ax.set_ylabel(**value)
|
434
140
|
# tick location
|
435
141
|
if "tic" in key.lower() or "tk" in key.lower():
|
436
142
|
if ("loc" in key.lower()) or ("po" in key.lower()):
|
@@ -479,9 +185,22 @@ def figsets(*args,**kwargs):
|
|
479
185
|
# rotation
|
480
186
|
if "angle" in key.lower() or ("rot" in key.lower()):
|
481
187
|
if "x" in key.lower():
|
482
|
-
|
188
|
+
if value in [0,90,180,270]:
|
189
|
+
ax.tick_params(axis="x", rotation=value)
|
190
|
+
for tick in ax.get_xticklabels():
|
191
|
+
tick.set_horizontalalignment('center')
|
192
|
+
elif value >0:
|
193
|
+
ax.tick_params(axis="x", rotation=value)
|
194
|
+
for tick in ax.get_xticklabels():
|
195
|
+
tick.set_horizontalalignment('right')
|
196
|
+
elif value <0:
|
197
|
+
ax.tick_params(axis='x', rotation=value)
|
198
|
+
for tick in ax.get_xticklabels():
|
199
|
+
tick.set_horizontalalignment('left')
|
483
200
|
if "y" in key.lower():
|
484
201
|
ax.tick_params(axis="y", rotation=value)
|
202
|
+
for tick in ax.get_yticklabels():
|
203
|
+
tick.set_horizontalalignment('right')
|
485
204
|
|
486
205
|
if "bo" in key in key: # box setting, and ("p" in key or "l" in key):
|
487
206
|
if isinstance(value, (str, list)):
|
@@ -602,7 +321,12 @@ def figsets(*args,**kwargs):
|
|
602
321
|
if "c" in key.lower() and ("sp" in key.lower() or "ax" in key.lower()):# spine color
|
603
322
|
for loc, spi in ax.spines.items():
|
604
323
|
spi.set_color(value)
|
605
|
-
|
324
|
+
if 'leg' in key.lower(): # legend
|
325
|
+
legend_kws = kwargs.get('legend', None)
|
326
|
+
if legend_kws:
|
327
|
+
# https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html
|
328
|
+
ax.legend(**legend_kws)
|
329
|
+
|
606
330
|
for arg in args:
|
607
331
|
if isinstance(arg,matplotlib.axes._axes.Axes):
|
608
332
|
ax=arg
|
@@ -646,7 +370,3 @@ def figsets(*args,**kwargs):
|
|
646
370
|
if len(fig.get_axes()) > 1:
|
647
371
|
plt.tight_layout()
|
648
372
|
plt.gcf().align_labels()
|
649
|
-
|
650
|
-
|
651
|
-
def get_cmap():
|
652
|
-
return plt.colormaps()
|
py2ls/plot/get_color.py
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
from cycler import cycler
|
3
|
+
|
4
|
+
# set up the colorlist, give the number, or the colormap's name
|
5
|
+
def get_color(n=1, cmap="auto", by="start"):
|
6
|
+
# Extract the colormap as a list
|
7
|
+
def cmap2hex(cmap_name):
|
8
|
+
cmap_ = matplotlib.pyplot.get_cmap(cmap_name)
|
9
|
+
colors = [cmap_(i) for i in range(cmap_.N)]
|
10
|
+
return [matplotlib.colors.rgb2hex(color) for color in colors]
|
11
|
+
# usage: clist = cmap2hex("viridis")
|
12
|
+
# cycle times, total number is n (defaultn=10)
|
13
|
+
def cycle2list(colorlist, n=10):
|
14
|
+
cycler_ = cycler(tmp=colorlist)
|
15
|
+
clist = []
|
16
|
+
for i, c_ in zip(range(n), cycler_()):
|
17
|
+
clist.append(c_["tmp"])
|
18
|
+
if i > n:
|
19
|
+
break
|
20
|
+
return clist
|
21
|
+
def hue2rgb(hex_colors):
|
22
|
+
def hex_to_rgb(hex_color):
|
23
|
+
"""Converts a hexadecimal color code to RGB values."""
|
24
|
+
if hex_colors.startswith("#"):
|
25
|
+
hex_color = hex_color.lstrip("#")
|
26
|
+
return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
|
27
|
+
if isinstance(hex_colors, str):
|
28
|
+
return hex_to_rgb(hex_colors)
|
29
|
+
elif isinstance(hex_colors, (list)):
|
30
|
+
"""Converts a list of hexadecimal color codes to a list of RGB values."""
|
31
|
+
rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
|
32
|
+
return rgb_values
|
33
|
+
if "aut" in cmap:
|
34
|
+
colorlist = [
|
35
|
+
"#474747",
|
36
|
+
"#FF2C00",
|
37
|
+
"#0C5DA5",
|
38
|
+
"#845B97",
|
39
|
+
"#58BBCC",
|
40
|
+
"#FF9500",
|
41
|
+
"#D57DBE",
|
42
|
+
]
|
43
|
+
else:
|
44
|
+
colorlist = cmap2hex(cmap)
|
45
|
+
if "st" in by.lower() or "be" in by.lower():
|
46
|
+
# cycle it
|
47
|
+
clist = cycle2list(colorlist, n=n)
|
48
|
+
if "l" in by.lower() or "p" in by.lower():
|
49
|
+
clist = []
|
50
|
+
[
|
51
|
+
clist.append(colorlist[i])
|
52
|
+
for i in [int(i) for i in np.linspace(0, len(colorlist) - 1, n)]
|
53
|
+
]
|
54
|
+
|
55
|
+
return clist # a color list
|
56
|
+
# example usage: clist = get_color(4,cmap="auto", by="start") # get_color(4, cmap="hot", by="linspace")
|
57
|
+
|
58
|
+
"""
|
59
|
+
# n = 7
|
60
|
+
# clist = get_color(n, cmap="auto", by="linspace") # get_color(100)
|
61
|
+
# plt.figure(figsize=[8, 5], dpi=100)
|
62
|
+
# x = np.linspace(0, 2 * np.pi, 50) * 100
|
63
|
+
# y = np.sin(x)
|
64
|
+
# for i in range(1, n + 1):
|
65
|
+
# plt.plot(x, y + i, c=clist[i - 1], lw=5, label=str(i))
|
66
|
+
# plt.legend()
|
67
|
+
# plt.ylim(-2, 20)
|
68
|
+
# figsets(plt.gca(), {"style": "whitegrid"}) """
|
py2ls/plot/stdshade.py
ADDED
@@ -0,0 +1,227 @@
|
|
1
|
+
from scipy.signal import savgol_filter
|
2
|
+
import numpy as np
|
3
|
+
import matplotlib.pyplot as plt
|
4
|
+
|
5
|
+
def stdshade(ax=None,*args, **kwargs):
|
6
|
+
# Separate kws_line and kws_fill if necessary
|
7
|
+
kws_line = kwargs.pop('kws_line', {})
|
8
|
+
kws_fill = kwargs.pop('kws_fill', {})
|
9
|
+
|
10
|
+
# Merge kws_line and kws_fill into kwargs
|
11
|
+
kwargs.update(kws_line)
|
12
|
+
kwargs.update(kws_fill)
|
13
|
+
def str2list(str_):
|
14
|
+
l = []
|
15
|
+
[l.append(x) for x in str_]
|
16
|
+
return l
|
17
|
+
def hue2rgb(hex_colors):
|
18
|
+
def hex_to_rgb(hex_color):
|
19
|
+
"""Converts a hexadecimal color code to RGB values."""
|
20
|
+
if hex_colors.startswith("#"):
|
21
|
+
hex_color = hex_color.lstrip("#")
|
22
|
+
return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
|
23
|
+
if isinstance(hex_colors, str):
|
24
|
+
return hex_to_rgb(hex_colors)
|
25
|
+
elif isinstance(hex_colors, (list)):
|
26
|
+
"""Converts a list of hexadecimal color codes to a list of RGB values."""
|
27
|
+
rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
|
28
|
+
return rgb_values
|
29
|
+
if (
|
30
|
+
isinstance(ax, np.ndarray)
|
31
|
+
and ax.ndim == 2
|
32
|
+
and min(ax.shape) > 1
|
33
|
+
and max(ax.shape) > 1
|
34
|
+
):
|
35
|
+
y = ax
|
36
|
+
ax = plt.gca()
|
37
|
+
if ax is None:
|
38
|
+
ax = plt.gca()
|
39
|
+
alpha = 0.5
|
40
|
+
acolor = "k"
|
41
|
+
paraStdSem = "sem"
|
42
|
+
plotStyle = "-"
|
43
|
+
plotMarker = "none"
|
44
|
+
smth = 1
|
45
|
+
l_c_one = ["r", "g", "b", "m", "c", "y", "k", "w"]
|
46
|
+
l_style2 = ["--", "-."]
|
47
|
+
l_style1 = ["-", ":"]
|
48
|
+
l_mark = ["o", "+", "*", ".", "x", "_", "|", "s", "d", "^", "v", ">", "<", "p", "h"]
|
49
|
+
# Check each argument
|
50
|
+
for iarg in range(len(args)):
|
51
|
+
if (
|
52
|
+
isinstance(args[iarg], np.ndarray)
|
53
|
+
and args[iarg].ndim == 2
|
54
|
+
and min(args[iarg].shape) > 1
|
55
|
+
and max(args[iarg].shape) > 1
|
56
|
+
):
|
57
|
+
y = args[iarg]
|
58
|
+
# Except y, continuous data is 'F'
|
59
|
+
if (isinstance(args[iarg], np.ndarray) and args[iarg].ndim == 1) or isinstance(
|
60
|
+
args[iarg], range
|
61
|
+
):
|
62
|
+
x = args[iarg]
|
63
|
+
if isinstance(x, range):
|
64
|
+
x = np.arange(start=x.start, stop=x.stop, step=x.step)
|
65
|
+
# Only one number( 0~1), 'alpha' / color
|
66
|
+
if isinstance(args[iarg], (int, float)):
|
67
|
+
if np.size(args[iarg]) == 1 and 0 <= args[iarg] <= 1:
|
68
|
+
alpha = args[iarg]
|
69
|
+
if isinstance(args[iarg], (list, tuple)) and np.size(args[iarg]) == 3:
|
70
|
+
acolor = args[iarg]
|
71
|
+
acolor = tuple(acolor) if isinstance(acolor, list) else acolor
|
72
|
+
# Color / plotStyle /
|
73
|
+
if (
|
74
|
+
isinstance(args[iarg], str)
|
75
|
+
and len(args[iarg]) == 1
|
76
|
+
and args[iarg] in l_c_one
|
77
|
+
):
|
78
|
+
acolor = args[iarg]
|
79
|
+
else:
|
80
|
+
if isinstance(args[iarg], str):
|
81
|
+
if args[iarg] in ["sem", "std"]:
|
82
|
+
paraStdSem = args[iarg]
|
83
|
+
if args[iarg].startswith("#"):
|
84
|
+
acolor=hue2rgb(args[iarg])
|
85
|
+
if str2list(args[iarg])[0] in l_c_one:
|
86
|
+
if len(args[iarg]) == 3:
|
87
|
+
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
88
|
+
if k != []:
|
89
|
+
acolor = k[0]
|
90
|
+
st = [i for i in l_style2 if i in args[iarg]]
|
91
|
+
if st != []:
|
92
|
+
plotStyle = st[0]
|
93
|
+
elif len(args[iarg]) == 2:
|
94
|
+
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
95
|
+
if k != []:
|
96
|
+
acolor = k[0]
|
97
|
+
mk = [i for i in str2list(args[iarg]) if i in l_mark]
|
98
|
+
if mk != []:
|
99
|
+
plotMarker = mk[0]
|
100
|
+
st = [i for i in l_style1 if i in args[iarg]]
|
101
|
+
if st != []:
|
102
|
+
plotStyle = st[0]
|
103
|
+
if len(args[iarg]) == 1:
|
104
|
+
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
105
|
+
if k != []:
|
106
|
+
acolor = k[0]
|
107
|
+
mk = [i for i in str2list(args[iarg]) if i in l_mark]
|
108
|
+
if mk != []:
|
109
|
+
plotMarker = mk[0]
|
110
|
+
st = [i for i in l_style1 if i in args[iarg]]
|
111
|
+
if st != []:
|
112
|
+
plotStyle = st[0]
|
113
|
+
if len(args[iarg]) == 2:
|
114
|
+
st = [i for i in l_style2 if i in args[iarg]]
|
115
|
+
if st != []:
|
116
|
+
plotStyle = st[0]
|
117
|
+
# smth
|
118
|
+
if (
|
119
|
+
isinstance(args[iarg], (int, float))
|
120
|
+
and np.size(args[iarg]) == 1
|
121
|
+
and args[iarg] >= 1
|
122
|
+
):
|
123
|
+
smth = args[iarg]
|
124
|
+
smth = kwargs.get('smth', smth)
|
125
|
+
if "x" not in locals() or x is None:
|
126
|
+
x = np.arange(1, y.shape[1] + 1)
|
127
|
+
elif len(x) < y.shape[1]:
|
128
|
+
y = y[:, x]
|
129
|
+
nRow = y.shape[0]
|
130
|
+
nCol = y.shape[1]
|
131
|
+
print(f"y was corrected, please confirm that {nRow} row, {nCol} col")
|
132
|
+
else:
|
133
|
+
x = np.arange(1, y.shape[1] + 1)
|
134
|
+
|
135
|
+
if x.shape[0] != 1:
|
136
|
+
x = x.T
|
137
|
+
yMean = np.nanmean(y, axis=0)
|
138
|
+
if smth > 1:
|
139
|
+
yMean = savgol_filter(np.nanmean(y, axis=0), smth, 1)
|
140
|
+
else:
|
141
|
+
yMean = np.nanmean(y, axis=0)
|
142
|
+
if paraStdSem == "sem":
|
143
|
+
if smth > 1:
|
144
|
+
wings = savgol_filter(np.nanstd(y, axis=0) / np.sqrt(y.shape[0]), smth, 1)
|
145
|
+
else:
|
146
|
+
wings = np.nanstd(y, axis=0) / np.sqrt(y.shape[0])
|
147
|
+
elif paraStdSem == "std":
|
148
|
+
if smth > 1:
|
149
|
+
wings = savgol_filter(np.nanstd(y, axis=0), smth, 1)
|
150
|
+
else:
|
151
|
+
wings = np.nanstd(y, axis=0)
|
152
|
+
|
153
|
+
# fill_kws = kwargs.get('fill_kws', {})
|
154
|
+
# line_kws = kwargs.get('line_kws', {})
|
155
|
+
|
156
|
+
# setting form kwargs
|
157
|
+
lw = kwargs.get('lw', 1.5)
|
158
|
+
ls= kwargs.get('ls', plotStyle)
|
159
|
+
marker=kwargs.get("marker",plotMarker)
|
160
|
+
label=kwargs.get("label",None)
|
161
|
+
label_line = kwargs.get("label_line",None)
|
162
|
+
label_fill = kwargs.get('label_fill',None)
|
163
|
+
alpha=kwargs.get('alpha',alpha)
|
164
|
+
color=kwargs.get('color', acolor)
|
165
|
+
if not label_line and label:
|
166
|
+
label_line = label
|
167
|
+
kwargs['lw'] = lw
|
168
|
+
kwargs['ls'] = ls
|
169
|
+
kwargs['label_line'] = label_line
|
170
|
+
kwargs['label_fill'] = label_fill
|
171
|
+
|
172
|
+
# set kws_line
|
173
|
+
if 'color' not in kws_line:
|
174
|
+
kws_line['color']=color
|
175
|
+
if 'lw' not in kws_line:
|
176
|
+
kws_line['lw']=lw
|
177
|
+
if 'ls' not in kws_line:
|
178
|
+
kws_line['ls']=ls
|
179
|
+
if 'marker' not in kws_line:
|
180
|
+
kws_line['marker']=marker
|
181
|
+
if 'label' not in kws_line:
|
182
|
+
kws_line['label']=label_line
|
183
|
+
|
184
|
+
# set kws_line
|
185
|
+
if 'color' not in kws_fill:
|
186
|
+
kws_fill['color']=color
|
187
|
+
if 'alpha' not in kws_fill:
|
188
|
+
kws_fill['alpha']=alpha
|
189
|
+
if 'lw' not in kws_fill:
|
190
|
+
kws_fill['lw']=0
|
191
|
+
if 'label' not in kws_fill:
|
192
|
+
kws_fill['label']=label_fill
|
193
|
+
|
194
|
+
fill = ax.fill_between(x, yMean + wings, yMean - wings, **kws_fill)
|
195
|
+
line = ax.plot(x, yMean, **kws_line)
|
196
|
+
return line[0], fill
|
197
|
+
|
198
|
+
|
199
|
+
"""
|
200
|
+
########## Usage 1 ##########
|
201
|
+
plot.stdshade(data,
|
202
|
+
'b',
|
203
|
+
':',
|
204
|
+
'd',
|
205
|
+
0.1,
|
206
|
+
4,
|
207
|
+
label='ddd',
|
208
|
+
label_line='label_line',
|
209
|
+
label_fill="label-fill")
|
210
|
+
plt.legend()
|
211
|
+
|
212
|
+
########## Usage 2 ##########
|
213
|
+
plot.stdshade(data,
|
214
|
+
'm-',
|
215
|
+
alpha=0.1,
|
216
|
+
lw=2,
|
217
|
+
ls=':',
|
218
|
+
marker='d',
|
219
|
+
color='b',
|
220
|
+
smth=4,
|
221
|
+
label='ddd',
|
222
|
+
label_line='label_line',
|
223
|
+
label_fill="label-fill")
|
224
|
+
plt.legend()
|
225
|
+
|
226
|
+
"""
|
227
|
+
|
@@ -133,14 +133,17 @@ py2ls/data/lang_code_iso639.json,sha256=qZiU7H2RLJjDMXK22C-jhwzLJCI5vKmampjB1ys4
|
|
133
133
|
py2ls/db2ls.py,sha256=MMfFX47aIPIyu7fU9aPvX9lbPRPYOpJ_VXwlnWk-8qo,13615
|
134
134
|
py2ls/doc.py,sha256=xN3g1OWfoaGUhikbJ0NqbN5eKy1VZVvWwRlhHMgyVEc,4243
|
135
135
|
py2ls/freqanalysis.py,sha256=F4218VSPbgL5tnngh6xNCYuNnfR-F_QjECUUxrPYZss,32594
|
136
|
-
py2ls/ips.py,sha256=
|
136
|
+
py2ls/ips.py,sha256=9BV26m0rnk25auM25dUIUKbKRYy6NFzpCYkOqRuUV-I,101177
|
137
137
|
py2ls/netfinder.py,sha256=ZsLWGYMeRuGvxj2nqE0Z8ANoaVl18Necfw0HQfh2q7I,45548
|
138
|
-
py2ls/plot.py,sha256=
|
138
|
+
py2ls/plot/catplot.py,sha256=fJDMd_LCknWwl-UHrbYEV6h6XBS6pA3_IOoQbnhvbM8,17697
|
139
|
+
py2ls/plot/figsets.py,sha256=Oavp-biIuzLy8eWkDYQIMWihe56bLEbfMoPKFY_HWUo,15659
|
140
|
+
py2ls/plot/get_color.py,sha256=TBZG8DPCjT9ut24FlxO60bhOeov1iWqkWC7AzP5xQ6Y,2454
|
141
|
+
py2ls/plot/stdshade.py,sha256=0Znt14wjpO3zr33Sg44fNTlVsJ4yOrnF7QGt18FNPCE,7702
|
139
142
|
py2ls/setuptools-70.1.0-py3-none-any.whl,sha256=2bi3cUVal8ip86s0SOvgspteEF8SKLukECi-EWmFomc,882588
|
140
143
|
py2ls/sleep_events_detectors.py,sha256=36MCuRrpurn0Uvzpo3p3b3_JlVsRNHSWCXbJxCGM3mg,51546
|
141
144
|
py2ls/stats.py,sha256=Wd9yCKQ_61QD29WMEgMuEcreFxF91NmlPW65iWT2B5w,39041
|
142
145
|
py2ls/translator.py,sha256=6S7MmTZmjj8NljVmj0W5uEauu4ePxso3AMf2LvGVRQA,30516
|
143
146
|
py2ls/wb_detector.py,sha256=7y6TmBUj9exCZeIgBAJ_9hwuhkDh1x_-yg4dvNY1_GQ,6284
|
144
|
-
py2ls-0.1.6.
|
145
|
-
py2ls-0.1.6.
|
146
|
-
py2ls-0.1.6.
|
147
|
+
py2ls-0.1.6.2.dist-info/METADATA,sha256=pVPM5bEveg0pnlE82nrKzU_t-HBsRX8ovQprVLESjw4,17943
|
148
|
+
py2ls-0.1.6.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
149
|
+
py2ls-0.1.6.2.dist-info/RECORD,,
|