gwaslab 3.5.7__py3-none-any.whl → 3.5.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.

Potentially problematic release.


This version of gwaslab might be problematic. Click here for more details.

Files changed (63) hide show
  1. gwaslab/__init__.py +2 -0
  2. gwaslab/bd_common_data.py +1 -0
  3. gwaslab/bd_get_hapmap3.py +0 -1
  4. gwaslab/data/formatbook.json +78 -0
  5. gwaslab/g_Sumstats.py +98 -24
  6. gwaslab/g_SumstatsMulti.py +287 -0
  7. gwaslab/g_SumstatsPair.py +101 -16
  8. gwaslab/g_Sumstats_polars.py +245 -0
  9. gwaslab/g_headers.py +12 -3
  10. gwaslab/g_meta.py +123 -47
  11. gwaslab/g_meta_update.py +48 -0
  12. gwaslab/g_vchange_status_polars.py +44 -0
  13. gwaslab/g_version.py +2 -2
  14. gwaslab/hm_casting.py +169 -110
  15. gwaslab/hm_casting_polars.py +202 -0
  16. gwaslab/hm_harmonize_sumstats.py +19 -8
  17. gwaslab/io_load_ld.py +529 -0
  18. gwaslab/io_preformat_input.py +11 -0
  19. gwaslab/io_preformat_input_polars.py +632 -0
  20. gwaslab/io_process_args.py +25 -1
  21. gwaslab/io_read_ldsc.py +34 -3
  22. gwaslab/io_read_pipcs.py +62 -6
  23. gwaslab/prscs_gigrnd.py +122 -0
  24. gwaslab/prscs_mcmc_gtb.py +136 -0
  25. gwaslab/prscs_parse_genet.py +98 -0
  26. gwaslab/qc_build.py +53 -0
  27. gwaslab/qc_check_datatype.py +10 -8
  28. gwaslab/qc_check_datatype_polars.py +128 -0
  29. gwaslab/qc_fix_sumstats.py +25 -23
  30. gwaslab/qc_fix_sumstats_polars.py +193 -0
  31. gwaslab/util_ex_calculate_ldmatrix.py +49 -19
  32. gwaslab/util_ex_gwascatalog.py +71 -28
  33. gwaslab/util_ex_ldsc.py +67 -21
  34. gwaslab/util_ex_match_ldmatrix.py +396 -0
  35. gwaslab/util_ex_run_2samplemr.py +0 -2
  36. gwaslab/util_ex_run_ccgwas.py +155 -0
  37. gwaslab/util_ex_run_coloc.py +1 -1
  38. gwaslab/util_ex_run_hyprcoloc.py +117 -0
  39. gwaslab/util_ex_run_mesusie.py +155 -0
  40. gwaslab/util_ex_run_mtag.py +92 -0
  41. gwaslab/util_ex_run_prscs.py +85 -0
  42. gwaslab/util_ex_run_susie.py +40 -9
  43. gwaslab/util_in_estimate_ess.py +18 -0
  44. gwaslab/util_in_fill_data.py +20 -1
  45. gwaslab/util_in_filter_value.py +10 -5
  46. gwaslab/util_in_get_sig.py +71 -13
  47. gwaslab/util_in_meta.py +168 -4
  48. gwaslab/util_in_meta_polars.py +174 -0
  49. gwaslab/viz_plot_compare_effect.py +87 -23
  50. gwaslab/viz_plot_credible_sets.py +55 -11
  51. gwaslab/viz_plot_effect.py +22 -12
  52. gwaslab/viz_plot_miamiplot2.py +3 -2
  53. gwaslab/viz_plot_mqqplot.py +84 -81
  54. gwaslab/viz_plot_qqplot.py +6 -6
  55. gwaslab/viz_plot_regional2.py +2 -1
  56. gwaslab/viz_plot_stackedregional.py +4 -1
  57. {gwaslab-3.5.7.dist-info → gwaslab-3.5.8.dist-info}/METADATA +8 -6
  58. gwaslab-3.5.8.dist-info/RECORD +117 -0
  59. {gwaslab-3.5.7.dist-info → gwaslab-3.5.8.dist-info}/WHEEL +1 -1
  60. gwaslab-3.5.7.dist-info/RECORD +0 -96
  61. {gwaslab-3.5.7.dist-info → gwaslab-3.5.8.dist-info/licenses}/LICENSE +0 -0
  62. {gwaslab-3.5.7.dist-info → gwaslab-3.5.8.dist-info/licenses}/LICENSE_before_v3.4.39 +0 -0
  63. {gwaslab-3.5.7.dist-info → gwaslab-3.5.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,174 @@
1
+
2
+ import pandas as pd
3
+ import numpy as np
4
+ from scipy.stats.distributions import chi2
5
+ from scipy.stats import norm
6
+ from gwaslab.g_Log import Log
7
+ from gwaslab.io_to_pickle import load_data_from_pickle
8
+ from gwaslab.g_Sumstats import Sumstats
9
+ import gc
10
+ import polars as pl
11
+ import statsmodels.api as sm
12
+ ########################################################################################################################################################################################################################################################################################################################################################
13
+ ########################################################################################################################################################################################################################################################################################################################################################
14
+ ########################################################################################################################################################################################################################################################################################################################################################
15
+ ################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
16
+ ########################################################################################################################################################################################################################################################################################################################################################
17
+ ########################################################################################################################################################################################################################################################################################################################################################
18
+
19
+ def meta_analyze_polars(sumstats_multi,
20
+ random_effects=False,
21
+ nstudy=1,
22
+ log=Log()):
23
+ log.write("Start to perform meta-analysis...")
24
+ ###########################################################################
25
+ log.write(" -Initiating result DataFrame...")
26
+
27
+ sumstats_multi = sumstats_multi.with_row_index()
28
+
29
+ sumstats_multi = sumstats_multi.with_columns(
30
+ N=pl.lit(0),
31
+ _BETAW_SUM = pl.lit(0.0),
32
+ _BETA2W_SUM =pl.lit(0.0),
33
+ _W_SUM =pl.lit(0.0),
34
+ _W2_SUM=pl.lit(0.0),
35
+ _EA_N=pl.lit(0.0),
36
+ _NEA_N=pl.lit(0.0),
37
+ DIRECTION =pl.lit(""),
38
+ BETA=pl.lit(0.0),
39
+ SE=pl.lit(0.0),
40
+ DOF =pl.lit(-1),
41
+ _R2=pl.lit(0.0),
42
+ )
43
+
44
+ for i in range(nstudy):
45
+ n="N_{}".format(i+1)
46
+ beta="BETA_{}".format(i+1)
47
+ se="SE_{}".format(i+1)
48
+ eaf="EAF_{}".format(i+1)
49
+ sumstats_multi = sumstats_multi.with_columns(
50
+ pl.when(pl.col(beta).is_null())
51
+ .then(pl.col("N"))
52
+ .otherwise(pl.col("N") + pl.col(n))
53
+ .alias("N")
54
+ ).with_columns(
55
+ pl.when(pl.col(beta).is_null())
56
+ .then(pl.col("DOF") )
57
+ .otherwise(pl.col("DOF") + 1 )
58
+ .alias("DOF")
59
+ ).with_columns(
60
+ pl.when(pl.col(beta).is_null())
61
+ .then(pl.col("_BETA2W_SUM"))
62
+ .otherwise(pl.col("_BETA2W_SUM") + pl.col(beta)**2 *(1/(pl.col(se)**2)))
63
+ .alias("_BETA2W_SUM")
64
+ ).with_columns(
65
+ pl.when(pl.col(beta).is_null())
66
+ .then( pl.col("_BETAW_SUM") )
67
+ .otherwise(pl.col("_BETAW_SUM") + pl.col(beta)*(1/(pl.col(se)**2)) )
68
+ .alias("_BETAW_SUM")
69
+ ).with_columns(
70
+ pl.when(pl.col(beta).is_null())
71
+ .then( pl.col("_W_SUM") )
72
+ .otherwise(pl.col("_W_SUM") + 1/(pl.col(se)**2))
73
+ .alias("_W_SUM")
74
+ ).with_columns(
75
+ pl.when(pl.col(beta).is_null())
76
+ .then( pl.col("_W2_SUM") )
77
+ .otherwise(pl.col("_W2_SUM") + pl.col("_W_SUM")**2)
78
+ .alias("_W2_SUM")
79
+ ).with_columns(
80
+ pl.when(pl.col(beta).is_null())
81
+ .then( pl.col("_EA_N") )
82
+ .otherwise(pl.col("_EA_N") + pl.col(n)*pl.col(eaf))
83
+ .alias("_EA_N")
84
+ ).with_columns(
85
+ pl.when(pl.col(beta).is_null())
86
+ .then( pl.col("_NEA_N") )
87
+ .otherwise(pl.col("_EA_N") + pl.col(n)*(1-pl.col(eaf)))
88
+ .alias("_NEA_N")
89
+ ).with_columns(
90
+ pl.when(pl.col(beta) <0 )
91
+ .then( pl.col("DIRECTION") +"-" )
92
+ .otherwise( pl.col("DIRECTION") )
93
+ .alias("DIRECTION")
94
+ ).with_columns(
95
+ pl.when(pl.col(beta) >0 )
96
+ .then( pl.col("DIRECTION") +"-" )
97
+ .otherwise( pl.col("DIRECTION") )
98
+ .alias("DIRECTION")
99
+ ).with_columns(
100
+ pl.when(pl.col(beta) ==0 )
101
+ .then( pl.col("DIRECTION") +"0" )
102
+ .otherwise( pl.col("DIRECTION") )
103
+ .alias("DIRECTION")
104
+ ).with_columns(
105
+ pl.when(pl.col(beta).is_null() )
106
+ .then( pl.col("DIRECTION") +"?" )
107
+ .otherwise( pl.col("DIRECTION") )
108
+ .alias("DIRECTION")
109
+ )
110
+
111
+ sumstats_multi = sumstats_multi.with_columns(
112
+ BETA = pl.col("_BETAW_SUM") / pl.col("_W_SUM"),
113
+ EAF = pl.col("_EA_N") / (pl.col("_EA_N") + pl.col("_NEA_N")),
114
+ SE = (1/pl.col("_W_SUM")).sqrt(),
115
+ Q = pl.col("_BETA2W_SUM") - (pl.col("_BETAW_SUM")**2/pl.col("_W_SUM"))
116
+ )
117
+
118
+ sumstats_multi = sumstats_multi.with_columns(
119
+ Z = pl.col("BETA") / pl.col("SE")
120
+ ).with_columns(
121
+ P = pl.col("Z").map_batches(lambda x: pl.Series(2*norm.sf(x.abs())))
122
+ )
123
+
124
+ if random_effects==True:
125
+ sumstats_multi = sumstats_multi.with_columns(
126
+ _R2 = (pl.col("Q") - pl.col("DOF")) / (pl.col("_W_SUM") - (pl.col("_W2_SUM")/pl.col("_W_SUM")))
127
+ ).with_columns(
128
+ pl.when(pl.col("_R2")<0 )
129
+ .then( pl.lit(0) )
130
+ .otherwise( pl.col("_R2") )
131
+ .alias("_R2")
132
+ )
133
+
134
+ sumstats_multi = sumstats_multi.with_columns(
135
+ _BETAW_SUM_R = pl.lit(0.0),
136
+ _W_SUM_R =pl.lit(0.0),
137
+ BETA_RANDOM =pl.col("BETA"),
138
+ SE_RANDOM = pl.col("SE")
139
+ )
140
+
141
+
142
+
143
+ for i in range(nstudy):
144
+ n="N_{}".format(i+1)
145
+ beta="BETA_{}".format(i+1)
146
+ se="SE_{}".format(i+1)
147
+ eaf="EAF_{}".format(i+1)
148
+
149
+ sumstats_multi = sumstats_multi.with_columns(
150
+ pl.when( pl.col(beta).is_null() )
151
+ .then(pl.col("_BETAW_SUM_R"))
152
+ .otherwise(pl.col("_BETAW_SUM_R") + pl.col(beta)*(1/ (pl.col(se)**2 + pl.col("_R2")) ))
153
+ .alias("_BETAW_SUM_R")
154
+ ).with_columns(
155
+ pl.when( pl.col(beta).is_null() )
156
+ .then(pl.col("_W_SUM_R") )
157
+ .otherwise( pl.col("_W_SUM_R") + 1/(pl.col(se)**2 + pl.col("_R2") ) )
158
+ .alias("_W_SUM_R")
159
+ )
160
+
161
+ sumstats_multi = sumstats_multi.with_columns(
162
+ BETA_RANDOM = (pl.col("_BETAW_SUM_R") / pl.col("_W_SUM_R"))
163
+ ).with_columns(
164
+ SE_RANDOM = ( (1/pl.col("_W_SUM_R")).sqrt() )
165
+ ).with_columns(
166
+ Z_RANDOM = pl.col("BETA_RANDOM") / pl.col("SE_RANDOM")
167
+ ).with_columns(
168
+ P_RANDOM = pl.col("Z_RANDOM").map_batches(lambda x: pl.Series(2*norm.sf(x.abs()))
169
+ )
170
+ )
171
+
172
+ sumstats_multi = sumstats_multi.select(pl.all().exclude("^_.*$|\w+_[\d]+$") )
173
+ log.write("Finished performing meta-analysis.")
174
+ return sumstats_multi
@@ -51,11 +51,12 @@ def compare_effect(path1,
51
51
  reg_box=None,
52
52
  is_reg=True,
53
53
  fdr=False,
54
+ reg_text="full",
54
55
  allele_match=False,
55
56
  r_se=False,
56
57
  is_45_helper_line=True,
57
58
  legend_mode="full",
58
- legend_title=r'$ P < 5 x 10^{-8}$ in:',
59
+ legend_title=r'$\mathregular{ P < 5 x 10^{-8}}$ in:',
59
60
  legend_title2=r'Heterogeneity test:',
60
61
  legend_pos='upper left',
61
62
  scatterargs=None,
@@ -85,12 +86,12 @@ def compare_effect(path1,
85
86
  scaled1 = True
86
87
  scaled2 = True
87
88
 
88
- if legend_title== r'$ P < 5 x 10^{-8}$ in:' and sig_level!=5e-8:
89
+ if legend_title== r'$\mathregular{ P < 5 x 10^{-8}}$ in:' and sig_level!=5e-8:
89
90
 
90
91
  exponent = math.floor(math.log10(sig_level))
91
92
  mantissa = sig_level / 10**exponent
92
93
 
93
- legend_title = '$ P < {} x 10^{{{}}}$ in:'.format(mantissa, exponent)
94
+ legend_title = '$\mathregular{ P < {} x 10^{{{}}}}$ in:'.format(mantissa, exponent)
94
95
 
95
96
  if is_q_mc=="fdr" or is_q_mc=="bon":
96
97
  is_q = True
@@ -100,6 +101,8 @@ def compare_effect(path1,
100
101
  if save_args is None:
101
102
  save_args = {"dpi":300,"facecolor":"white"}
102
103
  if reg_box is None:
104
+ reg_box= None
105
+ elif reg_box==True:
103
106
  reg_box = dict(boxstyle='round', facecolor='white', alpha=1,edgecolor="grey")
104
107
  if sep is None:
105
108
  sep = ["\t","\t"]
@@ -116,7 +119,7 @@ def compare_effect(path1,
116
119
  if helper_line_args is None:
117
120
  helper_line_args={"color":'black', "linestyle":'-',"lw":1}
118
121
  if plt_args is None:
119
- plt_args={"figsize":(8,8),"dpi":300}
122
+ plt_args={"figsize":(7,7),"dpi":300}
120
123
  if scatterargs is None:
121
124
  scatterargs={"s":20}
122
125
  if label is None:
@@ -487,9 +490,23 @@ def compare_effect(path1,
487
490
  ax.spines[spine].set_visible(False)
488
491
 
489
492
  ###regression line##############################################################################################################################
490
- ax = confire_regression_line(is_reg,reg_box, sig_list_merged, ax, mode,xl,yl,xh,yh, null_beta, r_se,
491
- is_45_helper_line,helper_line_args, font_kwargs,
492
- log, verbose)
493
+ ax = configure_regression_line(is_reg=is_reg,
494
+ reg_text=reg_text,
495
+ reg_box=reg_box,
496
+ sig_list_merged=sig_list_merged,
497
+ ax=ax,
498
+ mode=mode,
499
+ xl=xl,
500
+ yl=yl,
501
+ xh=xh,
502
+ yh=yh,
503
+ null_beta=null_beta,
504
+ r_se=r_se,
505
+ is_45_helper_line=is_45_helper_line,
506
+ helper_line_args=helper_line_args,
507
+ font_kwargs=font_kwargs,
508
+ log=log,
509
+ verbose=verbose)
493
510
 
494
511
 
495
512
  ax.set_xlabel(xylabel_prefix+label[0],**font_kwargs)
@@ -1128,9 +1145,23 @@ def scatter_annotation(ax, sig_list_merged,anno, anno_het, is_q, mode,
1128
1145
  return ax
1129
1146
 
1130
1147
 
1131
- def confire_regression_line(is_reg, reg_box, sig_list_merged, ax, mode,xl,yl,xh,yh, null_beta, r_se,
1132
- is_45_helper_line,helper_line_args, font_kwargs,
1133
- log, verbose):
1148
+ def configure_regression_line(is_reg,
1149
+ reg_box,
1150
+ reg_text,
1151
+ sig_list_merged,
1152
+ ax,
1153
+ mode,
1154
+ xl,
1155
+ yl,
1156
+ xh,
1157
+ yh,
1158
+ null_beta,
1159
+ r_se,
1160
+ is_45_helper_line,
1161
+ helper_line_args,
1162
+ font_kwargs,
1163
+ log,
1164
+ verbose):
1134
1165
  if len(sig_list_merged)<3: is_reg=False
1135
1166
  if is_reg is True:
1136
1167
  if mode=="beta" or mode=="BETA" or mode=="Beta":
@@ -1149,8 +1180,8 @@ def confire_regression_line(is_reg, reg_box, sig_list_merged, ax, mode,xl,yl,xh
1149
1180
 
1150
1181
  #### calculate p values based on selected value , default = 0
1151
1182
  log.write(" -Calculating p values based on given null slope :",null_beta, verbose=verbose)
1152
- t_score = (reg[0]-null_beta) / reg[4]
1153
- degree = len(sig_list_merged.dropna())-2
1183
+ #t_score = (reg[0]-null_beta) / reg[4]
1184
+ #degree = len(sig_list_merged.dropna())-2
1154
1185
  p = reg[3]
1155
1186
  #ss.t.sf(abs(t_score), df=degree)*2
1156
1187
  log.write(" -Beta = ", reg[0], verbose=verbose)
@@ -1174,9 +1205,25 @@ def confire_regression_line(is_reg, reg_box, sig_list_merged, ax, mode,xl,yl,xh
1174
1205
  except:
1175
1206
  p12="0"
1176
1207
  pe="0"
1177
- p_text="$p = " + p12 + " \\times 10^{"+pe+"}$"
1208
+ if p > 1e-300:
1209
+ p_text="$\mathregular{p = " + p12 + " \\times 10^{"+pe+"}}$"
1210
+ else:
1211
+ p_text="$\mathregular{p < 1 \\times 10^{-300}}$"
1178
1212
  p_latex= f'{p_text}'
1179
- ax.text(0.98,0.02,"$y =$ "+"{:.2f}".format(reg[1]) +" $+$ "+ "{:.2f}".format(reg[0])+" $x$, "+ p_latex + ", $r =$" +"{:.2f}".format(reg[2])+r_se_jackknife_string, va="bottom",ha="right",transform=ax.transAxes, bbox=reg_box, **font_kwargs)
1213
+
1214
+ if reg_text=="full":
1215
+ reg_string = "y = "+"{:.2f}".format(reg[1]) +" + "+ "{:.2f}".format(reg[0])+" x, "+ p_latex + ", r = " +"{:.2f}".format(reg[2])+r_se_jackknife_string
1216
+ ax.text(0.98,0.02,
1217
+ reg_string,
1218
+ va="bottom",ha="right",transform=ax.transAxes, bbox=reg_box, **font_kwargs)
1219
+ elif reg_text=="r":
1220
+ reg_string ="r = " +"{:.2f}".format(reg[2])+r_se_jackknife_string
1221
+ ax.text(0.98,0.02,
1222
+ reg_string, va="bottom",ha="right",transform=ax.transAxes, bbox=reg_box, **font_kwargs)
1223
+ elif reg_text=="r2":
1224
+ reg_string = "$\mathregular{r^{2}} = " +"{:.2f}".format(reg[2]**2)
1225
+ ax.text(0.98,0.02,
1226
+ reg_string, va="bottom",ha="right",transform=ax.transAxes, bbox=reg_box, **font_kwargs)
1180
1227
  else:
1181
1228
  #if regression coeeficient <0 : auxiliary line slope = -1
1182
1229
  if is_45_helper_line is True:
@@ -1191,9 +1238,25 @@ def confire_regression_line(is_reg, reg_box, sig_list_merged, ax, mode,xl,yl,xh
1191
1238
  except:
1192
1239
  p12="0"
1193
1240
  pe="0"
1194
- p_text="$p = " + p12 + " \\times 10^{"+pe+"}$"
1241
+
1242
+ if p > 1e-300:
1243
+ p_text="$\mathregular{p = " + p12 + " \\times 10^{"+pe+"}}$"
1244
+ else:
1245
+ p_text="$\mathregular{p < 1 \\times 10^{-300}}$"
1195
1246
  p_latex= f'{p_text}'
1196
- ax.text(0.98,0.02,"$y =$ "+"{:.2f}".format(reg[1]) +" $-$ "+ "{:.2f}".format(abs(reg[0]))+" $x$, "+ p_latex + ", $r =$" +"{:.2f}".format(reg[2])+r_se_jackknife_string, va="bottom",ha="right",transform=ax.transAxes,bbox=reg_box,**font_kwargs)
1247
+
1248
+ if reg_text=="full":
1249
+ ax.text(0.98,0.02,
1250
+ "y = "+"{:.2f}".format(reg[1]) +" - "+ "{:.2f}".format(abs(reg[0]))+" x, "+ p_latex + ", r = " +"{:.2f}".format(reg[2])+r_se_jackknife_string,
1251
+ va="bottom",ha="right",transform=ax.transAxes,bbox=reg_box,**font_kwargs)
1252
+ elif reg_text=="r":
1253
+ ax.text(0.98,0.02,
1254
+ "r = " +"{:.2f}".format(reg[2])+r_se_jackknife_string,
1255
+ va="bottom",ha="right",transform=ax.transAxes, bbox=reg_box, **font_kwargs)
1256
+ elif reg_text=="r2":
1257
+ ax.text(0.98,0.02,
1258
+ "$\mathregular{r^{2}} = " +"{:.2f}".format(reg[2]**2),
1259
+ va="bottom",ha="right",transform=ax.transAxes, bbox=reg_box, **font_kwargs)
1197
1260
 
1198
1261
  if mode=="beta" or mode=="BETA" or mode=="Beta":
1199
1262
  middle = sig_list_merged["EFFECT_1"].mean()
@@ -1216,7 +1279,8 @@ def configure_legend(fig, ax, legend_mode, is_q, is_q_mc, legend_elements, legen
1216
1279
  "handletextpad":0.8,
1217
1280
  "edgecolor":"grey",
1218
1281
  "borderpad":0.3,
1219
- "alignment":"left"
1282
+ "alignment":"left",
1283
+ "frameon":False
1220
1284
  }
1221
1285
 
1222
1286
  if legend_args is not None:
@@ -1227,14 +1291,14 @@ def configure_legend(fig, ax, legend_mode, is_q, is_q_mc, legend_elements, legen
1227
1291
  title_proxy = Rectangle((0,0), 0, 0, color='w',label=legend_title)
1228
1292
  title_proxy2 = Rectangle((0,0), 0, 0, color='w',label=legend_title2)
1229
1293
  if is_q_mc=="fdr":
1230
- het_label_sig = r"$FDR_{het} < $" + "${}$".format(q_level)
1231
- het_label_sig2 = r"$FDR_{het} > $" + "${}$".format(q_level)
1294
+ het_label_sig = r"$\mathregular{FDR_{het} < }$" + "{}".format(q_level)
1295
+ het_label_sig2 = r"$\mathregular{FDR_{het} > }$" + "{}".format(q_level)
1232
1296
  elif is_q_mc=="bon":
1233
- het_label_sig = r"$P_{het,bon} < $" + "${}$".format(q_level)
1234
- het_label_sig2 = r"$P_{het,bon} > $" + "${}$".format(q_level)
1297
+ het_label_sig = r"$\mathregular{P_{het,bon} < }$" + "{}".format(q_level)
1298
+ het_label_sig2 = r"$\mathregular{P_{het,bon} > }$" + "{}".format(q_level)
1235
1299
  else:
1236
- het_label_sig = r"$P_{het} < $" + "${}$".format(q_level)
1237
- het_label_sig2 = r"$P_{het} > $" + "${}$".format(q_level)
1300
+ het_label_sig = r"$\mathregular{P_{het} < }$" + "{}".format(q_level)
1301
+ het_label_sig2 = r"$\mathregular{P_{het} > }$" + "{}".format(q_level)
1238
1302
  het_sig = Rectangle((0,0), 0, 0, facecolor='#cccccc',edgecolor="black", linewidth=1, label=het_label_sig)
1239
1303
  het_nonsig = Rectangle((0,0), 0, 0, facecolor='#cccccc',edgecolor="white",linewidth=1, label=het_label_sig2)
1240
1304
 
@@ -9,39 +9,56 @@ from gwaslab.viz_plot_mqqplot import _process_xlabel
9
9
  from gwaslab.bd_common_data import get_number_to_chr
10
10
  from gwaslab.util_in_filter_value import _filter_region
11
11
  from gwaslab.io_process_args import _extract_kwargs
12
+ import copy
12
13
 
13
- def _plot_cs(pipcs,
14
- region,
14
+ def _plot_cs(pipcs_raw,
15
+ region=None,
16
+ locus=None,
15
17
  figax=None,
16
18
  _posdiccul=None,
17
19
  xtick_chr_dict=None,
18
20
  pip="PIP",
19
21
  onlycs=False,
22
+ pos="POS",
23
+ chrom="CHR",
20
24
  cs="CREDIBLE_SET_INDEX",
25
+ cs_category = "CS_CATEGORY",
21
26
  marker_size=(45,85),
22
27
  fontsize = 12,
23
28
  font_family = "Arial",
24
- legend_title="Credible sets",
29
+ legend_title="Credible set",
30
+ fig_args=None,
25
31
  log=Log(),
26
32
  verbose=True,
27
33
  **kwargs):
28
34
  '''
29
35
  pipcs : a DataFrame of finemapping results
30
36
  '''
37
+ pipcs = pipcs_raw.copy()
31
38
  ## parameters #############################
32
39
  if xtick_chr_dict is None:
33
40
  xtick_chr_dict = get_number_to_chr()
34
-
41
+ if fig_args is None:
42
+ fig_args={"figsize":(15,5),"dpi":400}
35
43
  scatter_kwargs = _extract_kwargs("scatter", dict(), locals())
36
44
 
37
45
  region_marker_shapes = ['o', '^','s','D','*','P','X','h','8']
38
46
  region_ld_colors_m = ["grey","#E51819","green","#F07818","#AD5691","yellow","purple"]
39
47
 
40
-
41
- ## filter data #############################
42
- pipcs = _filter_region(pipcs, region)
48
+ if region is not None:
49
+ ## filter data #############################
50
+ pipcs = _filter_region(pipcs, region)
51
+ log.write(" -Loading PIP and CS for variants in the region :{}".format(region))
52
+
53
+ if locus is not None:
54
+ pipcs = pipcs.loc[pipcs["LOCUS"] == locus,:].copy()
55
+ log.write(" -Loading PIP and CS for variants in the locus :{}".format(region))
56
+ if region is None:
57
+ region = (pipcs[chrom].iloc[0],pipcs[pos].min(),pipcs[pos].max())
58
+ log.write(" -Extracted region:{}".format(region))
43
59
  if onlycs ==True:
44
60
  pipcs = pipcs.loc[pipcs[cs]>0,:]
61
+ log.write(" -Loading only variants in CS...")
45
62
 
46
63
  pipcs[cs] = pipcs[cs].astype("string")
47
64
 
@@ -50,7 +67,7 @@ def _plot_cs(pipcs,
50
67
  ax=figax[1]
51
68
  fig=figax[0]
52
69
  else:
53
- fig, ax = plt.subplots()
70
+ fig, ax = plt.subplots(**fig_args)
54
71
 
55
72
  # assign i
56
73
  pipcs,chrom_df=_quick_assign_i_with_rank(pipcs, chrpad=0.00,
@@ -58,12 +75,17 @@ def _plot_cs(pipcs,
58
75
  chrom="CHR",pos="POS",
59
76
  drop_chr_start=False,
60
77
  _posdiccul=_posdiccul)
78
+
61
79
  pipcs = pipcs.sort_values(by=cs,ascending=True)
62
80
 
63
81
  ## plot ##########################################
64
82
  scatter_kwargs["markers"]= {m:region_marker_shapes[i] for i,m in enumerate(pipcs[cs].unique())}
65
83
  palette = sns.color_palette(region_ld_colors_m,n_colors=pipcs[cs].nunique())
66
84
  edgecolor="none"
85
+
86
+ if cs_category in pipcs.columns:
87
+ cs_category_dic = pipcs.loc[~pipcs[cs_category].isna(), [cs, cs_category]].drop_duplicates().set_index(cs).to_dict()
88
+
67
89
 
68
90
  plot = sns.scatterplot(data=pipcs,
69
91
  x="i",
@@ -75,6 +97,17 @@ def _plot_cs(pipcs,
75
97
  s=marker_size[1],
76
98
  ax=ax,
77
99
  **scatter_kwargs)
100
+
101
+ region_step=21
102
+ region_ticks = list(map('{:.3f}'.format,np.linspace(region[1], region[2], num=region_step).astype("int")/1000000))
103
+
104
+ most_left_snp = pipcs["i"].idxmin()
105
+ # distance between leftmost variant position to region left bound
106
+ i_pos_offset = pipcs.loc[most_left_snp,"i"] - pipcs.loc[most_left_snp,pos]
107
+ ax.set_xticks(np.linspace(i_pos_offset+region[1], i_pos_offset+region[2], num=region_step))
108
+ ax.set_xticklabels(region_ticks,rotation=45)
109
+ xlabel = "Chromosome "+str(region[0])+" (MB)"
110
+ ax.set_xlabel(xlabel,fontsize=fontsize,family=font_family)
78
111
 
79
112
  # process legend
80
113
  handles, labels = ax.get_legend_handles_labels()
@@ -82,18 +115,29 @@ def _plot_cs(pipcs,
82
115
  new_handles = []
83
116
  ncol = len(labels)
84
117
 
118
+ ax.tick_params(axis='y',
119
+ labelsize=fontsize,
120
+ labelfontfamily=font_family)
121
+
85
122
  for i,label in enumerate(labels):
86
123
  if label in [str(j) for j in range(1,10)]:
87
- new_labels.append(labels[i])
124
+ if cs_category in pipcs.columns:
125
+ new_labels.append("#{} - {}".format(labels[i],cs_category_dic[cs_category][label]) )
126
+ else:
127
+ new_labels.append("#"+labels[i])
88
128
  new_handles.append(handles[i])
89
129
 
130
+
90
131
  ax.legend(labels =new_labels,
91
132
  handles=new_handles,
92
133
  loc="upper right",
93
134
  bbox_to_anchor=(0.995, 0.995),
94
135
  ncol=1,
95
- scatterpoints=2,
136
+ markerfirst=False,
137
+ scatterpoints=1,
96
138
  title=legend_title,
97
- frameon=True)
139
+ title_fontproperties={"size":fontsize,"family":font_family},
140
+ prop={"size":fontsize,"family":font_family},
141
+ frameon=False)
98
142
 
99
143
  return fig, log
@@ -86,6 +86,8 @@ def _plot_effect(to_plot,
86
86
  verbose=True,
87
87
  legend_mode=1,
88
88
  ncol=2,
89
+ fontsize=12,
90
+ font_family="Arial",
89
91
  size=None,
90
92
  hue=None,
91
93
  style=None,
@@ -188,26 +190,28 @@ def _plot_effect(to_plot,
188
190
  **err_kwargs)
189
191
 
190
192
  ax1.axvline(x=0,linestyle="dashed",c="grey")
191
- ax1.set_yticks(to_plot[y], labels = to_plot[y_name])
192
- ax1.set_ylabel(ylabel)
193
+ ax1.set_yticks(to_plot[y], labels = to_plot[y_name], fontsize=fontsize, family=font_family)
194
+ ax1.set_ylabel(ylabel, fontsize=fontsize, family=font_family)
193
195
 
194
196
  if title is not None:
195
- ax1.set_title(title)
197
+ ax1.set_title(title,fontsize=fontsize, family=font_family)
196
198
 
197
199
  if eaf_panel==True:
198
200
  ax2.barh(y=to_plot[y], width=to_plot[eaf], zorder=100, **eaf_args)
199
- ax2.set_xlabel(eaf)
201
+ ax2.set_xlabel(eaf, fontsize=fontsize, family=font_family)
200
202
 
201
203
  if snpvar_panel==True:
202
204
  ax3.barh(y=to_plot[y], width=to_plot[snpr2], zorder=100,**snpr2_args)
203
- ax3.set_xlabel(snpr2)
205
+ ax3.set_xlabel(snpr2, fontsize=fontsize, family=font_family)
204
206
 
205
207
  #try:
206
208
  if legend_mode==1:
207
209
  #if ncols==1:
208
210
  sns.move_legend(
209
211
  ax1, "upper left",
210
- bbox_to_anchor=(1, 1), title=None, frameon=False, bbox_transform = axes[-1].transAxes
212
+ bbox_to_anchor=(1, 1), title=None, frameon=False, bbox_transform = axes[-1].transAxes,
213
+ title_fontproperties={"size":fontsize,"family":font_family},
214
+ prop={"size":fontsize,"family":font_family}
211
215
  )
212
216
  #else:
213
217
  ##
@@ -269,15 +273,21 @@ def _plot_effect(to_plot,
269
273
  # for legend_row in legend_rows[:-1]:
270
274
  # ax1.add_artist(legend_row)
271
275
 
272
-
273
-
274
276
  if effect_label is not None:
275
- ax1.set_xlabel(effect_label)
277
+ ax1.set_xlabel(effect_label, fontsize=fontsize, family=font_family)
278
+ ax1.tick_params(axis='x',
279
+ labelsize=fontsize,
280
+ labelfontfamily=font_family)
276
281
  if eaf_label is not None:
277
- ax2.set_xlabel(eaf_label)
282
+ ax2.set_xlabel(eaf_label, fontsize=fontsize, family=font_family)
283
+ ax2.tick_params(axis='x',
284
+ labelsize=fontsize,
285
+ labelfontfamily=font_family)
278
286
  if snpr2_label is not None:
279
- ax3.set_xlabel(snpr2_label)
280
-
287
+ ax3.set_xlabel(snpr2_label, fontsize=fontsize, family=font_family)
288
+ ax3.tick_params(axis='x',
289
+ labelsize=fontsize,
290
+ labelfontfamily=font_family)
281
291
  save_figure(fig, save, keyword="forest",save_args=save_kwargs, log=log, verbose=verbose)
282
292
 
283
293
  return fig
@@ -301,6 +301,7 @@ def plot_miami2(
301
301
  ax5l, ax5r = ax1.get_xlim()
302
302
  ax1.set_xlim([min(ax1l,ax5l), max(ax1r,ax5r)])
303
303
  ax5.set_xlim([min(ax1l,ax5l), max(ax1r,ax5r)])
304
+
304
305
  #####################################################################################################################
305
306
  ax5.set_xlabel("")
306
307
  #ax5.set_xticks(chrom_df)
@@ -317,8 +318,8 @@ def plot_miami2(
317
318
 
318
319
  ax1.tick_params(axis='x', which='major', pad=xtick_label_pad)
319
320
 
320
- ax1.set_ylabel("$-log_{10}(P)$",fontsize=fontsize,family=font_family)
321
- ax5.set_ylabel("$-log_{10}(P)$",fontsize=fontsize,family=font_family)
321
+ ax1.set_ylabel("$\mathregular{-log_{10}(P)}$",fontsize=fontsize,family=font_family)
322
+ ax5.set_ylabel("$\mathregular{-log_{10}(P)}$",fontsize=fontsize,family=font_family)
322
323
 
323
324
  ax1.set_title(titles[0],y=titles_pad_adjusted[0],family=font_family)
324
325
  ax5.set_title(titles[1],y=titles_pad_adjusted[1],family=font_family)