py2ls 0.1.8.6__py3-none-any.whl → 0.1.8.8__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,6 +4,9 @@ import pandas as pd
|
|
4
4
|
from matplotlib.colors import to_rgba
|
5
5
|
from scipy.stats import gaussian_kde
|
6
6
|
|
7
|
+
import matplotlib
|
8
|
+
import matplotlib.ticker as tck
|
9
|
+
from cycler import cycler
|
7
10
|
import logging
|
8
11
|
|
9
12
|
# Suppress INFO messages from fontTools
|
@@ -18,25 +21,38 @@ def catplot(data, *args, **kwargs):
|
|
18
21
|
data (array): data matrix
|
19
22
|
"""
|
20
23
|
|
21
|
-
def plot_bars(data, data_m, opt_b, xloc, ax):
|
24
|
+
def plot_bars(data, data_m, opt_b, xloc, ax, label=None):
|
22
25
|
bar_positions = get_positions(
|
23
26
|
xloc, opt_b["loc"], opt_b["x_width"], data.shape[0]
|
24
27
|
)
|
25
28
|
bar_positions = np.nanmean(bar_positions, axis=0)
|
26
29
|
for i, (x, y) in enumerate(zip(bar_positions, data_m)):
|
27
30
|
color = to_rgba(opt_b["FaceColor"][i % len(opt_b["FaceColor"])])
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
if label is not None and i < len(label):
|
32
|
+
ax.bar(
|
33
|
+
x,
|
34
|
+
y,
|
35
|
+
width=opt_b["x_width"],
|
36
|
+
color=color,
|
37
|
+
edgecolor=opt_b["EdgeColor"],
|
38
|
+
alpha=opt_b["FaceAlpha"],
|
39
|
+
linewidth=opt_b["LineWidth"],
|
40
|
+
hatch=opt_b["hatch"],
|
41
|
+
label=label[i],
|
42
|
+
)
|
43
|
+
else:
|
44
|
+
ax.bar(
|
45
|
+
x,
|
46
|
+
y,
|
47
|
+
width=opt_b["x_width"],
|
48
|
+
color=color,
|
49
|
+
edgecolor=opt_b["EdgeColor"],
|
50
|
+
alpha=opt_b["FaceAlpha"],
|
51
|
+
linewidth=opt_b["LineWidth"],
|
52
|
+
hatch=opt_b["hatch"],
|
53
|
+
)
|
38
54
|
|
39
|
-
def plot_errors(data, data_m, opt_e, xloc, ax):
|
55
|
+
def plot_errors(data, data_m, opt_e, xloc, ax, label=None):
|
40
56
|
error_positions = get_positions(
|
41
57
|
xloc, opt_e["loc"], opt_e["x_width"], data.shape[0]
|
42
58
|
)
|
@@ -50,59 +66,110 @@ def catplot(data, *args, **kwargs):
|
|
50
66
|
if not isinstance(opt_e["MarkerEdgeColor"], list):
|
51
67
|
opt_e["MarkerEdgeColor"] = [opt_e["MarkerEdgeColor"]]
|
52
68
|
for i, (x, y, err) in enumerate(zip(error_positions, data_m, errors)):
|
53
|
-
if
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
if label is not None and i < len(label):
|
70
|
+
if opt_e["MarkerSize"] == "auto":
|
71
|
+
ax.errorbar(
|
72
|
+
x,
|
73
|
+
y,
|
74
|
+
yerr=err,
|
75
|
+
fmt=opt_e["Marker"],
|
76
|
+
ecolor=opt_e["LineColor"],
|
77
|
+
elinewidth=opt_e["LineWidth"],
|
78
|
+
lw=opt_e["LineWidth"],
|
79
|
+
ls=opt_e["LineStyle"],
|
80
|
+
capsize=opt_e["CapSize"],
|
81
|
+
capthick=opt_e["CapLineWidth"],
|
82
|
+
mec=opt_e["MarkerEdgeColor"][i % len(opt_e["MarkerEdgeColor"])],
|
83
|
+
mfc=opt_e["FaceColor"][i % len(opt_e["FaceColor"])],
|
84
|
+
visible=opt_e["Visible"],
|
85
|
+
label=label[i],
|
86
|
+
)
|
87
|
+
else:
|
88
|
+
ax.errorbar(
|
89
|
+
x,
|
90
|
+
y,
|
91
|
+
yerr=err,
|
92
|
+
fmt=opt_e["Marker"],
|
93
|
+
ecolor=opt_e["LineColor"],
|
94
|
+
elinewidth=opt_e["LineWidth"],
|
95
|
+
lw=opt_e["LineWidth"],
|
96
|
+
ls=opt_e["LineStyle"],
|
97
|
+
capsize=opt_e["CapSize"],
|
98
|
+
capthick=opt_e["CapLineWidth"],
|
99
|
+
markersize=opt_e["MarkerSize"],
|
100
|
+
mec=opt_e["MarkerEdgeColor"][i % len(opt_e["MarkerEdgeColor"])],
|
101
|
+
mfc=opt_e["FaceColor"][i % len(opt_e["FaceColor"])],
|
102
|
+
visible=opt_e["Visible"],
|
103
|
+
label=label[i],
|
104
|
+
)
|
69
105
|
else:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
106
|
+
if opt_e["MarkerSize"] == "auto":
|
107
|
+
ax.errorbar(
|
108
|
+
x,
|
109
|
+
y,
|
110
|
+
yerr=err,
|
111
|
+
fmt=opt_e["Marker"],
|
112
|
+
ecolor=opt_e["LineColor"],
|
113
|
+
elinewidth=opt_e["LineWidth"],
|
114
|
+
lw=opt_e["LineWidth"],
|
115
|
+
ls=opt_e["LineStyle"],
|
116
|
+
capsize=opt_e["CapSize"],
|
117
|
+
capthick=opt_e["CapLineWidth"],
|
118
|
+
mec=opt_e["MarkerEdgeColor"][i % len(opt_e["MarkerEdgeColor"])],
|
119
|
+
mfc=opt_e["FaceColor"][i % len(opt_e["FaceColor"])],
|
120
|
+
visible=opt_e["Visible"],
|
121
|
+
)
|
122
|
+
else:
|
123
|
+
ax.errorbar(
|
124
|
+
x,
|
125
|
+
y,
|
126
|
+
yerr=err,
|
127
|
+
fmt=opt_e["Marker"],
|
128
|
+
ecolor=opt_e["LineColor"],
|
129
|
+
elinewidth=opt_e["LineWidth"],
|
130
|
+
lw=opt_e["LineWidth"],
|
131
|
+
ls=opt_e["LineStyle"],
|
132
|
+
capsize=opt_e["CapSize"],
|
133
|
+
capthick=opt_e["CapLineWidth"],
|
134
|
+
markersize=opt_e["MarkerSize"],
|
135
|
+
mec=opt_e["MarkerEdgeColor"][i % len(opt_e["MarkerEdgeColor"])],
|
136
|
+
mfc=opt_e["FaceColor"][i % len(opt_e["FaceColor"])],
|
137
|
+
visible=opt_e["Visible"],
|
138
|
+
)
|
86
139
|
|
87
|
-
def plot_scatter(data, opt_s, xloc, ax):
|
140
|
+
def plot_scatter(data, opt_s, xloc, ax, label=None):
|
88
141
|
scatter_positions = get_positions(
|
89
142
|
xloc, opt_s["loc"], opt_s["x_width"], data.shape[0]
|
90
143
|
)
|
91
144
|
for i, (x, y) in enumerate(zip(scatter_positions.T, data.T)):
|
92
145
|
color = to_rgba(opt_s["FaceColor"][i % len(opt_s["FaceColor"])])
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
146
|
+
if label is not None and i < len(label):
|
147
|
+
ax.scatter(
|
148
|
+
x,
|
149
|
+
y,
|
150
|
+
color=color,
|
151
|
+
alpha=opt_s["FaceAlpha"],
|
152
|
+
edgecolor=opt_s["MarkerEdgeColor"],
|
153
|
+
s=opt_s["MarkerSize"],
|
154
|
+
marker=opt_s["Marker"],
|
155
|
+
linewidths=opt_s["LineWidth"],
|
156
|
+
cmap=opt_s["cmap"],
|
157
|
+
label=label[i],
|
158
|
+
)
|
159
|
+
else:
|
160
|
+
ax.scatter(
|
161
|
+
x,
|
162
|
+
y,
|
163
|
+
color=color,
|
164
|
+
alpha=opt_s["FaceAlpha"],
|
165
|
+
edgecolor=opt_s["MarkerEdgeColor"],
|
166
|
+
s=opt_s["MarkerSize"],
|
167
|
+
marker=opt_s["Marker"],
|
168
|
+
linewidths=opt_s["LineWidth"],
|
169
|
+
cmap=opt_s["cmap"],
|
170
|
+
)
|
104
171
|
|
105
|
-
def plot_boxplot(data, bx_opt, xloc, ax):
|
172
|
+
def plot_boxplot(data, bx_opt, xloc, ax, label=None):
|
106
173
|
if "l" in bx_opt["loc"]:
|
107
174
|
X_bx = xloc - bx_opt["x_width"]
|
108
175
|
elif "r" in bx_opt["loc"]:
|
@@ -162,6 +229,7 @@ def catplot(data, *args, **kwargs):
|
|
162
229
|
showmeans=bx_opt["MeanLine"],
|
163
230
|
meanprops=meanprops,
|
164
231
|
widths=bx_opt["x_width"],
|
232
|
+
label=label,
|
165
233
|
)
|
166
234
|
|
167
235
|
if bx_opt["BoxLineWidth"] < 0.1:
|
@@ -175,19 +243,84 @@ def catplot(data, *args, **kwargs):
|
|
175
243
|
if bx_opt["MedianLineTop"]:
|
176
244
|
ax.set_children(ax.get_children()[::-1]) # move median line forward
|
177
245
|
|
178
|
-
def plot_violin(data, opt_v, xloc, ax):
|
246
|
+
def plot_violin(data, opt_v, xloc, ax, label=None):
|
179
247
|
violin_positions = get_positions(
|
180
248
|
xloc, opt_v["loc"], opt_v["x_width"], data.shape[0]
|
181
249
|
)
|
182
250
|
violin_positions = np.nanmean(violin_positions, axis=0)
|
183
251
|
for i, (x, ys) in enumerate(zip(violin_positions, data.T)):
|
184
252
|
ys = ys[~np.isnan(ys)]
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
253
|
+
kde = gaussian_kde(ys, bw_method=opt_v["BandWidth"])
|
254
|
+
min_val, max_val = ys.min(), ys.max()
|
255
|
+
y_vals = np.linspace(min_val, max_val, opt_v["NumPoints"])
|
256
|
+
kde_vals = kde(y_vals)
|
257
|
+
kde_vals = kde_vals / kde_vals.max() * opt_v["x_width"]
|
258
|
+
if label is not None and i < len(label):
|
259
|
+
if len(ys) > 1:
|
260
|
+
if "r" in opt_v["loc"].lower():
|
261
|
+
ax.fill_betweenx(
|
262
|
+
y_vals,
|
263
|
+
x,
|
264
|
+
x + kde_vals,
|
265
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
266
|
+
alpha=opt_v["FaceAlpha"],
|
267
|
+
edgecolor=opt_v["EdgeColor"],
|
268
|
+
label=label[i],
|
269
|
+
)
|
270
|
+
elif (
|
271
|
+
"l" in opt_v["loc"].lower() and not "f" in opt_v["loc"].lower()
|
272
|
+
):
|
273
|
+
ax.fill_betweenx(
|
274
|
+
y_vals,
|
275
|
+
x - kde_vals,
|
276
|
+
x,
|
277
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
278
|
+
alpha=opt_v["FaceAlpha"],
|
279
|
+
edgecolor=opt_v["EdgeColor"],
|
280
|
+
label=label[i],
|
281
|
+
)
|
282
|
+
elif "o" in opt_v["loc"].lower() or "both" in opt_v["loc"].lower():
|
283
|
+
ax.fill_betweenx(
|
284
|
+
y_vals,
|
285
|
+
x - kde_vals,
|
286
|
+
x + kde_vals,
|
287
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
288
|
+
alpha=opt_v["FaceAlpha"],
|
289
|
+
edgecolor=opt_v["EdgeColor"],
|
290
|
+
label=label[i],
|
291
|
+
)
|
292
|
+
elif "i" in opt_v["loc"].lower():
|
293
|
+
if i % 2 == 1: # odd number
|
294
|
+
ax.fill_betweenx(
|
295
|
+
y_vals,
|
296
|
+
x - kde_vals,
|
297
|
+
x,
|
298
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
299
|
+
alpha=opt_v["FaceAlpha"],
|
300
|
+
edgecolor=opt_v["EdgeColor"],
|
301
|
+
label=label[i],
|
302
|
+
)
|
303
|
+
else:
|
304
|
+
ax.fill_betweenx(
|
305
|
+
y_vals,
|
306
|
+
x,
|
307
|
+
x + kde_vals,
|
308
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
309
|
+
alpha=opt_v["FaceAlpha"],
|
310
|
+
edgecolor=opt_v["EdgeColor"],
|
311
|
+
label=label[i],
|
312
|
+
)
|
313
|
+
elif "f" in opt_v["loc"].lower():
|
314
|
+
ax.fill_betweenx(
|
315
|
+
y_vals,
|
316
|
+
x - kde_vals,
|
317
|
+
x + kde_vals,
|
318
|
+
color=opt_v["FaceColor"][i % len(opt_v["FaceColor"])],
|
319
|
+
alpha=opt_v["FaceAlpha"],
|
320
|
+
edgecolor=opt_v["EdgeColor"],
|
321
|
+
label=label[i],
|
322
|
+
)
|
323
|
+
else:
|
191
324
|
if "r" in opt_v["loc"].lower():
|
192
325
|
ax.fill_betweenx(
|
193
326
|
y_vals,
|
@@ -327,7 +460,7 @@ def catplot(data, *args, **kwargs):
|
|
327
460
|
x = kwargs.get("x", None)
|
328
461
|
y = kwargs.get("y", None)
|
329
462
|
hue = kwargs.get("hue", None)
|
330
|
-
data = df2array(data=data, x=x, y=y, hue=hue)
|
463
|
+
data = df2array(data=data, x=x, y=y, hue=hue)
|
331
464
|
xticklabels = []
|
332
465
|
if hue is not None:
|
333
466
|
for i in df[x].unique().tolist():
|
@@ -337,10 +470,12 @@ def catplot(data, *args, **kwargs):
|
|
337
470
|
hue_len = len(df[hue].unique().tolist())
|
338
471
|
xticks = generate_xticks_with_gap(x_len, hue_len)
|
339
472
|
default_x_width = 0.85
|
473
|
+
legend_hue = df[hue].unique().tolist()
|
340
474
|
else:
|
341
475
|
for i in df[x].unique().tolist():
|
342
476
|
xticklabels.append(i)
|
343
477
|
xticks = np.arange(1, len(xticklabels) + 1)
|
478
|
+
legend_hue = xticklabels
|
344
479
|
default_x_width = 0.5
|
345
480
|
# when the xticklabels are too long, rotate the labels a bit
|
346
481
|
|
@@ -362,6 +497,10 @@ def catplot(data, *args, **kwargs):
|
|
362
497
|
"xticklabels": xticklabels,
|
363
498
|
"xangle": xangle,
|
364
499
|
}
|
500
|
+
else:
|
501
|
+
xticks = np.arange(1, data.shape[1] + 1)
|
502
|
+
default_x_width = 0.5
|
503
|
+
xangle = 0
|
365
504
|
|
366
505
|
# full_order
|
367
506
|
opt = kwargs.get("opt", {})
|
@@ -520,17 +659,47 @@ def catplot(data, *args, **kwargs):
|
|
520
659
|
else:
|
521
660
|
xloc = opt["loc"]["xloc"]
|
522
661
|
layers = sort_catplot_layers(opt["layer"])
|
662
|
+
|
663
|
+
label_which = kwargs.get("label_which", "barplot")
|
664
|
+
if "b" in label_which:
|
665
|
+
legend_which = "b"
|
666
|
+
elif "s" in label_which:
|
667
|
+
legend_which = "s"
|
668
|
+
elif "bx" in label_which:
|
669
|
+
legend_which = "bx"
|
670
|
+
elif "e" in label_which:
|
671
|
+
legend_which = "e"
|
672
|
+
elif "v" in label_which:
|
673
|
+
legend_which = "v"
|
674
|
+
else:
|
675
|
+
legend_which = None
|
676
|
+
|
523
677
|
for layer in layers:
|
524
678
|
if layer == "b" and opt["b"]["go"]:
|
525
|
-
|
679
|
+
if legend_which == "b":
|
680
|
+
plot_bars(data, data_m, opt["b"], xloc, ax, label=legend_hue)
|
681
|
+
else:
|
682
|
+
plot_bars(data, data_m, opt["b"], xloc, ax, label=None)
|
526
683
|
elif layer == "e" and opt["e"]["go"]:
|
527
|
-
|
684
|
+
if legend_which == "e":
|
685
|
+
plot_errors(data, data_m, opt["e"], xloc, ax, label=legend_hue)
|
686
|
+
else:
|
687
|
+
plot_errors(data, data_m, opt["e"], xloc, ax, label=None)
|
528
688
|
elif layer == "s" and opt["s"]["go"]:
|
529
|
-
|
689
|
+
if legend_which == "s":
|
690
|
+
plot_scatter(data, opt["s"], xloc, ax, label=legend_hue)
|
691
|
+
else:
|
692
|
+
plot_scatter(data, opt["s"], xloc, ax, label=None)
|
530
693
|
elif layer == "bx" and opt["bx"]["go"]:
|
531
|
-
|
694
|
+
if legend_which == "bx":
|
695
|
+
plot_boxplot(data, opt["bx"], xloc, ax, label=legend_hue)
|
696
|
+
else:
|
697
|
+
plot_boxplot(data, opt["bx"], xloc, ax, label=None)
|
532
698
|
elif layer == "v" and opt["v"]["go"]:
|
533
|
-
|
699
|
+
if legend_which == "v":
|
700
|
+
plot_violin(data, opt["v"], xloc, ax, label=legend_hue)
|
701
|
+
else:
|
702
|
+
plot_violin(data, opt["v"], xloc, ax, label=None)
|
534
703
|
elif all([layer == "l", opt["l"]["go"], opt["s"]["go"]]):
|
535
704
|
plot_lines(data, opt["l"], opt["s"], ax)
|
536
705
|
|
@@ -539,98 +708,6 @@ def catplot(data, *args, **kwargs):
|
|
539
708
|
return ax
|
540
709
|
|
541
710
|
|
542
|
-
# from py2ls.ips import get_color,figsets
|
543
|
-
# opt={}
|
544
|
-
# opt = {
|
545
|
-
# 'export':{'path':get_cwd()},
|
546
|
-
# 'c': get_color(5,cmap='jet',by='linspace'), # Custom colors for 3 categories
|
547
|
-
# 'b': {
|
548
|
-
# 'go': 0,
|
549
|
-
# 'x_width': 0.85,
|
550
|
-
# 'FaceAlpha': 0.7,
|
551
|
-
# 'EdgeColor':'none'
|
552
|
-
# },
|
553
|
-
# 'e': {
|
554
|
-
# 'loc':'r',
|
555
|
-
# 'go': 1,
|
556
|
-
# 'error': 'sem',
|
557
|
-
# 'Marker':'d',
|
558
|
-
# 'CapSize': 1,
|
559
|
-
# 'LineWidth':1,
|
560
|
-
# 'CapLineWidth':8,
|
561
|
-
# 'LineStyle':'--',
|
562
|
-
# 'MarkerSize':6,
|
563
|
-
# 'LineColor':'k',
|
564
|
-
# 'FaceColor':get_color(10),
|
565
|
-
# 'MarkerEdgeColor':'none',
|
566
|
-
# 'Visible':True
|
567
|
-
# },
|
568
|
-
# 's': {
|
569
|
-
# 'go': 1,
|
570
|
-
# 'x_width':0.2,
|
571
|
-
# 'loc':'random',
|
572
|
-
# 'Marker': 'o',
|
573
|
-
# # 'MarkerSize': 20,
|
574
|
-
# 'FaceAlpha': 1,
|
575
|
-
# 'FaceColor':'k',
|
576
|
-
# 'LineWidth':1
|
577
|
-
|
578
|
-
# },
|
579
|
-
# 'bx':{
|
580
|
-
# 'go':1,
|
581
|
-
# 'FaceAlpha':0.8,
|
582
|
-
# 'EdgeColor':'none',
|
583
|
-
# 'loc':'c',
|
584
|
-
# 'x_width':0.2,
|
585
|
-
# 'WhiskerLineWidth':1,
|
586
|
-
# 'MedianLineWidth':2,
|
587
|
-
# # 'MedianLineColor':'r',
|
588
|
-
# 'OutlierMarker':'+',
|
589
|
-
# 'OutlierColor':'r',
|
590
|
-
# 'CapSize':.2,
|
591
|
-
# # 'Caps':False,
|
592
|
-
# # 'CapLineColor':'r',
|
593
|
-
# # 'CapLineWidth':8,
|
594
|
-
# # 'MeanLine':True,
|
595
|
-
# # 'FaceColor':['r','g','b','m','c']
|
596
|
-
# },
|
597
|
-
# 'v':{
|
598
|
-
# 'go':0,
|
599
|
-
# 'loc':'r',
|
600
|
-
# 'x_width':0.2,
|
601
|
-
# 'FaceAlpha':0.51,
|
602
|
-
# },
|
603
|
-
# 'l':{
|
604
|
-
# 'go':1,
|
605
|
-
# 'LineColor':'k'
|
606
|
-
# }
|
607
|
-
# }
|
608
|
-
# data1 = np.random.rand(10, 5)
|
609
|
-
# data2 = np.random.rand(10, 5)
|
610
|
-
# fig, axs=plt.subplots(1,2,figsize=(6,2.5))
|
611
|
-
# catplot(data1, opt=opt,ax=axs[0])
|
612
|
-
# catplot(data2, opt=opt,ax=axs[1])
|
613
|
-
# figsets(sp=5,
|
614
|
-
# ax=axs[0],
|
615
|
-
# xticks=np.arange(1,6,1),
|
616
|
-
# xtickslabel=['glua1','glua2','a','b','c'],
|
617
|
-
# xlabel='proteins',
|
618
|
-
# xangle=90,
|
619
|
-
# yticks=np.arange(0,2,0.5),
|
620
|
-
# xlim=[0.75, 5.1],
|
621
|
-
# ticks=dict(pad=1,c='k'))
|
622
|
-
|
623
|
-
# figsave("/Users/macjianfeng/Dropbox/Downloads/",'test.pdf')
|
624
|
-
|
625
|
-
|
626
|
-
import numpy as np
|
627
|
-
import matplotlib
|
628
|
-
import matplotlib.pyplot as plt
|
629
|
-
import matplotlib.ticker as tck
|
630
|
-
import seaborn as sns
|
631
|
-
from cycler import cycler
|
632
|
-
|
633
|
-
|
634
711
|
def get_cmap():
|
635
712
|
return plt.colormaps()
|
636
713
|
|
@@ -1450,30 +1527,49 @@ def padcat(*args, fill_value=np.nan, axis=1, order="row"):
|
|
1450
1527
|
The value to use for padding the shorter lists (default is np.nan).
|
1451
1528
|
axis : int, optional
|
1452
1529
|
The axis along which to concatenate (0 for rows, 1 for columns, default is 1).
|
1530
|
+
order : str, optional
|
1531
|
+
The order for flattening when required: "row" or "column" (default is "row").
|
1453
1532
|
|
1454
1533
|
Returns:
|
1455
1534
|
np.ndarray
|
1456
1535
|
A 2D array with the input arrays concatenated along the specified axis,
|
1457
1536
|
padded with fill_value where necessary.
|
1458
1537
|
"""
|
1459
|
-
#
|
1538
|
+
# Set the order for processing
|
1460
1539
|
if "ro" in order.lower():
|
1461
|
-
order = "C" #
|
1540
|
+
order = "C" # row-major order
|
1462
1541
|
else:
|
1463
|
-
order = "F" # column
|
1464
|
-
|
1542
|
+
order = "F" # column-major order
|
1543
|
+
|
1544
|
+
# Process input arrays based on their dimensions
|
1545
|
+
processed_arrays = []
|
1546
|
+
for arg in args:
|
1547
|
+
arr = np.asarray(arg)
|
1548
|
+
if arr.ndim == 1:
|
1549
|
+
processed_arrays.append(arr) # Keep 1D arrays as is
|
1550
|
+
elif arr.ndim == 2:
|
1551
|
+
if axis == 0:
|
1552
|
+
# If concatenating along rows, split 2D arrays into 1D arrays row-wise
|
1553
|
+
processed_arrays.extend(arr)
|
1554
|
+
elif axis == 1:
|
1555
|
+
# If concatenating along columns, split 2D arrays into 1D arrays column-wise
|
1556
|
+
processed_arrays.extend(arr.T)
|
1557
|
+
else:
|
1558
|
+
raise ValueError("axis must be 0 or 1")
|
1559
|
+
else:
|
1560
|
+
raise ValueError("Input arrays must be 1D or 2D")
|
1465
1561
|
|
1466
1562
|
if axis == 0:
|
1467
1563
|
# Concatenate along rows
|
1468
|
-
max_len = max(arr.size for arr in
|
1469
|
-
result = np.full((len(
|
1470
|
-
for i, arr in enumerate(
|
1564
|
+
max_len = max(arr.size for arr in processed_arrays)
|
1565
|
+
result = np.full((len(processed_arrays), max_len), fill_value)
|
1566
|
+
for i, arr in enumerate(processed_arrays):
|
1471
1567
|
result[i, : arr.size] = arr
|
1472
1568
|
elif axis == 1:
|
1473
1569
|
# Concatenate along columns
|
1474
|
-
max_len = max(arr.size for arr in
|
1475
|
-
result = np.full((max_len, len(
|
1476
|
-
for i, arr in enumerate(
|
1570
|
+
max_len = max(arr.size for arr in processed_arrays)
|
1571
|
+
result = np.full((max_len, len(processed_arrays)), fill_value)
|
1572
|
+
for i, arr in enumerate(processed_arrays):
|
1477
1573
|
result[: arr.size, i] = arr
|
1478
1574
|
else:
|
1479
1575
|
raise ValueError("axis must be 0 or 1")
|
@@ -1481,49 +1577,77 @@ def padcat(*args, fill_value=np.nan, axis=1, order="row"):
|
|
1481
1577
|
return result
|
1482
1578
|
|
1483
1579
|
|
1484
|
-
|
1580
|
+
# # Example usage:
|
1581
|
+
# a = [1, np.nan]
|
1582
|
+
# b = [1, 3, 4, np.nan, 2, np.nan]
|
1583
|
+
# c = [1, 2, 3, 4, 5, 6, 7, 8, 10]
|
1584
|
+
# d = padcat(a, b)
|
1585
|
+
# result1 = padcat(d, c)
|
1586
|
+
# result2 = padcat(a, b, c)
|
1587
|
+
# print("Result of padcat(d, c):\n", result1)
|
1588
|
+
# print("Result of padcat(a, b, c):\n", result2)
|
1589
|
+
|
1590
|
+
|
1591
|
+
def sort_rows_move_nan(arr, sort=False):
|
1485
1592
|
# Handle edge cases where all values are NaN
|
1486
1593
|
if np.all(np.isnan(arr)):
|
1487
1594
|
return arr # Return unchanged if the entire array is NaN
|
1488
1595
|
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
# Sort each row
|
1496
|
-
sorted_arr = np.sort(arr_no_nan, axis=1)
|
1596
|
+
if sort:
|
1597
|
+
# Replace NaNs with a temporary large value for sorting
|
1598
|
+
temp_value = (
|
1599
|
+
np.nanmax(arr[np.isfinite(arr)]) + 1 if np.any(np.isfinite(arr)) else np.inf
|
1600
|
+
)
|
1601
|
+
arr_no_nan = np.where(np.isnan(arr), temp_value, arr)
|
1497
1602
|
|
1498
|
-
|
1499
|
-
|
1603
|
+
# Sort each row
|
1604
|
+
sorted_arr = np.sort(arr_no_nan, axis=1)
|
1500
1605
|
|
1501
|
-
|
1606
|
+
# Move NaNs to the end
|
1607
|
+
result_arr = np.where(sorted_arr == temp_value, np.nan, sorted_arr)
|
1608
|
+
else:
|
1609
|
+
result_rows = []
|
1610
|
+
for row in arr:
|
1611
|
+
# Separate non-NaN and NaN values
|
1612
|
+
non_nan_values = row[~np.isnan(row)]
|
1613
|
+
nan_count = np.isnan(row).sum()
|
1614
|
+
# Create a new row with non-NaN values followed by NaNs
|
1615
|
+
new_row = np.concatenate([non_nan_values, [np.nan] * nan_count])
|
1616
|
+
result_rows.append(new_row)
|
1617
|
+
# Convert the list of rows back into a 2D NumPy array
|
1618
|
+
result_arr = np.array(result_rows)
|
1619
|
+
|
1620
|
+
# Remove rows/columns that contain only NaNs
|
1502
1621
|
clean_arr = result_arr[~np.isnan(result_arr).all(axis=1)]
|
1503
|
-
|
1504
|
-
# Remove columns that contain only NaNs
|
1505
1622
|
clean_arr_ = clean_arr[:, ~np.isnan(clean_arr).all(axis=0)]
|
1506
1623
|
|
1507
1624
|
return clean_arr_
|
1508
1625
|
|
1509
1626
|
|
1510
|
-
def df2array(data: pd.DataFrame, x, y, hue=None):
|
1627
|
+
def df2array(data: pd.DataFrame, x, y, hue=None, sort=False):
|
1511
1628
|
if hue is None:
|
1512
1629
|
a = []
|
1513
|
-
|
1630
|
+
if sort:
|
1631
|
+
np.sort(data[x].unique().tolist()).tolist()
|
1632
|
+
else:
|
1633
|
+
cat_x = data[x].unique().tolist()
|
1514
1634
|
for i, x_ in enumerate(cat_x):
|
1515
1635
|
new_ = data.loc[data[x] == x_, y].to_list()
|
1516
1636
|
a = padcat(a, new_, axis=0)
|
1517
|
-
return sort_rows_move_nan(a.
|
1637
|
+
return sort_rows_move_nan(a).T
|
1518
1638
|
else:
|
1519
1639
|
a = []
|
1520
|
-
|
1521
|
-
|
1640
|
+
if sort:
|
1641
|
+
cat_x = np.sort(data[x].unique().tolist()).tolist()
|
1642
|
+
cat_hue = np.sort(data[hue].unique().tolist()).tolist()
|
1643
|
+
else:
|
1644
|
+
cat_x = data[x].unique().tolist()
|
1645
|
+
cat_hue = data[hue].unique().tolist()
|
1522
1646
|
for i, x_ in enumerate(cat_x):
|
1523
1647
|
for j, hue_ in enumerate(cat_hue):
|
1524
1648
|
new_ = data.loc[(data[x] == x_) & (data[hue] == hue_), y].to_list()
|
1525
1649
|
a = padcat(a, new_, axis=0)
|
1526
|
-
return sort_rows_move_nan(a.
|
1650
|
+
return sort_rows_move_nan(a).T
|
1527
1651
|
|
1528
1652
|
|
1529
1653
|
def generate_xticks_with_gap(x_len, hue_len):
|
@@ -136,12 +136,12 @@ py2ls/export_requirements.py,sha256=x2WgUF0jYKz9GfA1MVKN-MdsM-oQ8yUeC6Ua8oCymio,
|
|
136
136
|
py2ls/freqanalysis.py,sha256=F4218VSPbgL5tnngh6xNCYuNnfR-F_QjECUUxrPYZss,32594
|
137
137
|
py2ls/ips.py,sha256=6eNvNwaCDj2jyjter7VPL9oEGB2jS4ge9mSgiIrvZfo,100788
|
138
138
|
py2ls/netfinder.py,sha256=OMStrwMAASf1ajlyEfseoaEygo7G5WKBAFRE0LY15Lw,49477
|
139
|
-
py2ls/plot.py,sha256=
|
139
|
+
py2ls/plot.py,sha256=E6cV26ixVa8HFYTsTvaEtc-CgLYvaA7OhPg6S0eBZ2M,62740
|
140
140
|
py2ls/setuptools-70.1.0-py3-none-any.whl,sha256=2bi3cUVal8ip86s0SOvgspteEF8SKLukECi-EWmFomc,882588
|
141
141
|
py2ls/sleep_events_detectors.py,sha256=bQA3HJqv5qnYKJJEIhCyhlDtkXQfIzqksnD0YRXso68,52145
|
142
142
|
py2ls/stats.py,sha256=Wd9yCKQ_61QD29WMEgMuEcreFxF91NmlPW65iWT2B5w,39041
|
143
143
|
py2ls/translator.py,sha256=bc5FB-wqC4TtQz9gyCP1mE38HqNRJ_pmuRIgKnAlMzM,30581
|
144
144
|
py2ls/wb_detector.py,sha256=7y6TmBUj9exCZeIgBAJ_9hwuhkDh1x_-yg4dvNY1_GQ,6284
|
145
|
-
py2ls-0.1.8.
|
146
|
-
py2ls-0.1.8.
|
147
|
-
py2ls-0.1.8.
|
145
|
+
py2ls-0.1.8.8.dist-info/METADATA,sha256=tnUzLUWK94WS_DVJ1Jxcn_fRFrQRktuceHW0WMRfS5g,20017
|
146
|
+
py2ls-0.1.8.8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
147
|
+
py2ls-0.1.8.8.dist-info/RECORD,,
|
File without changes
|