py2ls 0.1.7.9__py3-none-any.whl → 0.1.8.1__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
CHANGED
@@ -4,8 +4,9 @@ from matplotlib.colors import to_rgba
|
|
4
4
|
from scipy.stats import gaussian_kde
|
5
5
|
|
6
6
|
import logging
|
7
|
+
|
7
8
|
# Suppress INFO messages from fontTools
|
8
|
-
logging.getLogger(
|
9
|
+
logging.getLogger("fontTools").setLevel(logging.WARNING)
|
9
10
|
|
10
11
|
|
11
12
|
def catplot(data, *args, **kwargs):
|
@@ -15,220 +16,291 @@ def catplot(data, *args, **kwargs):
|
|
15
16
|
Args:
|
16
17
|
data (array): data matrix
|
17
18
|
"""
|
18
|
-
|
19
|
-
|
20
|
-
bar_positions=
|
19
|
+
|
20
|
+
def plot_bars(data, data_m, opt_b, xloc, ax):
|
21
|
+
bar_positions = get_positions(
|
22
|
+
xloc, opt_b["loc"], opt_b["x_width"], data.shape[0]
|
23
|
+
)
|
24
|
+
bar_positions = np.nanmean(bar_positions, axis=0)
|
21
25
|
for i, (x, y) in enumerate(zip(bar_positions, data_m)):
|
22
|
-
color = to_rgba(opt_b[
|
23
|
-
ax.bar(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
color = to_rgba(opt_b["FaceColor"][i % len(opt_b["FaceColor"])])
|
27
|
+
ax.bar(
|
28
|
+
x,
|
29
|
+
y,
|
30
|
+
width=opt_b["x_width"],
|
31
|
+
color=color,
|
32
|
+
edgecolor=opt_b["EdgeColor"],
|
33
|
+
alpha=opt_b["FaceAlpha"],
|
34
|
+
linewidth=opt_b["LineWidth"],
|
35
|
+
hatch=opt_b["hatch"],
|
36
|
+
)
|
31
37
|
|
32
38
|
def plot_errors(data, data_m, opt_e, xloc, ax):
|
33
|
-
error_positions = get_positions(
|
34
|
-
|
39
|
+
error_positions = get_positions(
|
40
|
+
xloc, opt_e["loc"], opt_e["x_width"], data.shape[0]
|
41
|
+
)
|
42
|
+
error_positions = np.nanmean(error_positions, axis=0)
|
35
43
|
errors = np.nanstd(data, axis=0)
|
36
|
-
if opt_e[
|
37
|
-
errors /= np.sqrt(np.sum(~np.isnan(data),axis=0))
|
44
|
+
if opt_e["error"] == "sem":
|
45
|
+
errors /= np.sqrt(np.sum(~np.isnan(data), axis=0))
|
38
46
|
|
39
|
-
if not isinstance(opt_e[
|
40
|
-
opt_e[
|
41
|
-
if not isinstance(opt_e[
|
42
|
-
opt_e[
|
47
|
+
if not isinstance(opt_e["FaceColor"], list):
|
48
|
+
opt_e["FaceColor"] = [opt_e["FaceColor"]]
|
49
|
+
if not isinstance(opt_e["MarkerEdgeColor"], list):
|
50
|
+
opt_e["MarkerEdgeColor"] = [opt_e["MarkerEdgeColor"]]
|
43
51
|
for i, (x, y, err) in enumerate(zip(error_positions, data_m, errors)):
|
44
|
-
if opt_e[
|
45
|
-
ax.errorbar(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
if opt_e["MarkerSize"] == "auto":
|
53
|
+
ax.errorbar(
|
54
|
+
x,
|
55
|
+
y,
|
56
|
+
yerr=err,
|
57
|
+
fmt=opt_e["Marker"],
|
58
|
+
ecolor=opt_e["LineColor"],
|
59
|
+
elinewidth=opt_e["LineWidth"],
|
60
|
+
lw=opt_e["LineWidth"],
|
61
|
+
ls=opt_e["LineStyle"],
|
62
|
+
capsize=opt_e["CapSize"],
|
63
|
+
capthick=opt_e["CapLineWidth"],
|
64
|
+
mec=opt_e["MarkerEdgeColor"][i % len(opt_e["MarkerEdgeColor"])],
|
65
|
+
mfc=opt_e["FaceColor"][i % len(opt_e["FaceColor"])],
|
66
|
+
visible=opt_e["Visible"],
|
67
|
+
)
|
57
68
|
else:
|
58
|
-
ax.errorbar(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
ax.errorbar(
|
70
|
+
x,
|
71
|
+
y,
|
72
|
+
yerr=err,
|
73
|
+
fmt=opt_e["Marker"],
|
74
|
+
ecolor=opt_e["LineColor"],
|
75
|
+
elinewidth=opt_e["LineWidth"],
|
76
|
+
lw=opt_e["LineWidth"],
|
77
|
+
ls=opt_e["LineStyle"],
|
78
|
+
capsize=opt_e["CapSize"],
|
79
|
+
capthick=opt_e["CapLineWidth"],
|
80
|
+
markersize=opt_e["MarkerSize"],
|
81
|
+
mec=opt_e["MarkerEdgeColor"][i % len(opt_e["MarkerEdgeColor"])],
|
82
|
+
mfc=opt_e["FaceColor"][i % len(opt_e["FaceColor"])],
|
83
|
+
visible=opt_e["Visible"],
|
84
|
+
)
|
72
85
|
|
73
86
|
def plot_scatter(data, opt_s, xloc, ax):
|
74
|
-
scatter_positions = get_positions(
|
87
|
+
scatter_positions = get_positions(
|
88
|
+
xloc, opt_s["loc"], opt_s["x_width"], data.shape[0]
|
89
|
+
)
|
75
90
|
for i, (x, y) in enumerate(zip(scatter_positions.T, data.T)):
|
76
|
-
color = to_rgba(opt_s[
|
77
|
-
ax.scatter(
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
X_bx = xloc
|
92
|
-
elif
|
91
|
+
color = to_rgba(opt_s["FaceColor"][i % len(opt_s["FaceColor"])])
|
92
|
+
ax.scatter(
|
93
|
+
x,
|
94
|
+
y,
|
95
|
+
color=color,
|
96
|
+
alpha=opt_s["FaceAlpha"],
|
97
|
+
edgecolor=opt_s["MarkerEdgeColor"],
|
98
|
+
s=opt_s["MarkerSize"],
|
99
|
+
marker=opt_s["Marker"],
|
100
|
+
linewidths=opt_s["LineWidth"],
|
101
|
+
cmap=opt_s["cmap"],
|
102
|
+
)
|
103
|
+
|
104
|
+
def plot_boxplot(data, bx_opt, xloc, ax):
|
105
|
+
if "l" in bx_opt["loc"]:
|
106
|
+
X_bx = xloc - bx_opt["x_width"]
|
107
|
+
elif "r" in bx_opt["loc"]:
|
108
|
+
X_bx = xloc + bx_opt["x_width"]
|
109
|
+
elif "i" in bx_opt["loc"]:
|
93
110
|
X_bx = xloc
|
94
|
-
X_bx[:, 0] += bx_opt[
|
95
|
-
X_bx[:, -1] -= bx_opt[
|
96
|
-
elif
|
111
|
+
X_bx[:, 0] += bx_opt["x_width"]
|
112
|
+
X_bx[:, -1] -= bx_opt["x_width"]
|
113
|
+
elif "o" in bx_opt["loc"]:
|
97
114
|
X_bx = xloc
|
98
|
-
X_bx[:, 0] -= bx_opt[
|
99
|
-
X_bx[:, -1] += bx_opt[
|
100
|
-
elif
|
115
|
+
X_bx[:, 0] -= bx_opt["x_width"]
|
116
|
+
X_bx[:, -1] += bx_opt["x_width"]
|
117
|
+
elif "c" in bx_opt["loc"] or "m" in bx_opt["loc"]:
|
101
118
|
X_bx = xloc
|
102
119
|
else:
|
103
120
|
X_bx = xloc
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
whiskerprops = dict(
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
bx_opt[
|
121
|
+
|
122
|
+
boxprops = dict(color=bx_opt["EdgeColor"], linewidth=bx_opt["BoxLineWidth"])
|
123
|
+
flierprops = dict(
|
124
|
+
marker=bx_opt["OutlierMarker"],
|
125
|
+
markerfacecolor=bx_opt["OutlierColor"],
|
126
|
+
markersize=bx_opt["OutlierSize"],
|
127
|
+
)
|
128
|
+
whiskerprops = dict(
|
129
|
+
linestyle=bx_opt["WhiskerLineStyle"],
|
130
|
+
color=bx_opt["WhiskerLineColor"],
|
131
|
+
linewidth=bx_opt["WhiskerLineWidth"],
|
132
|
+
)
|
133
|
+
capprops = dict(
|
134
|
+
color=bx_opt["CapLineColor"],
|
135
|
+
linewidth=bx_opt["CapLineWidth"],
|
136
|
+
)
|
137
|
+
medianprops = dict(
|
138
|
+
linestyle=bx_opt["MedianLineStyle"],
|
139
|
+
color=bx_opt["MedianLineColor"],
|
140
|
+
linewidth=bx_opt["MedianLineWidth"],
|
141
|
+
)
|
142
|
+
meanprops = dict(
|
143
|
+
linestyle=bx_opt["MeanLineStyle"],
|
144
|
+
color=bx_opt["MeanLineColor"],
|
145
|
+
linewidth=bx_opt["MeanLineWidth"],
|
146
|
+
)
|
147
|
+
bxp = ax.boxplot(
|
148
|
+
data,
|
149
|
+
positions=X_bx,
|
150
|
+
notch=bx_opt["Notch"],
|
151
|
+
patch_artist=True,
|
152
|
+
boxprops=boxprops,
|
153
|
+
flierprops=flierprops,
|
154
|
+
whiskerprops=whiskerprops,
|
155
|
+
capwidths=bx_opt["CapSize"],
|
156
|
+
showfliers=bx_opt["Outliers"],
|
157
|
+
showcaps=bx_opt["Caps"],
|
158
|
+
capprops=capprops,
|
159
|
+
medianprops=medianprops,
|
160
|
+
meanline=bx_opt["MeanLine"],
|
161
|
+
showmeans=bx_opt["MeanLine"],
|
162
|
+
meanprops=meanprops,
|
163
|
+
widths=bx_opt["x_width"],
|
164
|
+
)
|
165
|
+
|
166
|
+
if bx_opt["BoxLineWidth"] < 0.1:
|
167
|
+
bx_opt["EdgeColor"] = "none"
|
141
168
|
else:
|
142
|
-
bx_opt[
|
169
|
+
bx_opt["EdgeColor"] = bx_opt["EdgeColor"]
|
143
170
|
|
144
|
-
for patch, color in zip(bxp[
|
145
|
-
patch.set_facecolor(to_rgba(color, bx_opt[
|
171
|
+
for patch, color in zip(bxp["boxes"], bx_opt["FaceColor"]):
|
172
|
+
patch.set_facecolor(to_rgba(color, bx_opt["FaceAlpha"]))
|
146
173
|
|
147
|
-
if bx_opt[
|
174
|
+
if bx_opt["MedianLineTop"]:
|
148
175
|
ax.set_children(ax.get_children()[::-1]) # move median line forward
|
149
176
|
|
150
177
|
def plot_violin(data, opt_v, xloc, ax):
|
151
|
-
violin_positions = get_positions(
|
178
|
+
violin_positions = get_positions(
|
179
|
+
xloc, opt_v["loc"], opt_v["x_width"], data.shape[0]
|
180
|
+
)
|
152
181
|
violin_positions = np.nanmean(violin_positions, axis=0)
|
153
182
|
for i, (x, ys) in enumerate(zip(violin_positions, data.T)):
|
154
183
|
ys = ys[~np.isnan(ys)]
|
155
184
|
if len(ys) > 1:
|
156
|
-
kde = gaussian_kde(ys, bw_method=opt_v[
|
185
|
+
kde = gaussian_kde(ys, bw_method=opt_v["BandWidth"])
|
157
186
|
min_val, max_val = ys.min(), ys.max()
|
158
|
-
y_vals = np.linspace(min_val, max_val, opt_v[
|
187
|
+
y_vals = np.linspace(min_val, max_val, opt_v["NumPoints"])
|
159
188
|
kde_vals = kde(y_vals)
|
160
|
-
kde_vals = kde_vals / kde_vals.max() * opt_v[
|
161
|
-
if
|
162
|
-
ax.fill_betweenx(
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
189
|
+
kde_vals = kde_vals / kde_vals.max() * opt_v["x_width"]
|
190
|
+
if "r" in opt_v["loc"].lower():
|
191
|
+
ax.fill_betweenx(
|
192
|
+
y_vals,
|
193
|
+
x,
|
194
|
+
x + kde_vals,
|
195
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
196
|
+
alpha=opt_v["FaceAlpha"],
|
197
|
+
edgecolor=opt_v["EdgeColor"],
|
198
|
+
)
|
199
|
+
elif "l" in opt_v["loc"].lower() and not "f" in opt_v["loc"].lower():
|
200
|
+
ax.fill_betweenx(
|
201
|
+
y_vals,
|
202
|
+
x - kde_vals,
|
203
|
+
x,
|
204
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
205
|
+
alpha=opt_v["FaceAlpha"],
|
206
|
+
edgecolor=opt_v["EdgeColor"],
|
207
|
+
)
|
208
|
+
elif "o" in opt_v["loc"].lower() or "both" in opt_v["loc"].lower():
|
209
|
+
ax.fill_betweenx(
|
210
|
+
y_vals,
|
211
|
+
x - kde_vals,
|
212
|
+
x + kde_vals,
|
213
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
214
|
+
alpha=opt_v["FaceAlpha"],
|
215
|
+
edgecolor=opt_v["EdgeColor"],
|
216
|
+
)
|
217
|
+
elif "i" in opt_v["loc"].lower():
|
177
218
|
if i % 2 == 1: # odd number
|
178
|
-
ax.fill_betweenx(
|
179
|
-
|
180
|
-
|
181
|
-
|
219
|
+
ax.fill_betweenx(
|
220
|
+
y_vals,
|
221
|
+
x - kde_vals,
|
222
|
+
x,
|
223
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
224
|
+
alpha=opt_v["FaceAlpha"],
|
225
|
+
edgecolor=opt_v["EdgeColor"],
|
226
|
+
)
|
182
227
|
else:
|
183
|
-
ax.fill_betweenx(
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
228
|
+
ax.fill_betweenx(
|
229
|
+
y_vals,
|
230
|
+
x,
|
231
|
+
x + kde_vals,
|
232
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
233
|
+
alpha=opt_v["FaceAlpha"],
|
234
|
+
edgecolor=opt_v["EdgeColor"],
|
235
|
+
)
|
236
|
+
elif "f" in opt_v["loc"].lower():
|
237
|
+
ax.fill_betweenx(
|
238
|
+
y_vals,
|
239
|
+
x - kde_vals,
|
240
|
+
x + kde_vals,
|
241
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
242
|
+
alpha=opt_v["FaceAlpha"],
|
243
|
+
edgecolor=opt_v["EdgeColor"],
|
244
|
+
)
|
245
|
+
|
246
|
+
def plot_lines(data, opt_l, opt_s, ax):
|
247
|
+
scatter_positions = get_positions(
|
248
|
+
xloc, opt_s["loc"], opt_s["x_width"], data.shape[0]
|
249
|
+
)
|
250
|
+
for incol in range(data.shape[1] - 1):
|
196
251
|
for irow in range(data.shape[0]):
|
197
252
|
if not np.isnan(data[irow, incol]):
|
198
|
-
if
|
199
|
-
|
253
|
+
if (
|
254
|
+
opt_l["LineStyle"] is not None
|
255
|
+
and not opt_l["LineStyle"] == "none"
|
256
|
+
):
|
257
|
+
x_data = [
|
258
|
+
scatter_positions[irow, incol],
|
259
|
+
scatter_positions[irow, incol + 1],
|
260
|
+
]
|
200
261
|
y_data = [data[irow, incol], data[irow, incol + 1]]
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
262
|
+
|
263
|
+
ax.plot(
|
264
|
+
x_data,
|
265
|
+
y_data,
|
266
|
+
color=opt_l["LineColor"],
|
267
|
+
linestyle=opt_l["LineStyle"],
|
268
|
+
linewidth=opt_l["LineWidth"],
|
269
|
+
alpha=opt_l["LineAlpha"],
|
270
|
+
)
|
271
|
+
|
209
272
|
def get_positions(xloc, loc_type, x_width, n_row=None):
|
210
|
-
if
|
273
|
+
if "rand" in loc_type:
|
211
274
|
scatter_positions = np.zeros((n_row, len(xloc)))
|
212
275
|
np.random.seed(111)
|
213
276
|
for i, x in enumerate(xloc):
|
214
|
-
scatter_positions[:, i] = np.random.uniform(
|
277
|
+
scatter_positions[:, i] = np.random.uniform(
|
278
|
+
x - x_width, x + x_width, n_row
|
279
|
+
)
|
215
280
|
return scatter_positions
|
216
|
-
elif
|
217
|
-
return np.tile(xloc - x_width,(n_row,1))
|
218
|
-
elif
|
219
|
-
return np.tile(xloc + x_width,(n_row,1))
|
220
|
-
elif
|
221
|
-
return np.tile(
|
222
|
-
|
223
|
-
|
281
|
+
elif "l" in loc_type:
|
282
|
+
return np.tile(xloc - x_width, (n_row, 1))
|
283
|
+
elif "r" in loc_type and not "d" in loc_type:
|
284
|
+
return np.tile(xloc + x_width, (n_row, 1))
|
285
|
+
elif "i" in loc_type:
|
286
|
+
return np.tile(
|
287
|
+
np.concatenate([xloc[:1] + x_width, xloc[1:-1], xloc[-1:] - x_width]),
|
288
|
+
(n_row, 1),
|
289
|
+
)
|
290
|
+
elif "o" in loc_type:
|
291
|
+
return np.tile(
|
292
|
+
np.concatenate([xloc[:1] - x_width, xloc[1:-1], xloc[-1:] + x_width]),
|
293
|
+
(n_row, 1),
|
294
|
+
)
|
224
295
|
else:
|
225
|
-
return np.tile(xloc,(n_row,1))
|
226
|
-
|
296
|
+
return np.tile(xloc, (n_row, 1))
|
297
|
+
|
298
|
+
def sort_catplot_layers(custom_order, full_order=["b", "bx", "e", "v", "s", "l"]):
|
227
299
|
"""
|
228
300
|
sort layers
|
229
301
|
"""
|
230
302
|
# Ensure custom_order is a list of strings
|
231
|
-
custom_order = [str(layer) for layer in custom_order]
|
303
|
+
custom_order = [str(layer) for layer in custom_order]
|
232
304
|
j = 1
|
233
305
|
layers = list(range(len(full_order)))
|
234
306
|
for i in range(len(full_order)):
|
@@ -245,181 +317,188 @@ def catplot(data, *args, **kwargs):
|
|
245
317
|
# # Example usage:
|
246
318
|
# custom_order = ['s', 'bx', 'e']
|
247
319
|
# full_order = sort_catplot_layers(custom_order)
|
248
|
-
|
320
|
+
|
249
321
|
# full_order
|
250
|
-
opt = kwargs.get(
|
251
|
-
ax = kwargs.get(
|
252
|
-
if
|
253
|
-
ax=plt.gca()
|
254
|
-
|
255
|
-
default_colors =
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
opt.setdefault(
|
270
|
-
opt[
|
271
|
-
|
322
|
+
opt = kwargs.get("opt", {})
|
323
|
+
ax = kwargs.get("ax", None)
|
324
|
+
if "ax" not in locals() or ax is None:
|
325
|
+
ax = plt.gca()
|
326
|
+
|
327
|
+
default_colors = (
|
328
|
+
np.array(
|
329
|
+
[
|
330
|
+
[0, 0, 0],
|
331
|
+
[234, 37, 46],
|
332
|
+
[0, 154, 222],
|
333
|
+
[175, 89, 186],
|
334
|
+
[255, 198, 37],
|
335
|
+
[242, 133, 34],
|
336
|
+
]
|
337
|
+
)
|
338
|
+
/ 255.0
|
339
|
+
)
|
340
|
+
|
341
|
+
opt.setdefault("c", default_colors)
|
342
|
+
if len(opt["c"]) < data.shape[1]:
|
343
|
+
additional_colors = plt.cm.winter(
|
344
|
+
np.linspace(0, 1, data.shape[1] - len(opt["c"]))
|
345
|
+
)
|
346
|
+
opt["c"] = np.vstack([opt["c"], additional_colors[:, :3]])
|
347
|
+
|
348
|
+
opt.setdefault("loc", {})
|
349
|
+
opt["loc"].setdefault("go", 0)
|
350
|
+
opt["loc"].setdefault("xloc", np.arange(1, data.shape[1] + 1))
|
272
351
|
|
273
352
|
# export setting
|
274
|
-
opt.setdefault(
|
275
|
-
opt[
|
276
|
-
print(opt[
|
353
|
+
opt.setdefault("export", {})
|
354
|
+
opt["export"].setdefault("path", None)
|
355
|
+
print(opt["export"])
|
277
356
|
|
278
357
|
# opt.setdefault('layer', {})
|
279
|
-
opt.setdefault(
|
280
|
-
|
281
|
-
opt.setdefault(
|
282
|
-
opt[
|
283
|
-
opt[
|
284
|
-
opt[
|
285
|
-
opt[
|
286
|
-
opt[
|
287
|
-
opt[
|
288
|
-
opt[
|
289
|
-
opt[
|
290
|
-
opt[
|
291
|
-
opt[
|
292
|
-
opt[
|
293
|
-
|
294
|
-
opt.setdefault(
|
295
|
-
opt[
|
296
|
-
opt[
|
297
|
-
opt[
|
298
|
-
opt[
|
299
|
-
opt[
|
300
|
-
opt[
|
301
|
-
opt[
|
302
|
-
opt[
|
303
|
-
opt[
|
304
|
-
opt[
|
305
|
-
opt[
|
306
|
-
opt[
|
307
|
-
opt[
|
308
|
-
opt[
|
309
|
-
opt[
|
310
|
-
opt[
|
311
|
-
opt[
|
312
|
-
|
313
|
-
opt.setdefault(
|
314
|
-
opt[
|
315
|
-
opt[
|
316
|
-
opt[
|
317
|
-
opt[
|
318
|
-
opt[
|
319
|
-
opt[
|
320
|
-
opt[
|
321
|
-
opt[
|
322
|
-
opt[
|
323
|
-
opt[
|
324
|
-
|
325
|
-
opt.setdefault(
|
326
|
-
opt[
|
327
|
-
opt[
|
328
|
-
opt[
|
329
|
-
opt[
|
330
|
-
opt[
|
331
|
-
|
332
|
-
opt.setdefault(
|
333
|
-
opt[
|
334
|
-
opt[
|
335
|
-
opt[
|
336
|
-
opt[
|
337
|
-
opt[
|
338
|
-
opt[
|
339
|
-
opt[
|
340
|
-
opt[
|
341
|
-
opt[
|
342
|
-
opt[
|
343
|
-
opt[
|
344
|
-
opt[
|
345
|
-
opt[
|
346
|
-
opt[
|
358
|
+
opt.setdefault("layer", ["b", "bx", "e", "v", "s", "l"])
|
359
|
+
|
360
|
+
opt.setdefault("b", {})
|
361
|
+
opt["b"].setdefault("go", 1)
|
362
|
+
opt["b"].setdefault("loc", "c")
|
363
|
+
opt["b"].setdefault("FaceColor", opt["c"])
|
364
|
+
opt["b"].setdefault("FaceAlpha", 0.65)
|
365
|
+
opt["b"].setdefault("EdgeColor", "k")
|
366
|
+
opt["b"].setdefault("EdgeAlpha", 1)
|
367
|
+
opt["b"].setdefault("LineStyle", "-")
|
368
|
+
opt["b"].setdefault("LineWidth", 0.8)
|
369
|
+
opt["b"].setdefault("x_width", 0.5)
|
370
|
+
opt["b"].setdefault("ShowBaseLine", "off")
|
371
|
+
opt["b"].setdefault("hatch", None)
|
372
|
+
|
373
|
+
opt.setdefault("e", {})
|
374
|
+
opt["e"].setdefault("go", 1)
|
375
|
+
opt["e"].setdefault("loc", "l")
|
376
|
+
opt["e"].setdefault("LineWidth", 1)
|
377
|
+
opt["e"].setdefault("CapLineWidth", 1)
|
378
|
+
opt["e"].setdefault("CapSize", 2)
|
379
|
+
opt["e"].setdefault("Marker", "none")
|
380
|
+
opt["e"].setdefault("LineStyle", "none")
|
381
|
+
opt["e"].setdefault("LineColor", "k")
|
382
|
+
opt["e"].setdefault("LineJoin", "round")
|
383
|
+
opt["e"].setdefault("MarkerSize", "auto")
|
384
|
+
opt["e"].setdefault("FaceColor", opt["c"])
|
385
|
+
opt["e"].setdefault("MarkerEdgeColor", "none")
|
386
|
+
opt["e"].setdefault("Visible", True)
|
387
|
+
opt["e"].setdefault("Orientation", "vertical")
|
388
|
+
opt["e"].setdefault("error", "sem")
|
389
|
+
opt["e"].setdefault("x_width", opt["b"]["x_width"] / 5)
|
390
|
+
opt["e"].setdefault("cap_dir", "b")
|
391
|
+
|
392
|
+
opt.setdefault("s", {})
|
393
|
+
opt["s"].setdefault("go", 1)
|
394
|
+
opt["s"].setdefault("loc", "r")
|
395
|
+
opt["s"].setdefault("FaceColor", opt["c"])
|
396
|
+
opt["s"].setdefault("cmap", None)
|
397
|
+
opt["s"].setdefault("FaceAlpha", 1)
|
398
|
+
opt["s"].setdefault("x_width", opt["b"]["x_width"] / 5)
|
399
|
+
opt["s"].setdefault("Marker", "o")
|
400
|
+
opt["s"].setdefault("MarkerSize", 10)
|
401
|
+
opt["s"].setdefault("LineWidth", 0.5)
|
402
|
+
opt["s"].setdefault("MarkerEdgeColor", "k")
|
403
|
+
|
404
|
+
opt.setdefault("l", {})
|
405
|
+
opt["l"].setdefault("go", 1)
|
406
|
+
opt["l"].setdefault("LineStyle", "-")
|
407
|
+
opt["l"].setdefault("LineColor", "k")
|
408
|
+
opt["l"].setdefault("LineWidth", 0.5)
|
409
|
+
opt["l"].setdefault("LineAlpha", 0.5)
|
410
|
+
|
411
|
+
opt.setdefault("bx", {})
|
412
|
+
opt["bx"].setdefault("go", 0)
|
413
|
+
opt["bx"].setdefault("loc", "r")
|
414
|
+
opt["bx"].setdefault("FaceColor", opt["c"])
|
415
|
+
opt["bx"].setdefault("EdgeColor", "k")
|
416
|
+
opt["bx"].setdefault("FaceAlpha", 0.7)
|
417
|
+
opt["bx"].setdefault("EdgeAlpha", 1)
|
418
|
+
opt["bx"].setdefault("LineStyle", "-")
|
419
|
+
opt["bx"].setdefault("x_width", 0.2)
|
420
|
+
opt["bx"].setdefault("ShowBaseLine", "off")
|
421
|
+
opt["bx"].setdefault("Notch", False)
|
422
|
+
opt["bx"].setdefault("Outliers", "on")
|
423
|
+
opt["bx"].setdefault("OutlierMarker", "+")
|
424
|
+
opt["bx"].setdefault("OutlierColor", "r")
|
425
|
+
opt["bx"].setdefault("OutlierSize", 6)
|
347
426
|
# opt['bx'].setdefault('PlotStyle', 'traditional')
|
348
427
|
# opt['bx'].setdefault('FactorDirection', 'auto')
|
349
|
-
opt[
|
350
|
-
opt[
|
351
|
-
opt[
|
352
|
-
opt[
|
353
|
-
opt[
|
354
|
-
opt[
|
355
|
-
opt[
|
356
|
-
opt[
|
357
|
-
opt[
|
358
|
-
opt[
|
359
|
-
opt[
|
360
|
-
opt[
|
361
|
-
opt[
|
362
|
-
opt[
|
363
|
-
opt[
|
364
|
-
opt[
|
365
|
-
opt[
|
366
|
-
opt[
|
367
|
-
opt[
|
368
|
-
opt[
|
369
|
-
opt[
|
370
|
-
|
428
|
+
opt["bx"].setdefault("Whisker", 0.5)
|
429
|
+
opt["bx"].setdefault("Orientation", "vertical")
|
430
|
+
opt["bx"].setdefault("BoxLineWidth", 0.5)
|
431
|
+
opt["bx"].setdefault("FaceColor", "k")
|
432
|
+
opt["bx"].setdefault("WhiskerLineStyle", "-")
|
433
|
+
opt["bx"].setdefault("WhiskerLineColor", "k")
|
434
|
+
opt["bx"].setdefault("WhiskerLineWidth", 0.5)
|
435
|
+
opt["bx"].setdefault("Caps", True)
|
436
|
+
opt["bx"].setdefault("CapLineColor", "k")
|
437
|
+
opt["bx"].setdefault("CapLineWidth", 0.5)
|
438
|
+
opt["bx"].setdefault("CapSize", 0.2)
|
439
|
+
opt["bx"].setdefault("MedianLineStyle", "-")
|
440
|
+
opt["bx"].setdefault("MedianStyle", "line")
|
441
|
+
opt["bx"].setdefault("MedianLineColor", "k")
|
442
|
+
opt["bx"].setdefault("MedianLineWidth", 2)
|
443
|
+
opt["bx"].setdefault("MedianLineTop", False)
|
444
|
+
opt["bx"].setdefault("MeanLine", False)
|
445
|
+
opt["bx"].setdefault("showmeans", opt["bx"]["MeanLine"])
|
446
|
+
opt["bx"].setdefault("MeanLineStyle", "-")
|
447
|
+
opt["bx"].setdefault("MeanLineColor", "w")
|
448
|
+
opt["bx"].setdefault("MeanLineWidth", 2)
|
449
|
+
|
371
450
|
# Violin plot options
|
372
|
-
opt.setdefault(
|
373
|
-
opt[
|
374
|
-
opt[
|
375
|
-
opt[
|
376
|
-
opt[
|
377
|
-
opt[
|
378
|
-
opt[
|
379
|
-
opt[
|
380
|
-
opt[
|
381
|
-
opt[
|
382
|
-
opt[
|
383
|
-
opt[
|
384
|
-
|
451
|
+
opt.setdefault("v", {})
|
452
|
+
opt["v"].setdefault("go", 0)
|
453
|
+
opt["v"].setdefault("x_width", 0.3)
|
454
|
+
opt["v"].setdefault("loc", "r")
|
455
|
+
opt["v"].setdefault("EdgeColor", "none")
|
456
|
+
opt["v"].setdefault("FaceColor", opt["c"])
|
457
|
+
opt["v"].setdefault("FaceAlpha", 0.3)
|
458
|
+
opt["v"].setdefault("BandWidth", "scott")
|
459
|
+
opt["v"].setdefault("Function", "pdf")
|
460
|
+
opt["v"].setdefault("Kernel", "gau")
|
461
|
+
opt["v"].setdefault("NumPoints", 500)
|
462
|
+
opt["v"].setdefault("BoundaryCorrection", "reflection")
|
385
463
|
|
386
464
|
data_m = np.nanmean(data, axis=0)
|
387
465
|
nr, nc = data.shape
|
388
|
-
|
466
|
+
|
389
467
|
for key in kwargs.keys():
|
390
468
|
if key in opt:
|
391
469
|
if isinstance(kwargs[key], dict):
|
392
470
|
opt[key].update(kwargs[key])
|
393
471
|
else:
|
394
472
|
opt[key] = kwargs[key]
|
395
|
-
xloc = opt[
|
396
|
-
layers = sort_catplot_layers(opt[
|
397
|
-
for layer in layers:
|
398
|
-
if layer==
|
399
|
-
plot_bars(data_m, opt[
|
400
|
-
elif layer==
|
401
|
-
plot_errors(data, data_m, opt[
|
402
|
-
elif layer==
|
403
|
-
plot_scatter(data, opt[
|
404
|
-
elif layer==
|
405
|
-
plot_boxplot(data, opt[
|
406
|
-
elif layer==
|
407
|
-
plot_violin(data, opt[
|
408
|
-
elif all([layer==
|
409
|
-
plot_lines(data, opt[
|
473
|
+
xloc = opt["loc"]["xloc"]
|
474
|
+
layers = sort_catplot_layers(opt["layer"])
|
475
|
+
for layer in layers:
|
476
|
+
if layer == "b" and opt["b"]["go"]:
|
477
|
+
plot_bars(data, data_m, opt["b"], xloc, ax)
|
478
|
+
elif layer == "e" and opt["e"]["go"]:
|
479
|
+
plot_errors(data, data_m, opt["e"], xloc, ax)
|
480
|
+
elif layer == "s" and opt["s"]["go"]:
|
481
|
+
plot_scatter(data, opt["s"], xloc, ax)
|
482
|
+
elif layer == "bx" and opt["bx"]["go"]:
|
483
|
+
plot_boxplot(data, opt["bx"], xloc, ax)
|
484
|
+
elif layer == "v" and opt["v"]["go"]:
|
485
|
+
plot_violin(data, opt["v"], xloc, ax)
|
486
|
+
elif all([layer == "l", opt["l"]["go"], opt["s"]["go"]]):
|
487
|
+
plot_lines(data, opt["l"], opt["s"], ax)
|
410
488
|
# figsets
|
411
|
-
kw_figsets=kwargs.get(
|
489
|
+
kw_figsets = kwargs.get("figsets", None)
|
412
490
|
if kw_figsets is not None:
|
413
|
-
figsets(ax=ax
|
491
|
+
figsets(ax=ax, **kw_figsets)
|
414
492
|
return ax
|
415
493
|
|
494
|
+
|
416
495
|
# from py2ls.ips import get_color,figsets
|
417
496
|
# opt={}
|
418
497
|
# opt = {
|
419
498
|
# 'export':{'path':get_cwd()},
|
420
499
|
# 'c': get_color(5,cmap='jet',by='linspace'), # Custom colors for 3 categories
|
421
500
|
# 'b': {
|
422
|
-
# 'go': 0,
|
501
|
+
# 'go': 0,
|
423
502
|
# 'x_width': 0.85,
|
424
503
|
# 'FaceAlpha': 0.7,
|
425
504
|
# 'EdgeColor':'none'
|
@@ -448,7 +527,7 @@ def catplot(data, *args, **kwargs):
|
|
448
527
|
# 'FaceAlpha': 1,
|
449
528
|
# 'FaceColor':'k',
|
450
529
|
# 'LineWidth':1
|
451
|
-
|
530
|
+
|
452
531
|
# },
|
453
532
|
# 'bx':{
|
454
533
|
# 'go':1,
|
@@ -500,7 +579,7 @@ def catplot(data, *args, **kwargs):
|
|
500
579
|
import numpy as np
|
501
580
|
import matplotlib
|
502
581
|
import matplotlib.pyplot as plt
|
503
|
-
import matplotlib.ticker as tck
|
582
|
+
import matplotlib.ticker as tck
|
504
583
|
import seaborn as sns
|
505
584
|
from cycler import cycler
|
506
585
|
|
@@ -508,6 +587,7 @@ from cycler import cycler
|
|
508
587
|
def get_cmap():
|
509
588
|
return plt.colormaps()
|
510
589
|
|
590
|
+
|
511
591
|
def read_mplstyle(style_file):
|
512
592
|
# Load the style file
|
513
593
|
plt.style.use(style_file)
|
@@ -521,11 +601,14 @@ def read_mplstyle(style_file):
|
|
521
601
|
for i, j in style_dict.items():
|
522
602
|
print(f"\n{i}::::{j}")
|
523
603
|
return style_dict
|
604
|
+
|
605
|
+
|
524
606
|
# #example usage:
|
525
607
|
# style_file = "/ std-colors.mplstyle"
|
526
608
|
# style_dict = read_mplstyle(style_file)
|
527
609
|
|
528
|
-
|
610
|
+
|
611
|
+
def figsets(*args, **kwargs):
|
529
612
|
"""
|
530
613
|
usage:
|
531
614
|
figsets(ax=axs[1],
|
@@ -557,7 +640,7 @@ def figsets(*args,**kwargs):
|
|
557
640
|
box=['right','bottom'],
|
558
641
|
xrot=-45,
|
559
642
|
yangle=20,
|
560
|
-
font_sz =
|
643
|
+
font_sz = 12,
|
561
644
|
legend=dict(labels=['group_a','group_b'],
|
562
645
|
loc='upper left',
|
563
646
|
edgecolor='k',
|
@@ -575,14 +658,33 @@ def figsets(*args,**kwargs):
|
|
575
658
|
fontname = "Arial"
|
576
659
|
sns_themes = ["white", "whitegrid", "dark", "darkgrid", "ticks"]
|
577
660
|
sns_contexts = ["notebook", "talk", "poster"] # now available "paper"
|
578
|
-
scienceplots_styles = [
|
579
|
-
"
|
580
|
-
"
|
661
|
+
scienceplots_styles = [
|
662
|
+
"science",
|
663
|
+
"nature",
|
664
|
+
"scatter",
|
665
|
+
"ieee",
|
666
|
+
"no-latex",
|
667
|
+
"std-colors",
|
668
|
+
"high-vis",
|
669
|
+
"bright",
|
670
|
+
"dark_background",
|
671
|
+
"science",
|
672
|
+
"high-vis",
|
673
|
+
"vibrant",
|
674
|
+
"muted",
|
675
|
+
"retro",
|
676
|
+
"grid",
|
677
|
+
"high-contrast",
|
678
|
+
"light",
|
679
|
+
"cjk-tc-font",
|
680
|
+
"cjk-kr-font",
|
581
681
|
]
|
582
|
-
|
682
|
+
|
683
|
+
def set_step_1(ax, key, value):
|
583
684
|
if ("fo" in key) and (("size" in key) or ("sz" in key)):
|
584
|
-
fontsize=value
|
585
|
-
|
685
|
+
fontsize = value
|
686
|
+
print(fontsize)
|
687
|
+
plt.rcParams.update({"font.size": fontsize})
|
586
688
|
# style
|
587
689
|
if "st" in key.lower() or "th" in key.lower():
|
588
690
|
if isinstance(value, str):
|
@@ -611,13 +713,13 @@ def figsets(*args,**kwargs):
|
|
611
713
|
if "la" in key.lower():
|
612
714
|
if "loc" in key.lower() or "po" in key.lower():
|
613
715
|
for i in value:
|
614
|
-
if "l" in i.lower() and not
|
615
|
-
ax.yaxis.set_label_position("left")
|
616
|
-
if "r" in i.lower() and not
|
716
|
+
if "l" in i.lower() and not "g" in i.lower():
|
717
|
+
ax.yaxis.set_label_position("left")
|
718
|
+
if "r" in i.lower() and not "o" in i.lower():
|
617
719
|
ax.yaxis.set_label_position("right")
|
618
|
-
if "t" in i.lower() and not
|
720
|
+
if "t" in i.lower() and not "l" in i.lower():
|
619
721
|
ax.xaxis.set_label_position("top")
|
620
|
-
if "b" in i.lower()and not
|
722
|
+
if "b" in i.lower() and not "o" in i.lower():
|
621
723
|
ax.xaxis.set_label_position("bottom")
|
622
724
|
if ("x" in key.lower()) and (
|
623
725
|
"tic" not in key.lower() and "tk" not in key.lower()
|
@@ -631,15 +733,15 @@ def figsets(*args,**kwargs):
|
|
631
733
|
"tic" not in key.lower() and "tk" not in key.lower()
|
632
734
|
):
|
633
735
|
ax.set_zlabel(value, fontname=fontname)
|
634
|
-
if key==
|
736
|
+
if key == "xlabel" and isinstance(value, dict):
|
635
737
|
ax.set_xlabel(**value)
|
636
|
-
if key==
|
738
|
+
if key == "ylabel" and isinstance(value, dict):
|
637
739
|
ax.set_ylabel(**value)
|
638
740
|
# tick location
|
639
741
|
if "tic" in key.lower() or "tk" in key.lower():
|
640
742
|
if ("loc" in key.lower()) or ("po" in key.lower()):
|
641
|
-
if isinstance(value,str):
|
642
|
-
value=[value]
|
743
|
+
if isinstance(value, str):
|
744
|
+
value = [value]
|
643
745
|
if isinstance(value, list):
|
644
746
|
loc = []
|
645
747
|
for i in value:
|
@@ -654,28 +756,28 @@ def figsets(*args,**kwargs):
|
|
654
756
|
if i.lower() in ["a", "both", "all", "al", ":"]:
|
655
757
|
ax.xaxis.set_ticks_position("both")
|
656
758
|
ax.yaxis.set_ticks_position("both")
|
657
|
-
if i.lower() in ["xnone",
|
759
|
+
if i.lower() in ["xnone", "xoff", "none"]:
|
658
760
|
ax.xaxis.set_ticks_position("none")
|
659
|
-
if i.lower() in ["ynone",
|
761
|
+
if i.lower() in ["ynone", "yoff", "none"]:
|
660
762
|
ax.yaxis.set_ticks_position("none")
|
661
763
|
# ticks / labels
|
662
764
|
elif "x" in key.lower():
|
663
765
|
if value is None:
|
664
|
-
value=[]
|
766
|
+
value = []
|
665
767
|
if "la" not in key.lower():
|
666
768
|
ax.set_xticks(value)
|
667
769
|
if "la" in key.lower():
|
668
770
|
ax.set_xticklabels(value)
|
669
771
|
elif "y" in key.lower():
|
670
772
|
if value is None:
|
671
|
-
value=[]
|
773
|
+
value = []
|
672
774
|
if "la" not in key.lower():
|
673
775
|
ax.set_yticks(value)
|
674
776
|
if "la" in key.lower():
|
675
777
|
ax.set_yticklabels(value)
|
676
778
|
elif "z" in key.lower():
|
677
779
|
if value is None:
|
678
|
-
value=[]
|
780
|
+
value = []
|
679
781
|
if "la" not in key.lower():
|
680
782
|
ax.set_zticks(value)
|
681
783
|
if "la" in key.lower():
|
@@ -683,34 +785,34 @@ def figsets(*args,**kwargs):
|
|
683
785
|
# rotation
|
684
786
|
if "angle" in key.lower() or ("rot" in key.lower()):
|
685
787
|
if "x" in key.lower():
|
686
|
-
if value in [0,90,180,270]:
|
788
|
+
if value in [0, 90, 180, 270]:
|
687
789
|
ax.tick_params(axis="x", rotation=value)
|
688
790
|
for tick in ax.get_xticklabels():
|
689
|
-
tick.set_horizontalalignment(
|
690
|
-
elif value >0:
|
791
|
+
tick.set_horizontalalignment("center")
|
792
|
+
elif value > 0:
|
691
793
|
ax.tick_params(axis="x", rotation=value)
|
692
794
|
for tick in ax.get_xticklabels():
|
693
|
-
tick.set_horizontalalignment(
|
694
|
-
elif value <0:
|
695
|
-
ax.tick_params(axis=
|
795
|
+
tick.set_horizontalalignment("right")
|
796
|
+
elif value < 0:
|
797
|
+
ax.tick_params(axis="x", rotation=value)
|
696
798
|
for tick in ax.get_xticklabels():
|
697
|
-
tick.set_horizontalalignment(
|
799
|
+
tick.set_horizontalalignment("left")
|
698
800
|
if "y" in key.lower():
|
699
801
|
ax.tick_params(axis="y", rotation=value)
|
700
802
|
for tick in ax.get_yticklabels():
|
701
|
-
tick.set_horizontalalignment(
|
803
|
+
tick.set_horizontalalignment("right")
|
702
804
|
|
703
805
|
if "bo" in key in key: # box setting, and ("p" in key or "l" in key):
|
704
806
|
if isinstance(value, (str, list)):
|
705
807
|
locations = []
|
706
808
|
for i in value:
|
707
|
-
if "l" in i.lower() and not
|
809
|
+
if "l" in i.lower() and not "t" in i.lower():
|
708
810
|
locations.append("left")
|
709
|
-
if "r" in i.lower()and not
|
811
|
+
if "r" in i.lower() and not "o" in i.lower(): # right
|
710
812
|
locations.append("right")
|
711
|
-
if "t" in i.lower() and not
|
813
|
+
if "t" in i.lower() and not "r" in i.lower(): # top
|
712
814
|
locations.append("top")
|
713
|
-
if "b" in i.lower() and not
|
815
|
+
if "b" in i.lower() and not "t" in i.lower():
|
714
816
|
locations.append("bottom")
|
715
817
|
if i.lower() in ["a", "both", "all", "al", ":"]:
|
716
818
|
[
|
@@ -726,7 +828,7 @@ def figsets(*args,**kwargs):
|
|
726
828
|
spi.set_position(("outward", 0))
|
727
829
|
else:
|
728
830
|
spi.set_color("none") # no spine
|
729
|
-
if
|
831
|
+
if "tick" in key.lower(): # tick ticks tick_para ={}
|
730
832
|
if isinstance(value, dict):
|
731
833
|
for k, val in value.items():
|
732
834
|
if "wh" in k.lower():
|
@@ -735,28 +837,28 @@ def figsets(*args,**kwargs):
|
|
735
837
|
) # {'major', 'minor', 'both'}, default: 'major'
|
736
838
|
elif "dir" in k.lower():
|
737
839
|
ax.tick_params(direction=val) # {'in', 'out', 'inout'}
|
738
|
-
elif "len" in k.lower()
|
840
|
+
elif "len" in k.lower(): # length
|
739
841
|
ax.tick_params(length=val)
|
740
|
-
elif ("wid" in k.lower()) or ("wd" in k.lower()):
|
842
|
+
elif ("wid" in k.lower()) or ("wd" in k.lower()): # width
|
741
843
|
ax.tick_params(width=val)
|
742
|
-
elif "ax" in k.lower():
|
844
|
+
elif "ax" in k.lower(): # ax
|
743
845
|
ax.tick_params(axis=val) # {'x', 'y', 'both'}, default: 'both'
|
744
846
|
elif ("c" in k.lower()) and ("ect" not in k.lower()):
|
745
847
|
ax.tick_params(colors=val) # Tick color.
|
746
|
-
elif "pad" in k.lower() or
|
848
|
+
elif "pad" in k.lower() or "space" in k.lower():
|
747
849
|
ax.tick_params(
|
748
850
|
pad=val
|
749
851
|
) # float, distance in points between tick and label
|
750
852
|
elif (
|
751
|
-
("lab" in k.lower() or
|
853
|
+
("lab" in k.lower() or "text" in k.lower())
|
752
854
|
and ("s" in k.lower())
|
753
855
|
and ("z" in k.lower())
|
754
|
-
):
|
856
|
+
): # label_size
|
755
857
|
ax.tick_params(
|
756
858
|
labelsize=val
|
757
859
|
) # float, distance in points between tick and label
|
758
860
|
|
759
|
-
if "mi" in key.lower() and "tic" in key.lower()
|
861
|
+
if "mi" in key.lower() and "tic" in key.lower(): # minor_ticks
|
760
862
|
if "x" in value.lower() or "x" in key.lower():
|
761
863
|
ax.xaxis.set_minor_locator(tck.AutoMinorLocator()) # ax.minorticks_on()
|
762
864
|
if "y" in value.lower() or "y" in key.lower():
|
@@ -767,7 +869,8 @@ def figsets(*args,**kwargs):
|
|
767
869
|
ax.minorticks_on()
|
768
870
|
if key == "colormap" or key == "cmap":
|
769
871
|
plt.set_cmap(value)
|
770
|
-
|
872
|
+
|
873
|
+
def set_step_2(ax, key, value):
|
771
874
|
if key == "figsize":
|
772
875
|
pass
|
773
876
|
if "xlim" in key.lower():
|
@@ -776,7 +879,7 @@ def figsets(*args,**kwargs):
|
|
776
879
|
ax.set_ylim(value)
|
777
880
|
if "zlim" in key.lower():
|
778
881
|
ax.set_zlim(value)
|
779
|
-
if "sc" in key.lower():
|
882
|
+
if "sc" in key.lower(): # scale
|
780
883
|
if "x" in key.lower():
|
781
884
|
ax.set_xscale(value)
|
782
885
|
if "y" in key.lower():
|
@@ -786,19 +889,19 @@ def figsets(*args,**kwargs):
|
|
786
889
|
if key == "grid":
|
787
890
|
if isinstance(value, dict):
|
788
891
|
for k, val in value.items():
|
789
|
-
if "wh" in k.lower():
|
892
|
+
if "wh" in k.lower(): # which
|
790
893
|
ax.grid(
|
791
894
|
which=val
|
792
895
|
) # {'major', 'minor', 'both'}, default: 'major'
|
793
|
-
elif "ax" in k.lower():
|
896
|
+
elif "ax" in k.lower(): # ax
|
794
897
|
ax.grid(axis=val) # {'x', 'y', 'both'}, default: 'both'
|
795
|
-
elif ("c" in k.lower()) and ("ect" not in k.lower()):
|
898
|
+
elif ("c" in k.lower()) and ("ect" not in k.lower()): # c: color
|
796
899
|
ax.grid(color=val) # Tick color.
|
797
|
-
elif "l" in k.lower() and ("s" in k.lower())
|
900
|
+
elif "l" in k.lower() and ("s" in k.lower()): # ls:line stype
|
798
901
|
ax.grid(linestyle=val)
|
799
|
-
elif "l" in k.lower() and ("w" in k.lower()):
|
902
|
+
elif "l" in k.lower() and ("w" in k.lower()): # lw: line width
|
800
903
|
ax.grid(linewidth=val)
|
801
|
-
elif "al" in k.lower()
|
904
|
+
elif "al" in k.lower(): # alpha:
|
802
905
|
ax.grid(alpha=val)
|
803
906
|
else:
|
804
907
|
if value == "on" or value is True:
|
@@ -810,37 +913,39 @@ def figsets(*args,**kwargs):
|
|
810
913
|
plt.suptitle(value)
|
811
914
|
else:
|
812
915
|
ax.set_title(value)
|
813
|
-
if key.lower() in ["spine", "adjust", "ad", "sp", "spi", "adj","spines"]:
|
916
|
+
if key.lower() in ["spine", "adjust", "ad", "sp", "spi", "adj", "spines"]:
|
814
917
|
if isinstance(value, bool) or (value in ["go", "do", "ja", "yes"]):
|
815
918
|
if value:
|
816
919
|
adjust_spines(ax) # dafault distance=2
|
817
920
|
if isinstance(value, (float, int)):
|
818
921
|
adjust_spines(ax=ax, distance=value)
|
819
|
-
if "c" in key.lower() and (
|
922
|
+
if "c" in key.lower() and (
|
923
|
+
"sp" in key.lower() or "ax" in key.lower()
|
924
|
+
): # spine color
|
820
925
|
for loc, spi in ax.spines.items():
|
821
926
|
spi.set_color(value)
|
822
|
-
if
|
823
|
-
legend_kws = kwargs.get(
|
927
|
+
if "leg" in key.lower(): # legend
|
928
|
+
legend_kws = kwargs.get("legend", None)
|
824
929
|
if legend_kws:
|
825
930
|
# https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html
|
826
|
-
ax.legend(**legend_kws)
|
827
|
-
|
931
|
+
ax.legend(**legend_kws)
|
932
|
+
|
828
933
|
for arg in args:
|
829
|
-
if isinstance(arg,matplotlib.axes._axes.Axes):
|
830
|
-
ax=arg
|
831
|
-
args=args[1:]
|
832
|
-
ax = kwargs.get(
|
833
|
-
if
|
834
|
-
ax=plt.gca()
|
934
|
+
if isinstance(arg, matplotlib.axes._axes.Axes):
|
935
|
+
ax = arg
|
936
|
+
args = args[1:]
|
937
|
+
ax = kwargs.get("ax", plt.gca())
|
938
|
+
if "ax" not in locals() or ax is None:
|
939
|
+
ax = plt.gca()
|
835
940
|
for key, value in kwargs.items():
|
836
941
|
set_step_1(ax, key, value)
|
837
942
|
set_step_2(ax, key, value)
|
838
943
|
for arg in args:
|
839
944
|
if isinstance(arg, dict):
|
840
945
|
for k, val in arg.items():
|
841
|
-
set_step_1(ax,k, val)
|
946
|
+
set_step_1(ax, k, val)
|
842
947
|
for k, val in arg.items():
|
843
|
-
set_step_2(ax,k, val)
|
948
|
+
set_step_2(ax, k, val)
|
844
949
|
else:
|
845
950
|
Nargin = len(args) // 2
|
846
951
|
ax.labelFontSizeMultiplier = 1
|
@@ -850,11 +955,11 @@ def figsets(*args,**kwargs):
|
|
850
955
|
for ip in range(Nargin):
|
851
956
|
key = args[ip * 2].lower()
|
852
957
|
value = args[ip * 2 + 1]
|
853
|
-
set_step_1(ax,key, value)
|
958
|
+
set_step_1(ax, key, value)
|
854
959
|
for ip in range(Nargin):
|
855
960
|
key = args[ip * 2].lower()
|
856
961
|
value = args[ip * 2 + 1]
|
857
|
-
set_step_2(ax,key, value)
|
962
|
+
set_step_2(ax, key, value)
|
858
963
|
colors = [
|
859
964
|
"#474747",
|
860
965
|
"#FF2C00",
|
@@ -870,18 +975,19 @@ def figsets(*args,**kwargs):
|
|
870
975
|
plt.gcf().align_labels()
|
871
976
|
|
872
977
|
|
978
|
+
from cycler import cycler
|
873
979
|
|
874
|
-
from cycler import cycler
|
875
980
|
|
876
981
|
# set up the colorlist, give the number, or the colormap's name
|
877
|
-
def get_color(n=1, cmap="auto", by="start"):
|
982
|
+
def get_color(n=1, cmap="auto", by="start", alpha=1.0):
|
878
983
|
# Extract the colormap as a list
|
879
984
|
def cmap2hex(cmap_name):
|
880
985
|
cmap_ = matplotlib.pyplot.get_cmap(cmap_name)
|
881
986
|
colors = [cmap_(i) for i in range(cmap_.N)]
|
882
987
|
return [matplotlib.colors.rgb2hex(color) for color in colors]
|
883
988
|
# usage: clist = cmap2hex("viridis")
|
884
|
-
|
989
|
+
|
990
|
+
# Cycle times, total number is n (default n=10)
|
885
991
|
def cycle2list(colorlist, n=10):
|
886
992
|
cycler_ = cycler(tmp=colorlist)
|
887
993
|
clist = []
|
@@ -890,18 +996,24 @@ def get_color(n=1, cmap="auto", by="start"):
|
|
890
996
|
if i > n:
|
891
997
|
break
|
892
998
|
return clist
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
999
|
+
|
1000
|
+
# Converts hexadecimal color codes to RGBA values
|
1001
|
+
def hue2rgb(hex_colors, alpha=1.0):
|
1002
|
+
def hex_to_rgba(hex_color, alpha=1.0):
|
1003
|
+
"""Converts a hexadecimal color code to RGBA values."""
|
1004
|
+
if hex_color.startswith("#"):
|
897
1005
|
hex_color = hex_color.lstrip("#")
|
898
|
-
|
1006
|
+
rgb = tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
|
1007
|
+
return rgb + (alpha,)
|
1008
|
+
|
899
1009
|
if isinstance(hex_colors, str):
|
900
|
-
return
|
901
|
-
elif isinstance(hex_colors,
|
902
|
-
"""Converts a list of hexadecimal color codes to a list of
|
903
|
-
|
904
|
-
return
|
1010
|
+
return hex_to_rgba(hex_colors, alpha)
|
1011
|
+
elif isinstance(hex_colors, list):
|
1012
|
+
"""Converts a list of hexadecimal color codes to a list of RGBA values."""
|
1013
|
+
rgba_values = [hex_to_rgba(hex_color, alpha) for hex_color in hex_colors]
|
1014
|
+
return rgba_values
|
1015
|
+
|
1016
|
+
# Determine color list based on cmap parameter
|
905
1017
|
if "aut" in cmap:
|
906
1018
|
colorlist = [
|
907
1019
|
"#474747",
|
@@ -914,8 +1026,9 @@ def get_color(n=1, cmap="auto", by="start"):
|
|
914
1026
|
]
|
915
1027
|
else:
|
916
1028
|
colorlist = cmap2hex(cmap)
|
917
|
-
|
918
|
-
|
1029
|
+
|
1030
|
+
# Determine method for generating color list
|
1031
|
+
if "st" in by.lower() or "be" in by.lower():
|
919
1032
|
clist = cycle2list(colorlist, n=n)
|
920
1033
|
if "l" in by.lower() or "p" in by.lower():
|
921
1034
|
clist = []
|
@@ -924,8 +1037,15 @@ def get_color(n=1, cmap="auto", by="start"):
|
|
924
1037
|
for i in [int(i) for i in np.linspace(0, len(colorlist) - 1, n)]
|
925
1038
|
]
|
926
1039
|
|
927
|
-
|
928
|
-
|
1040
|
+
# Convert colors to RGBA format with the specified alpha
|
1041
|
+
clist_with_alpha = hue2rgb(clist, alpha)
|
1042
|
+
|
1043
|
+
return clist_with_alpha
|
1044
|
+
|
1045
|
+
# # Example usage
|
1046
|
+
# colors = get_color(n=5, cmap="viridis", by="linear", alpha=0.5)
|
1047
|
+
# print(colors)
|
1048
|
+
|
929
1049
|
|
930
1050
|
"""
|
931
1051
|
# n = 7
|
@@ -940,35 +1060,39 @@ def get_color(n=1, cmap="auto", by="start"):
|
|
940
1060
|
# figsets(plt.gca(), {"style": "whitegrid"}) """
|
941
1061
|
|
942
1062
|
|
943
|
-
|
944
1063
|
from scipy.signal import savgol_filter
|
945
|
-
import numpy as np
|
946
|
-
import matplotlib.pyplot as plt
|
1064
|
+
import numpy as np
|
1065
|
+
import matplotlib.pyplot as plt
|
1066
|
+
|
947
1067
|
|
948
|
-
def stdshade(ax=None
|
1068
|
+
def stdshade(ax=None, *args, **kwargs):
|
949
1069
|
# Separate kws_line and kws_fill if necessary
|
950
|
-
kws_line = kwargs.pop(
|
951
|
-
kws_fill = kwargs.pop(
|
1070
|
+
kws_line = kwargs.pop("kws_line", {})
|
1071
|
+
kws_fill = kwargs.pop("kws_fill", {})
|
952
1072
|
|
953
1073
|
# Merge kws_line and kws_fill into kwargs
|
954
1074
|
kwargs.update(kws_line)
|
955
1075
|
kwargs.update(kws_fill)
|
1076
|
+
|
956
1077
|
def str2list(str_):
|
957
1078
|
l = []
|
958
1079
|
[l.append(x) for x in str_]
|
959
1080
|
return l
|
1081
|
+
|
960
1082
|
def hue2rgb(hex_colors):
|
961
1083
|
def hex_to_rgb(hex_color):
|
962
1084
|
"""Converts a hexadecimal color code to RGB values."""
|
963
1085
|
if hex_colors.startswith("#"):
|
964
1086
|
hex_color = hex_color.lstrip("#")
|
965
1087
|
return tuple(int(hex_color[i : i + 2], 16) / 255.0 for i in (0, 2, 4))
|
1088
|
+
|
966
1089
|
if isinstance(hex_colors, str):
|
967
1090
|
return hex_to_rgb(hex_colors)
|
968
1091
|
elif isinstance(hex_colors, (list)):
|
969
1092
|
"""Converts a list of hexadecimal color codes to a list of RGB values."""
|
970
1093
|
rgb_values = [hex_to_rgb(hex_color) for hex_color in hex_colors]
|
971
1094
|
return rgb_values
|
1095
|
+
|
972
1096
|
if (
|
973
1097
|
isinstance(ax, np.ndarray)
|
974
1098
|
and ax.ndim == 2
|
@@ -1024,35 +1148,35 @@ def stdshade(ax=None,*args, **kwargs):
|
|
1024
1148
|
if args[iarg] in ["sem", "std"]:
|
1025
1149
|
paraStdSem = args[iarg]
|
1026
1150
|
if args[iarg].startswith("#"):
|
1027
|
-
acolor=hue2rgb(args[iarg])
|
1151
|
+
acolor = hue2rgb(args[iarg])
|
1028
1152
|
if str2list(args[iarg])[0] in l_c_one:
|
1029
1153
|
if len(args[iarg]) == 3:
|
1030
1154
|
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
1031
1155
|
if k != []:
|
1032
|
-
acolor = k[0]
|
1156
|
+
acolor = k[0]
|
1033
1157
|
st = [i for i in l_style2 if i in args[iarg]]
|
1034
1158
|
if st != []:
|
1035
|
-
plotStyle = st[0]
|
1159
|
+
plotStyle = st[0]
|
1036
1160
|
elif len(args[iarg]) == 2:
|
1037
1161
|
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
1038
1162
|
if k != []:
|
1039
|
-
acolor = k[0]
|
1163
|
+
acolor = k[0]
|
1040
1164
|
mk = [i for i in str2list(args[iarg]) if i in l_mark]
|
1041
1165
|
if mk != []:
|
1042
|
-
plotMarker = mk[0]
|
1166
|
+
plotMarker = mk[0]
|
1043
1167
|
st = [i for i in l_style1 if i in args[iarg]]
|
1044
1168
|
if st != []:
|
1045
|
-
plotStyle = st[0]
|
1169
|
+
plotStyle = st[0]
|
1046
1170
|
if len(args[iarg]) == 1:
|
1047
1171
|
k = [i for i in str2list(args[iarg]) if i in l_c_one]
|
1048
1172
|
if k != []:
|
1049
|
-
acolor = k[0]
|
1173
|
+
acolor = k[0]
|
1050
1174
|
mk = [i for i in str2list(args[iarg]) if i in l_mark]
|
1051
1175
|
if mk != []:
|
1052
|
-
plotMarker = mk[0]
|
1176
|
+
plotMarker = mk[0]
|
1053
1177
|
st = [i for i in l_style1 if i in args[iarg]]
|
1054
1178
|
if st != []:
|
1055
|
-
plotStyle = st[0]
|
1179
|
+
plotStyle = st[0]
|
1056
1180
|
if len(args[iarg]) == 2:
|
1057
1181
|
st = [i for i in l_style2 if i in args[iarg]]
|
1058
1182
|
if st != []:
|
@@ -1064,7 +1188,7 @@ def stdshade(ax=None,*args, **kwargs):
|
|
1064
1188
|
and args[iarg] >= 1
|
1065
1189
|
):
|
1066
1190
|
smth = args[iarg]
|
1067
|
-
smth = kwargs.get(
|
1191
|
+
smth = kwargs.get("smth", smth)
|
1068
1192
|
if "x" not in locals() or x is None:
|
1069
1193
|
x = np.arange(1, y.shape[1] + 1)
|
1070
1194
|
elif len(x) < y.shape[1]:
|
@@ -1097,50 +1221,50 @@ def stdshade(ax=None,*args, **kwargs):
|
|
1097
1221
|
# line_kws = kwargs.get('line_kws', {})
|
1098
1222
|
|
1099
1223
|
# setting form kwargs
|
1100
|
-
lw = kwargs.get(
|
1101
|
-
ls= kwargs.get(
|
1102
|
-
marker=kwargs.get("marker",plotMarker)
|
1103
|
-
label=kwargs.get("label",None)
|
1104
|
-
label_line = kwargs.get("label_line",None)
|
1105
|
-
label_fill = kwargs.get(
|
1106
|
-
alpha=kwargs.get(
|
1107
|
-
color=kwargs.get(
|
1224
|
+
lw = kwargs.get("lw", 0.5)
|
1225
|
+
ls = kwargs.get("ls", plotStyle)
|
1226
|
+
marker = kwargs.get("marker", plotMarker)
|
1227
|
+
label = kwargs.get("label", None)
|
1228
|
+
label_line = kwargs.get("label_line", None)
|
1229
|
+
label_fill = kwargs.get("label_fill", None)
|
1230
|
+
alpha = kwargs.get("alpha", alpha)
|
1231
|
+
color = kwargs.get("color", acolor)
|
1108
1232
|
if not label_line and label:
|
1109
1233
|
label_line = label
|
1110
|
-
kwargs[
|
1111
|
-
kwargs[
|
1112
|
-
kwargs[
|
1113
|
-
kwargs[
|
1234
|
+
kwargs["lw"] = lw
|
1235
|
+
kwargs["ls"] = ls
|
1236
|
+
kwargs["label_line"] = label_line
|
1237
|
+
kwargs["label_fill"] = label_fill
|
1114
1238
|
|
1115
1239
|
# set kws_line
|
1116
|
-
if
|
1117
|
-
kws_line[
|
1118
|
-
if
|
1119
|
-
kws_line[
|
1120
|
-
if
|
1121
|
-
kws_line[
|
1122
|
-
if
|
1123
|
-
kws_line[
|
1124
|
-
if
|
1125
|
-
kws_line[
|
1240
|
+
if "color" not in kws_line:
|
1241
|
+
kws_line["color"] = color
|
1242
|
+
if "lw" not in kws_line:
|
1243
|
+
kws_line["lw"] = lw
|
1244
|
+
if "ls" not in kws_line:
|
1245
|
+
kws_line["ls"] = ls
|
1246
|
+
if "marker" not in kws_line:
|
1247
|
+
kws_line["marker"] = marker
|
1248
|
+
if "label" not in kws_line:
|
1249
|
+
kws_line["label"] = label_line
|
1126
1250
|
|
1127
1251
|
# set kws_line
|
1128
|
-
if
|
1129
|
-
kws_fill[
|
1130
|
-
if
|
1131
|
-
kws_fill[
|
1132
|
-
if
|
1133
|
-
kws_fill[
|
1134
|
-
if
|
1135
|
-
kws_fill[
|
1252
|
+
if "color" not in kws_fill:
|
1253
|
+
kws_fill["color"] = color
|
1254
|
+
if "alpha" not in kws_fill:
|
1255
|
+
kws_fill["alpha"] = alpha
|
1256
|
+
if "lw" not in kws_fill:
|
1257
|
+
kws_fill["lw"] = 0
|
1258
|
+
if "label" not in kws_fill:
|
1259
|
+
kws_fill["label"] = label_fill
|
1136
1260
|
|
1137
1261
|
fill = ax.fill_between(x, yMean + wings, yMean - wings, **kws_fill)
|
1138
1262
|
line = ax.plot(x, yMean, **kws_line)
|
1139
1263
|
|
1140
1264
|
# figsets
|
1141
|
-
kw_figsets=kwargs.get(
|
1265
|
+
kw_figsets = kwargs.get("figsets", None)
|
1142
1266
|
if kw_figsets is not None:
|
1143
|
-
figsets(ax=ax
|
1267
|
+
figsets(ax=ax, **kw_figsets)
|
1144
1268
|
|
1145
1269
|
return line[0], fill
|
1146
1270
|
|
@@ -1175,27 +1299,30 @@ plt.legend()
|
|
1175
1299
|
"""
|
1176
1300
|
|
1177
1301
|
|
1178
|
-
def adjust_spines(ax=None, spines=[
|
1302
|
+
def adjust_spines(ax=None, spines=["left", "bottom"], distance=2):
|
1179
1303
|
if ax is None:
|
1180
1304
|
ax = plt.gca()
|
1181
1305
|
for loc, spine in ax.spines.items():
|
1182
1306
|
if loc in spines:
|
1183
|
-
spine.set_position((
|
1307
|
+
spine.set_position(("outward", distance)) # outward by 2 points
|
1184
1308
|
# spine.set_smart_bounds(True)
|
1185
1309
|
else:
|
1186
|
-
spine.set_color(
|
1310
|
+
spine.set_color("none") # don't draw spine
|
1187
1311
|
# turn off ticks where there is no spine
|
1188
|
-
if
|
1189
|
-
ax.yaxis.set_ticks_position(
|
1312
|
+
if "left" in spines:
|
1313
|
+
ax.yaxis.set_ticks_position("left")
|
1190
1314
|
else:
|
1191
1315
|
ax.yaxis.set_ticks([])
|
1192
|
-
if
|
1193
|
-
ax.xaxis.set_ticks_position(
|
1316
|
+
if "bottom" in spines:
|
1317
|
+
ax.xaxis.set_ticks_position("bottom")
|
1194
1318
|
else:
|
1195
1319
|
# no xaxis ticks
|
1196
1320
|
ax.xaxis.set_ticks([])
|
1321
|
+
|
1322
|
+
|
1197
1323
|
# And then plot the data:
|
1198
1324
|
|
1325
|
+
|
1199
1326
|
def add_colorbar(im, width=None, pad=None, **kwargs):
|
1200
1327
|
# usage: add_colorbar(im, width=0.01, pad=0.005, label="PSD (dB)", shrink=0.8)
|
1201
1328
|
l, b, w, h = im.axes.get_position().bounds # get boundaries
|
@@ -1205,6 +1332,7 @@ def add_colorbar(im, width=None, pad=None, **kwargs):
|
|
1205
1332
|
cax = fig.add_axes([l + w + pad, b, width, h]) # define cbar Axes
|
1206
1333
|
return fig.colorbar(im, cax=cax, **kwargs) # draw cbar
|
1207
1334
|
|
1335
|
+
|
1208
1336
|
def padcat(*args, fill_value=np.nan, axis=1):
|
1209
1337
|
"""
|
1210
1338
|
Concatenate vectors with padding.
|
@@ -1226,14 +1354,14 @@ def padcat(*args, fill_value=np.nan, axis=1):
|
|
1226
1354
|
max_len = max(len(lst) for lst in args)
|
1227
1355
|
result = np.full((len(args), max_len), fill_value)
|
1228
1356
|
for i, lst in enumerate(args):
|
1229
|
-
result[i, :len(lst)] = lst
|
1357
|
+
result[i, : len(lst)] = lst
|
1230
1358
|
elif axis == 1:
|
1231
1359
|
# Concatenate along columns
|
1232
1360
|
max_len = max(len(lst) for lst in args)
|
1233
1361
|
result = np.full((max_len, len(args)), fill_value)
|
1234
1362
|
for i, lst in enumerate(args):
|
1235
|
-
result[:len(lst), i] = lst
|
1363
|
+
result[: len(lst), i] = lst
|
1236
1364
|
else:
|
1237
1365
|
raise ValueError("axis must be 0 or 1")
|
1238
|
-
|
1239
|
-
return result
|
1366
|
+
|
1367
|
+
return result
|