py2ls 0.1.9.4__py3-none-any.whl → 0.1.9.5__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/.DS_Store +0 -0
- py2ls/data/styles/example/style1.pdf +0 -0
- py2ls/data/styles/example/style2.pdf +0 -0
- py2ls/data/styles/example/style3.pdf +0 -0
- py2ls/data/styles/example/style4.pdf +0 -0
- py2ls/data/styles/example/style5.pdf +0 -0
- py2ls/data/styles/example/style6.pdf +0 -0
- py2ls/data/styles/example/style7.pdf +0 -0
- py2ls/data/styles/example/style8.pdf +0 -0
- py2ls/data/styles/example/style9.pdf +0 -0
- py2ls/data/styles/style6.json +31 -20
- py2ls/data/styles/style7.json +201 -0
- py2ls/data/styles/style8.json +199 -0
- py2ls/data/styles/style9.json +215 -0
- py2ls/plot.py +394 -35
- py2ls/stats.py +130 -340
- {py2ls-0.1.9.4.dist-info → py2ls-0.1.9.5.dist-info}/METADATA +1 -1
- {py2ls-0.1.9.4.dist-info → py2ls-0.1.9.5.dist-info}/RECORD +19 -7
- {py2ls-0.1.9.4.dist-info → py2ls-0.1.9.5.dist-info}/WHEEL +0 -0
py2ls/plot.py
CHANGED
@@ -9,7 +9,8 @@ import matplotlib.ticker as tck
|
|
9
9
|
from cycler import cycler
|
10
10
|
import logging
|
11
11
|
import os
|
12
|
-
|
12
|
+
|
13
|
+
from .ips import fsave, fload, mkdir, listdir
|
13
14
|
from .stats import *
|
14
15
|
|
15
16
|
# Suppress INFO messages from fontTools
|
@@ -28,8 +29,25 @@ def catplot(data, *args, **kwargs):
|
|
28
29
|
"""
|
29
30
|
|
30
31
|
def plot_bars(data, data_m, opt_b, xloc, ax, label=None):
|
32
|
+
if "l" in opt_b["loc"]:
|
33
|
+
xloc_s = xloc - opt_b["x_dist"]
|
34
|
+
elif "r" in opt_b["loc"]:
|
35
|
+
xloc_s = xloc + opt_b["x_dist"]
|
36
|
+
elif "i" in opt_b["loc"]:
|
37
|
+
xloc_s = xloc
|
38
|
+
xloc_s[:, 0] += opt_b["x_dist"]
|
39
|
+
xloc_s[:, -1] -= opt_b["x_dist"]
|
40
|
+
elif "o" in opt_b["loc"]:
|
41
|
+
xloc_s = xloc
|
42
|
+
xloc_s[:, 0] -= opt_b["x_dist"]
|
43
|
+
xloc_s[:, -1] += opt_b["x_dist"]
|
44
|
+
elif "c" in opt_b["loc"] or "m" in opt_b["loc"]:
|
45
|
+
xloc_s = xloc
|
46
|
+
else:
|
47
|
+
xloc_s = xloc
|
48
|
+
|
31
49
|
bar_positions = get_positions(
|
32
|
-
|
50
|
+
xloc_s, opt_b["loc"], opt_b["x_width"], data.shape[0]
|
33
51
|
)
|
34
52
|
bar_positions = np.nanmean(bar_positions, axis=0)
|
35
53
|
for i, (x, y) in enumerate(zip(bar_positions, data_m)):
|
@@ -60,12 +78,22 @@ def catplot(data, *args, **kwargs):
|
|
60
78
|
|
61
79
|
def plot_errors(data, data_m, opt_e, xloc, ax, label=None):
|
62
80
|
error_positions = get_positions(
|
63
|
-
xloc, opt_e["loc"], opt_e["
|
81
|
+
xloc, opt_e["loc"], opt_e["x_dist"], data.shape[0]
|
64
82
|
)
|
65
83
|
error_positions = np.nanmean(error_positions, axis=0)
|
66
84
|
errors = np.nanstd(data, axis=0, ddof=1)
|
67
85
|
if opt_e["error"] == "sem":
|
68
86
|
errors /= np.sqrt(np.sum(~np.isnan(data), axis=0))
|
87
|
+
if opt_e["LineStyle"] != "none":
|
88
|
+
# draw lines
|
89
|
+
ax.plot(
|
90
|
+
error_positions,
|
91
|
+
data_m,
|
92
|
+
color=opt_e["LineColor"],
|
93
|
+
linestyle=opt_e["LineStyle"],
|
94
|
+
linewidth=opt_e["LineWidth"],
|
95
|
+
alpha=opt_e["LineAlpha"],
|
96
|
+
)
|
69
97
|
|
70
98
|
if not isinstance(opt_e["FaceColor"], list):
|
71
99
|
opt_e["FaceColor"] = [opt_e["FaceColor"]]
|
@@ -144,8 +172,25 @@ def catplot(data, *args, **kwargs):
|
|
144
172
|
)
|
145
173
|
|
146
174
|
def plot_scatter(data, opt_s, xloc, ax, label=None):
|
175
|
+
if "l" in opt_s["loc"]:
|
176
|
+
xloc_s = xloc - opt_s["x_dist"]
|
177
|
+
elif "r" in opt_s["loc"]:
|
178
|
+
xloc_s = xloc + opt_s["x_dist"]
|
179
|
+
elif "i" in opt_s["loc"]:
|
180
|
+
xloc_s = xloc
|
181
|
+
xloc_s[:, 0] += opt_s["x_dist"]
|
182
|
+
xloc_s[:, -1] -= opt_s["x_dist"]
|
183
|
+
elif "o" in opt_s["loc"]:
|
184
|
+
xloc_s = xloc
|
185
|
+
xloc_s[:, 0] -= opt_s["x_dist"]
|
186
|
+
xloc_s[:, -1] += opt_s["x_dist"]
|
187
|
+
elif "c" in opt_s["loc"] or "m" in opt_s["loc"]:
|
188
|
+
xloc_s = xloc
|
189
|
+
else:
|
190
|
+
xloc_s = xloc
|
191
|
+
|
147
192
|
scatter_positions = get_positions(
|
148
|
-
|
193
|
+
xloc_s, opt_s["loc"], opt_s["x_width"], data.shape[0]
|
149
194
|
)
|
150
195
|
for i, (x, y) in enumerate(zip(scatter_positions.T, data.T)):
|
151
196
|
color = to_rgba(opt_s["FaceColor"][i % len(opt_s["FaceColor"])])
|
@@ -177,17 +222,17 @@ def catplot(data, *args, **kwargs):
|
|
177
222
|
|
178
223
|
def plot_boxplot(data, bx_opt, xloc, ax, label=None):
|
179
224
|
if "l" in bx_opt["loc"]:
|
180
|
-
X_bx = xloc - bx_opt["
|
225
|
+
X_bx = xloc - bx_opt["x_dist"]
|
181
226
|
elif "r" in bx_opt["loc"]:
|
182
|
-
X_bx = xloc + bx_opt["
|
227
|
+
X_bx = xloc + bx_opt["x_dist"]
|
183
228
|
elif "i" in bx_opt["loc"]:
|
184
229
|
X_bx = xloc
|
185
|
-
X_bx[:, 0] += bx_opt["
|
186
|
-
X_bx[:, -1] -= bx_opt["
|
230
|
+
X_bx[:, 0] += bx_opt["x_dist"]
|
231
|
+
X_bx[:, -1] -= bx_opt["x_dist"]
|
187
232
|
elif "o" in bx_opt["loc"]:
|
188
233
|
X_bx = xloc
|
189
|
-
X_bx[:, 0] -= bx_opt["
|
190
|
-
X_bx[:, -1] += bx_opt["
|
234
|
+
X_bx[:, 0] -= bx_opt["x_dist"]
|
235
|
+
X_bx[:, -1] += bx_opt["x_dist"]
|
191
236
|
elif "c" in bx_opt["loc"] or "m" in bx_opt["loc"]:
|
192
237
|
X_bx = xloc
|
193
238
|
else:
|
@@ -196,7 +241,8 @@ def catplot(data, *args, **kwargs):
|
|
196
241
|
boxprops = dict(color=bx_opt["EdgeColor"], linewidth=bx_opt["BoxLineWidth"])
|
197
242
|
flierprops = dict(
|
198
243
|
marker=bx_opt["OutlierMarker"],
|
199
|
-
markerfacecolor=bx_opt["
|
244
|
+
markerfacecolor=bx_opt["OutlierFaceColor"],
|
245
|
+
markeredgecolor=bx_opt["OutlierEdgeColor"],
|
200
246
|
markersize=bx_opt["OutlierSize"],
|
201
247
|
)
|
202
248
|
whiskerprops = dict(
|
@@ -258,9 +304,9 @@ def catplot(data, *args, **kwargs):
|
|
258
304
|
if bx_opt["MedianLineTop"]:
|
259
305
|
ax.set_children(ax.get_children()[::-1]) # move median line forward
|
260
306
|
|
261
|
-
def plot_violin(data, opt_v, xloc, ax, label=None):
|
307
|
+
def plot_violin(data, opt_v, xloc, ax, label=None, vertical=True):
|
262
308
|
violin_positions = get_positions(
|
263
|
-
xloc, opt_v["loc"], opt_v["
|
309
|
+
xloc, opt_v["loc"], opt_v["x_dist"], data.shape[0]
|
264
310
|
)
|
265
311
|
violin_positions = np.nanmean(violin_positions, axis=0)
|
266
312
|
for i, (x, ys) in enumerate(zip(violin_positions, data.T)):
|
@@ -392,9 +438,158 @@ def catplot(data, *args, **kwargs):
|
|
392
438
|
edgecolor=opt_v["EdgeColor"],
|
393
439
|
)
|
394
440
|
|
441
|
+
def plot_ridgeplot(data, x, y, opt_r, **kwargs_figsets):
|
442
|
+
# in the sns.FacetGrid class, the 'hue' argument is the one that is the one that will be represented by colors with 'palette'
|
443
|
+
if opt_r["column4color"] is None:
|
444
|
+
column4color = x
|
445
|
+
else:
|
446
|
+
column4color = opt_r["column4color"]
|
447
|
+
|
448
|
+
if opt_r["row_labels"] is None:
|
449
|
+
opt_r["row_labels"] = data[x].unique().tolist()
|
450
|
+
|
451
|
+
if isinstance(opt_r["FaceColor"], str):
|
452
|
+
opt_r["FaceColor"] = [opt_r["FaceColor"]]
|
453
|
+
if len(opt_r["FaceColor"]) == 1:
|
454
|
+
opt_r["FaceColor"] = np.tile(
|
455
|
+
opt_r["FaceColor"], [1, len(opt_r["row_labels"])]
|
456
|
+
)[0]
|
457
|
+
if len(opt_r["FaceColor"]) > len(opt_r["row_labels"]):
|
458
|
+
opt_r["FaceColor"] = opt_r["FaceColor"][: len(opt_r["row_labels"])]
|
459
|
+
|
460
|
+
g = sns.FacetGrid(
|
461
|
+
data=data,
|
462
|
+
row=x,
|
463
|
+
hue=column4color,
|
464
|
+
aspect=opt_r["aspect"],
|
465
|
+
height=opt_r["subplot_height"],
|
466
|
+
palette=opt_r["FaceColor"],
|
467
|
+
)
|
468
|
+
|
469
|
+
# kdeplot
|
470
|
+
g.map(
|
471
|
+
sns.kdeplot,
|
472
|
+
y,
|
473
|
+
bw_adjust=opt_r["bw_adjust"],
|
474
|
+
clip_on=opt_r["clip"],
|
475
|
+
fill=opt_r["fill"],
|
476
|
+
alpha=opt_r["FaceAlpha"],
|
477
|
+
linewidth=opt_r["EdgeLineWidth"],
|
478
|
+
)
|
479
|
+
|
480
|
+
# edge / line of kdeplot
|
481
|
+
if opt_r["EdgeColor"] is not None:
|
482
|
+
g.map(
|
483
|
+
sns.kdeplot,
|
484
|
+
y,
|
485
|
+
bw_adjust=opt_r["bw_adjust"],
|
486
|
+
clip_on=opt_r["clip"],
|
487
|
+
color=opt_r["EdgeColor"],
|
488
|
+
lw=opt_r["EdgeLineWidth"],
|
489
|
+
)
|
490
|
+
else:
|
491
|
+
g.map(
|
492
|
+
sns.kdeplot,
|
493
|
+
y,
|
494
|
+
bw_adjust=opt_r["bw_adjust"],
|
495
|
+
clip_on=opt_r["clip"],
|
496
|
+
color=opt_r["EdgeColor"],
|
497
|
+
lw=opt_r["EdgeLineWidth"],
|
498
|
+
)
|
499
|
+
|
500
|
+
# add a horizontal line
|
501
|
+
if opt_r["xLineColor"] is not None:
|
502
|
+
g.map(
|
503
|
+
plt.axhline,
|
504
|
+
y=0,
|
505
|
+
lw=opt_r["xLineWidth"],
|
506
|
+
clip_on=opt_r["clip"],
|
507
|
+
color=opt_r["xLineColor"],
|
508
|
+
)
|
509
|
+
else:
|
510
|
+
g.map(
|
511
|
+
plt.axhline,
|
512
|
+
y=0,
|
513
|
+
lw=opt_r["xLineWidth"],
|
514
|
+
clip_on=opt_r["clip"],
|
515
|
+
)
|
516
|
+
|
517
|
+
if isinstance(opt_r["color_row_label"], str):
|
518
|
+
opt_r["color_row_label"] = [opt_r["color_row_label"]]
|
519
|
+
if len(opt_r["color_row_label"]) == 1:
|
520
|
+
opt_r["color_row_label"] = np.tile(
|
521
|
+
opt_r["color_row_label"], [1, len(opt_r["row_labels"])]
|
522
|
+
)[0]
|
523
|
+
|
524
|
+
# loop over the FacetGrid figure axes (g.axes.flat)
|
525
|
+
for i, ax in enumerate(g.axes.flat):
|
526
|
+
if kwargs_figsets.get("xlim", False):
|
527
|
+
ax.set_xlim(kwargs_figsets.get("xlim", False))
|
528
|
+
if kwargs_figsets.get("xlim", False):
|
529
|
+
ax.set_ylim(kwargs_figsets.get("ylim", False))
|
530
|
+
if i == 0:
|
531
|
+
row_x = opt_r["row_label_loc_xscale"] * np.abs(
|
532
|
+
np.diff(ax.get_xlim())
|
533
|
+
) + np.min(ax.get_xlim())
|
534
|
+
row_y = opt_r["row_label_loc_yscale"] * np.abs(
|
535
|
+
np.diff(ax.get_ylim())
|
536
|
+
) + np.min(ax.get_ylim())
|
537
|
+
ax.set_title(kwargs_figsets.get("title", ""))
|
538
|
+
ax.text(
|
539
|
+
row_x,
|
540
|
+
row_y,
|
541
|
+
opt_r["row_labels"][i],
|
542
|
+
fontweight=opt_r["fontweight"],
|
543
|
+
fontsize=opt_r["fontsize"],
|
544
|
+
color=opt_r["color_row_label"][i],
|
545
|
+
)
|
546
|
+
figsets(**kwargs_figsets)
|
547
|
+
|
548
|
+
# we use matplotlib.Figure.subplots_adjust() function to get the subplots to overlap
|
549
|
+
g.fig.subplots_adjust(hspace=opt_r["subplot_hspace"])
|
550
|
+
|
551
|
+
# eventually we remove axes titles, yticks and spines
|
552
|
+
g.set_titles("")
|
553
|
+
g.set(yticks=[])
|
554
|
+
g.set(ylabel=opt_r["subplot_ylabel"])
|
555
|
+
# if kwargs_figsets:
|
556
|
+
# g.set(**kwargs_figsets)
|
557
|
+
if kwargs_figsets.get("xlim", False):
|
558
|
+
g.set(xlim=kwargs_figsets.get("xlim", False))
|
559
|
+
g.despine(bottom=True, left=True)
|
560
|
+
|
561
|
+
plt.setp(
|
562
|
+
ax.get_xticklabels(),
|
563
|
+
fontsize=opt_r["fontsize"],
|
564
|
+
fontweight=opt_r["fontweight"],
|
565
|
+
)
|
566
|
+
# if opt_r["ylabel"] is None:
|
567
|
+
# opt_r["ylabel"] = y
|
568
|
+
# plt.xlabel(
|
569
|
+
# opt_r["ylabel"], fontweight=opt_r["fontweight"], fontsize=opt_r["fontsize"]
|
570
|
+
# )
|
571
|
+
return g, opt_r
|
572
|
+
|
395
573
|
def plot_lines(data, opt_l, opt_s, ax):
|
574
|
+
if "l" in opt_s["loc"]:
|
575
|
+
xloc_s = xloc - opt_s["x_dist"]
|
576
|
+
elif "r" in opt_s["loc"]:
|
577
|
+
xloc_s = xloc + opt_s["x_dist"]
|
578
|
+
elif "i" in opt_s["loc"]:
|
579
|
+
xloc_s = xloc
|
580
|
+
xloc_s[:, 0] += opt_s["x_dist"]
|
581
|
+
xloc_s[:, -1] -= opt_s["x_dist"]
|
582
|
+
elif "o" in opt_s["loc"]:
|
583
|
+
xloc_s = xloc
|
584
|
+
xloc_s[:, 0] -= opt_s["x_dist"]
|
585
|
+
xloc_s[:, -1] += opt_s["x_dist"]
|
586
|
+
elif "c" in opt_s["loc"] or "m" in opt_s["loc"]:
|
587
|
+
xloc_s = xloc
|
588
|
+
else:
|
589
|
+
xloc_s = xloc
|
590
|
+
|
396
591
|
scatter_positions = get_positions(
|
397
|
-
|
592
|
+
xloc_s, opt_s["loc"], opt_s["x_width"], data.shape[0]
|
398
593
|
)
|
399
594
|
for incol in range(data.shape[1] - 1):
|
400
595
|
for irow in range(data.shape[0]):
|
@@ -448,6 +643,8 @@ def catplot(data, *args, **kwargs):
|
|
448
643
|
"""
|
449
644
|
sort layers
|
450
645
|
"""
|
646
|
+
if "r" in full_order:
|
647
|
+
return ["r"]
|
451
648
|
# Ensure custom_order is a list of strings
|
452
649
|
custom_order = [str(layer) for layer in custom_order]
|
453
650
|
j = 1
|
@@ -469,10 +666,9 @@ def catplot(data, *args, **kwargs):
|
|
469
666
|
|
470
667
|
ax = kwargs.get("ax", None)
|
471
668
|
col = kwargs.get("col", None)
|
669
|
+
report = kwargs.get("report", True)
|
670
|
+
vertical = kwargs.get("vertical", True)
|
472
671
|
if not col:
|
473
|
-
if "ax" not in locals() or ax is None:
|
474
|
-
ax = plt.gca()
|
475
|
-
|
476
672
|
kw_figsets = kwargs.get("figsets", None)
|
477
673
|
# check the data type
|
478
674
|
if isinstance(data, pd.DataFrame):
|
@@ -608,15 +804,20 @@ def catplot(data, *args, **kwargs):
|
|
608
804
|
if "style" in k and "exp" not in k:
|
609
805
|
style_use = v
|
610
806
|
break
|
611
|
-
if style_use:
|
807
|
+
if style_use is not None:
|
612
808
|
try:
|
613
809
|
dir_curr_script = os.path.dirname(os.path.abspath(__file__))
|
614
810
|
dir_style = dir_curr_script + "/data/styles/"
|
615
|
-
|
811
|
+
if isinstance(style_use, str):
|
812
|
+
style_load = fload(dir_style + style_use + ".json")
|
813
|
+
else:
|
814
|
+
style_load = fload(
|
815
|
+
listdir(dir_style, "json").path.tolist()[style_use]
|
816
|
+
)
|
616
817
|
style_load = remove_colors_in_dict(style_load)
|
617
818
|
opt.update(style_load)
|
618
819
|
except:
|
619
|
-
print(f"cannot find the style'{
|
820
|
+
print(f"cannot find the style'{style_use}'")
|
620
821
|
|
621
822
|
color_custom = kwargs.get("c", default_colors)
|
622
823
|
if not isinstance(color_custom, list):
|
@@ -631,7 +832,6 @@ def catplot(data, *args, **kwargs):
|
|
631
832
|
|
632
833
|
# export setting
|
633
834
|
opt.setdefault("style", {})
|
634
|
-
opt["style"].setdefault("export", None)
|
635
835
|
opt.setdefault("layer", ["b", "bx", "e", "v", "s", "l"])
|
636
836
|
|
637
837
|
opt.setdefault("b", {})
|
@@ -644,18 +844,20 @@ def catplot(data, *args, **kwargs):
|
|
644
844
|
opt["b"].setdefault("LineStyle", "-")
|
645
845
|
opt["b"].setdefault("LineWidth", 0.8)
|
646
846
|
opt["b"].setdefault("x_width", default_x_width)
|
847
|
+
opt["b"].setdefault("x_dist", opt["b"]["x_width"])
|
647
848
|
opt["b"].setdefault("ShowBaseLine", "off")
|
648
849
|
opt["b"].setdefault("hatch", None)
|
649
850
|
|
650
851
|
opt.setdefault("e", {})
|
651
852
|
opt["e"].setdefault("go", 1)
|
652
853
|
opt["e"].setdefault("loc", "l")
|
653
|
-
opt["e"].setdefault("LineWidth",
|
854
|
+
opt["e"].setdefault("LineWidth", 2)
|
654
855
|
opt["e"].setdefault("CapLineWidth", 1)
|
655
856
|
opt["e"].setdefault("CapSize", 2)
|
656
857
|
opt["e"].setdefault("Marker", "none")
|
657
858
|
opt["e"].setdefault("LineStyle", "none")
|
658
859
|
opt["e"].setdefault("LineColor", "k")
|
860
|
+
opt["e"].setdefault("LineAlpha", 0.5)
|
659
861
|
opt["e"].setdefault("LineJoin", "round")
|
660
862
|
opt["e"].setdefault("MarkerSize", "auto")
|
661
863
|
opt["e"].setdefault("FaceColor", color_custom)
|
@@ -664,22 +866,24 @@ def catplot(data, *args, **kwargs):
|
|
664
866
|
opt["e"].setdefault("Orientation", "vertical")
|
665
867
|
opt["e"].setdefault("error", "sem")
|
666
868
|
opt["e"].setdefault("x_width", default_x_width / 5)
|
869
|
+
opt["e"].setdefault("x_dist", opt["e"]["x_width"])
|
667
870
|
opt["e"].setdefault("cap_dir", "b")
|
668
871
|
|
669
872
|
opt.setdefault("s", {})
|
670
873
|
opt["s"].setdefault("go", 1)
|
671
874
|
opt["s"].setdefault("loc", "r")
|
672
|
-
opt["s"].setdefault("FaceColor",
|
875
|
+
opt["s"].setdefault("FaceColor", color_custom)
|
673
876
|
opt["s"].setdefault("cmap", None)
|
674
877
|
opt["s"].setdefault("FaceAlpha", 1)
|
675
|
-
opt["s"].setdefault("x_width", default_x_width / 5)
|
878
|
+
opt["s"].setdefault("x_width", default_x_width / 5 * 0.5)
|
879
|
+
opt["s"].setdefault("x_dist", opt["s"]["x_width"])
|
676
880
|
opt["s"].setdefault("Marker", "o")
|
677
881
|
opt["s"].setdefault("MarkerSize", 15)
|
678
882
|
opt["s"].setdefault("LineWidth", 0.8)
|
679
883
|
opt["s"].setdefault("MarkerEdgeColor", "k")
|
680
884
|
|
681
885
|
opt.setdefault("l", {})
|
682
|
-
opt["l"].setdefault("go",
|
886
|
+
opt["l"].setdefault("go", 0)
|
683
887
|
opt["l"].setdefault("LineStyle", "-")
|
684
888
|
opt["l"].setdefault("LineColor", "k")
|
685
889
|
opt["l"].setdefault("LineWidth", 0.5)
|
@@ -694,11 +898,13 @@ def catplot(data, *args, **kwargs):
|
|
694
898
|
opt["bx"].setdefault("EdgeAlpha", 1)
|
695
899
|
opt["bx"].setdefault("LineStyle", "-")
|
696
900
|
opt["bx"].setdefault("x_width", default_x_width / 5)
|
901
|
+
opt["bx"].setdefault("x_dist", opt["bx"]["x_width"])
|
697
902
|
opt["bx"].setdefault("ShowBaseLine", "off")
|
698
903
|
opt["bx"].setdefault("Notch", False)
|
699
904
|
opt["bx"].setdefault("Outliers", "on")
|
700
905
|
opt["bx"].setdefault("OutlierMarker", "+")
|
701
|
-
opt["bx"].setdefault("
|
906
|
+
opt["bx"].setdefault("OutlierFaceColor", "r")
|
907
|
+
opt["bx"].setdefault("OutlierEdgeColor", "k")
|
702
908
|
opt["bx"].setdefault("OutlierSize", 6)
|
703
909
|
# opt['bx'].setdefault('PlotStyle', 'traditional')
|
704
910
|
# opt['bx'].setdefault('FactorDirection', 'auto')
|
@@ -730,16 +936,42 @@ def catplot(data, *args, **kwargs):
|
|
730
936
|
opt.setdefault("v", {})
|
731
937
|
opt["v"].setdefault("go", 0)
|
732
938
|
opt["v"].setdefault("x_width", 0.3)
|
939
|
+
opt["v"].setdefault("x_dist", opt["v"]["x_width"])
|
733
940
|
opt["v"].setdefault("loc", "r")
|
734
941
|
opt["v"].setdefault("EdgeColor", "none")
|
735
942
|
opt["v"].setdefault("FaceColor", color_custom)
|
736
|
-
opt["v"].setdefault("FaceAlpha",
|
943
|
+
opt["v"].setdefault("FaceAlpha", 1)
|
737
944
|
opt["v"].setdefault("BandWidth", "scott")
|
738
945
|
opt["v"].setdefault("Function", "pdf")
|
739
946
|
opt["v"].setdefault("Kernel", "gau")
|
740
947
|
opt["v"].setdefault("NumPoints", 500)
|
741
948
|
opt["v"].setdefault("BoundaryCorrection", "reflection")
|
742
949
|
|
950
|
+
# ridgeplot
|
951
|
+
opt.setdefault("r", {})
|
952
|
+
opt["r"].setdefault("go", 0)
|
953
|
+
opt["r"].setdefault("bw_adjust", 1)
|
954
|
+
opt["r"].setdefault("clip", False)
|
955
|
+
opt["r"].setdefault("FaceColor", get_color(20))
|
956
|
+
opt["r"].setdefault("FaceAlpha", 1)
|
957
|
+
opt["r"].setdefault("EdgeLineWidth", 1.5)
|
958
|
+
opt["r"].setdefault("fill", True)
|
959
|
+
opt["r"].setdefault("EdgeColor", "none")
|
960
|
+
opt["r"].setdefault("xLineWidth", opt["r"]["EdgeLineWidth"] + 0.5)
|
961
|
+
opt["r"].setdefault("xLineColor", "none")
|
962
|
+
opt["r"].setdefault("aspect", 8)
|
963
|
+
opt["r"].setdefault("subplot_hspace", -0.3) # overlap subplots
|
964
|
+
opt["r"].setdefault("subplot_height", 0.75)
|
965
|
+
opt["r"].setdefault("subplot_ylabel", "")
|
966
|
+
opt["r"].setdefault("column4color", None)
|
967
|
+
opt["r"].setdefault("row_labels", None)
|
968
|
+
opt["r"].setdefault("row_label_loc_xscale", 0.01)
|
969
|
+
opt["r"].setdefault("row_label_loc_yscale", 0.05)
|
970
|
+
opt["r"].setdefault("fontweight", plt.rcParams["font.weight"])
|
971
|
+
opt["r"].setdefault("fontsize", plt.rcParams["font.size"])
|
972
|
+
opt["r"].setdefault("color_row_label", "k")
|
973
|
+
opt["r"].setdefault("ylabel", None)
|
974
|
+
|
743
975
|
data_m = np.nanmean(data, axis=0)
|
744
976
|
nr, nc = data.shape
|
745
977
|
|
@@ -753,8 +985,13 @@ def catplot(data, *args, **kwargs):
|
|
753
985
|
xloc = np.array(opt["loc"]["xloc"])
|
754
986
|
else:
|
755
987
|
xloc = opt["loc"]["xloc"]
|
756
|
-
|
988
|
+
if opt["r"]["go"]:
|
989
|
+
layers = sort_catplot_layers(opt["layer"], "r")
|
990
|
+
else:
|
991
|
+
layers = sort_catplot_layers(opt["layer"])
|
757
992
|
|
993
|
+
if ("ax" not in locals() or ax is None) and not opt["r"]["go"]:
|
994
|
+
ax = plt.gca()
|
758
995
|
label = kwargs.get("label", "bar")
|
759
996
|
if label:
|
760
997
|
if "b" in label:
|
@@ -792,23 +1029,37 @@ def catplot(data, *args, **kwargs):
|
|
792
1029
|
plot_boxplot(data, opt["bx"], xloc, ax, label=None)
|
793
1030
|
elif layer == "v" and opt["v"]["go"]:
|
794
1031
|
if legend_which == "v":
|
795
|
-
plot_violin(
|
1032
|
+
plot_violin(
|
1033
|
+
data, opt["v"], xloc, ax, label=legend_hue, vertical=vertical
|
1034
|
+
)
|
796
1035
|
else:
|
797
|
-
plot_violin(data, opt["v"], xloc, ax, label=None)
|
1036
|
+
plot_violin(data, opt["v"], xloc, ax, vertical=vertical, label=None)
|
1037
|
+
elif layer == "r" and opt["r"]["go"]:
|
1038
|
+
kwargs_figsets = kwargs.get("figsets", None)
|
1039
|
+
if x and y:
|
1040
|
+
if kwargs_figsets:
|
1041
|
+
plot_ridgeplot(df, x, y, opt["r"], **kwargs_figsets)
|
1042
|
+
else:
|
1043
|
+
plot_ridgeplot(df, x, y, opt["r"])
|
798
1044
|
elif all([layer == "l", opt["l"]["go"], opt["s"]["go"]]):
|
799
1045
|
plot_lines(data, opt["l"], opt["s"], ax)
|
800
1046
|
|
801
|
-
if kw_figsets is not None:
|
1047
|
+
if kw_figsets is not None and not opt["r"]["go"]:
|
802
1048
|
figsets(ax=ax, **kw_figsets)
|
803
1049
|
show_legend = kwargs.get("show_legend", True)
|
804
|
-
if show_legend:
|
1050
|
+
if show_legend and not opt["r"]["go"]:
|
805
1051
|
ax.legend()
|
806
1052
|
# ! add asterisks in the plot
|
807
1053
|
if stats_param:
|
808
1054
|
if len(xticklabels) >= 1:
|
809
1055
|
if hue is None:
|
810
1056
|
add_asterisks(
|
811
|
-
ax,
|
1057
|
+
ax,
|
1058
|
+
res,
|
1059
|
+
xticks_x_loc,
|
1060
|
+
xticklabels,
|
1061
|
+
y_loc=np.max(data),
|
1062
|
+
report_go=report,
|
812
1063
|
)
|
813
1064
|
else: # hue is not None
|
814
1065
|
ihue = 1
|
@@ -840,6 +1091,7 @@ def catplot(data, *args, **kwargs):
|
|
840
1091
|
xticks[xloc_curr : xloc_curr + hue_len],
|
841
1092
|
legend_hue,
|
842
1093
|
y_loc=np.max(data),
|
1094
|
+
report_go=report,
|
843
1095
|
)
|
844
1096
|
ihue += 1
|
845
1097
|
else: # 240814: still has some bugs
|
@@ -850,7 +1102,12 @@ def catplot(data, *args, **kwargs):
|
|
850
1102
|
tab_res[f"{xticklabels[0]}(mean±sem)"] = [str_mean_sem(x1)]
|
851
1103
|
tab_res[f"{xticklabels[1]}(mean±sem)"] = [str_mean_sem(x2)]
|
852
1104
|
add_asterisks(
|
853
|
-
ax,
|
1105
|
+
ax,
|
1106
|
+
res[1],
|
1107
|
+
xticks_x_loc,
|
1108
|
+
xticklabels,
|
1109
|
+
y_loc=np.max([x1, x2]),
|
1110
|
+
report_go=report,
|
854
1111
|
)
|
855
1112
|
elif isinstance(res, pd.DataFrame):
|
856
1113
|
display(res)
|
@@ -858,7 +1115,12 @@ def catplot(data, *args, **kwargs):
|
|
858
1115
|
x1 = df.loc[df[x] == xticklabels[0], y].tolist()
|
859
1116
|
x2 = df.loc[df[x] == xticklabels[1], y].tolist()
|
860
1117
|
add_asterisks(
|
861
|
-
ax,
|
1118
|
+
ax,
|
1119
|
+
res,
|
1120
|
+
xticks_x_loc,
|
1121
|
+
xticklabels,
|
1122
|
+
y_loc=np.max([x1, x2]),
|
1123
|
+
report_go=report,
|
862
1124
|
)
|
863
1125
|
|
864
1126
|
style_export = kwargs.get("style_export", None)
|
@@ -1294,6 +1556,8 @@ def get_color(
|
|
1294
1556
|
by: str = "start",
|
1295
1557
|
alpha: float = 1.0,
|
1296
1558
|
output: str = "hue",
|
1559
|
+
*args,
|
1560
|
+
**kwargs,
|
1297
1561
|
):
|
1298
1562
|
def cmap2hex(cmap_name):
|
1299
1563
|
cmap_ = matplotlib.pyplot.get_cmap(cmap_name)
|
@@ -1343,6 +1607,8 @@ def get_color(
|
|
1343
1607
|
else:
|
1344
1608
|
return "#{:02X}{:02X}{:02X}".format(r, g, b)
|
1345
1609
|
|
1610
|
+
if cmap == "gray":
|
1611
|
+
cmap = "grey"
|
1346
1612
|
# Determine color list based on cmap parameter
|
1347
1613
|
if "aut" in cmap:
|
1348
1614
|
colorlist = [
|
@@ -1354,7 +1620,38 @@ def get_color(
|
|
1354
1620
|
"#FF9500",
|
1355
1621
|
"#D57DBE",
|
1356
1622
|
]
|
1623
|
+
by = "start"
|
1624
|
+
elif any(["cub" in cmap.lower(), "sns" in cmap.lower()]):
|
1625
|
+
if kwargs:
|
1626
|
+
colorlist = sns.cubehelix_palette(n, **kwargs)
|
1627
|
+
else:
|
1628
|
+
colorlist = sns.cubehelix_palette(
|
1629
|
+
n, start=0.5, rot=-0.75, light=0.85, dark=0.15, as_cmap=False
|
1630
|
+
)
|
1631
|
+
colorlist = [matplotlib.colors.rgb2hex(color) for color in colorlist]
|
1632
|
+
elif any(["hls" in cmap.lower(), "hsl" in cmap.lower()]):
|
1633
|
+
if kwargs:
|
1634
|
+
colorlist = sns.hls_palette(n, **kwargs)
|
1635
|
+
else:
|
1636
|
+
colorlist = sns.hls_palette(n)
|
1637
|
+
colorlist = [matplotlib.colors.rgb2hex(color) for color in colorlist]
|
1638
|
+
elif any(["col" in cmap.lower(), "pal" in cmap.lower()]):
|
1639
|
+
palette, desat, as_cmap = None, None, False
|
1640
|
+
if kwargs:
|
1641
|
+
for k, v in kwargs.items():
|
1642
|
+
if "p" in k:
|
1643
|
+
palette = v
|
1644
|
+
elif "d" in k:
|
1645
|
+
desat = v
|
1646
|
+
elif "a" in k:
|
1647
|
+
as_cmap = v
|
1648
|
+
colorlist = sns.color_palette(
|
1649
|
+
palette=palette, n_colors=n, desat=desat, as_cmap=as_cmap
|
1650
|
+
)
|
1651
|
+
colorlist = [matplotlib.colors.rgb2hex(color) for color in colorlist]
|
1357
1652
|
else:
|
1653
|
+
if by == "start":
|
1654
|
+
by = "linspace"
|
1358
1655
|
colorlist = cmap2hex(cmap)
|
1359
1656
|
|
1360
1657
|
# Determine method for generating color list
|
@@ -1721,6 +2018,7 @@ def add_asterisks(ax, res, xticks_x_loc, xticklabels, **kwargs_funcstars):
|
|
1721
2018
|
pval_groups = res["res_tab"]["p-unc"].tolist()[0]
|
1722
2019
|
else:
|
1723
2020
|
pval_groups = res["res_tab"]["PR(>F)"].tolist()[0]
|
2021
|
+
report_go = kwargs_funcstars.get("report_go", False)
|
1724
2022
|
if pval_groups <= 0.05:
|
1725
2023
|
A_list = res["res_posthoc"]["A"].tolist()
|
1726
2024
|
B_list = res["res_posthoc"]["B"].tolist()
|
@@ -1743,6 +2041,32 @@ def add_asterisks(ax, res, xticks_x_loc, xticklabels, **kwargs_funcstars):
|
|
1743
2041
|
)
|
1744
2042
|
if P <= 0.05:
|
1745
2043
|
yscal_ -= 0.075
|
2044
|
+
if report_go:
|
2045
|
+
try:
|
2046
|
+
if isinstance(res["APA"], list):
|
2047
|
+
APA_str = res["APA"][0]
|
2048
|
+
else:
|
2049
|
+
APA_str = res["APA"]
|
2050
|
+
except:
|
2051
|
+
pass
|
2052
|
+
|
2053
|
+
FuncStars(
|
2054
|
+
ax=ax,
|
2055
|
+
x1=(
|
2056
|
+
xticks_x_loc[0] - (xticks_x_loc[-1] - xticks_x_loc[0]) / 3
|
2057
|
+
if xticks_x_loc[0] > 1
|
2058
|
+
else xticks_x_loc[0]
|
2059
|
+
),
|
2060
|
+
x2=(
|
2061
|
+
xticks_x_loc[0] - (xticks_x_loc[-1] - xticks_x_loc[0]) / 3
|
2062
|
+
if xticks_x_loc[0] > 1
|
2063
|
+
else xticks_x_loc[0]
|
2064
|
+
),
|
2065
|
+
pval=None,
|
2066
|
+
report_scale=np.random.uniform(0.7, 0.99),
|
2067
|
+
report=APA_str,
|
2068
|
+
fontsize_note=8,
|
2069
|
+
)
|
1746
2070
|
else:
|
1747
2071
|
if isinstance(res, tuple):
|
1748
2072
|
res = res[1]
|
@@ -1763,3 +2087,38 @@ def add_asterisks(ax, res, xticks_x_loc, xticklabels, **kwargs_funcstars):
|
|
1763
2087
|
pval=pval_groups,
|
1764
2088
|
**kwargs_funcstars,
|
1765
2089
|
)
|
2090
|
+
|
2091
|
+
|
2092
|
+
def style_examples(
|
2093
|
+
dir_save="/Users/macjianfeng/Dropbox/github/python/py2ls/.venv/lib/python3.12/site-packages/py2ls/data/styles/example",
|
2094
|
+
):
|
2095
|
+
f = listdir(
|
2096
|
+
"/Users/macjianfeng/Dropbox/github/python/py2ls/.venv/lib/python3.12/site-packages/py2ls/data/styles/",
|
2097
|
+
kind=".json",
|
2098
|
+
)
|
2099
|
+
display(f.sample(2))
|
2100
|
+
# def style_example(dir_save,)
|
2101
|
+
# Sample data creation
|
2102
|
+
np.random.seed(42)
|
2103
|
+
categories = ["A", "B", "C", "D", "E"]
|
2104
|
+
data = pd.DataFrame(
|
2105
|
+
{
|
2106
|
+
"value": np.concatenate(
|
2107
|
+
[np.random.normal(loc, 0.4, 100) for loc in range(5)]
|
2108
|
+
),
|
2109
|
+
"category": np.repeat(categories, 100),
|
2110
|
+
}
|
2111
|
+
)
|
2112
|
+
for i in range(f.num[0]):
|
2113
|
+
plt.figure()
|
2114
|
+
_, _ = catplot(
|
2115
|
+
data=data,
|
2116
|
+
x="category",
|
2117
|
+
y="value",
|
2118
|
+
style=i,
|
2119
|
+
figsets=dict(title=f"style{i+1} or style idx={i}"),
|
2120
|
+
)
|
2121
|
+
figsave(
|
2122
|
+
dir_save,
|
2123
|
+
f"{f.name[i]}.pdf",
|
2124
|
+
)
|