gwaslab 3.4.49__tar.gz → 3.5.0__tar.gz

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 (92) hide show
  1. {gwaslab-3.4.49/src/gwaslab.egg-info → gwaslab-3.5.0}/PKG-INFO +1 -1
  2. {gwaslab-3.4.49 → gwaslab-3.5.0}/pyproject.toml +1 -1
  3. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_Sumstats.py +14 -2
  4. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_version.py +2 -2
  5. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_get_sig.py +18 -2
  6. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_aux_annotate_plot.py +75 -242
  7. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_aux_quickfix.py +9 -2
  8. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_aux_save_figure.py +2 -1
  9. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_compare_effect.py +48 -20
  10. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_mqqplot.py +70 -20
  11. gwaslab-3.5.0/src/gwaslab/viz_plot_phe_heatmap.py +260 -0
  12. {gwaslab-3.4.49 → gwaslab-3.5.0/src/gwaslab.egg-info}/PKG-INFO +1 -1
  13. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab.egg-info/SOURCES.txt +1 -0
  14. {gwaslab-3.4.49 → gwaslab-3.5.0}/LICENSE +0 -0
  15. {gwaslab-3.4.49 → gwaslab-3.5.0}/LICENSE_before_v3.4.39 +0 -0
  16. {gwaslab-3.4.49 → gwaslab-3.5.0}/README.md +0 -0
  17. {gwaslab-3.4.49 → gwaslab-3.5.0}/setup.cfg +0 -0
  18. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/__init__.py +0 -0
  19. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/bd_common_data.py +0 -0
  20. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/bd_config.py +0 -0
  21. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/bd_download.py +0 -0
  22. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/bd_get_hapmap3.py +0 -0
  23. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/cache_manager.py +0 -0
  24. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/chrx_par/chrx_par_hg19.bed.gz +0 -0
  25. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/chrx_par/chrx_par_hg38.bed.gz +0 -0
  26. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/formatbook.json +0 -0
  27. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/hapmap3_SNPs/hapmap3_db150_hg19.snplist.gz +0 -0
  28. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/hapmap3_SNPs/hapmap3_db151_hg38.snplist.gz +0 -0
  29. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/high_ld/high_ld_hla_hg19.bed.gz +0 -0
  30. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/high_ld/high_ld_hla_hg38.bed.gz +0 -0
  31. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/data/reference.json +0 -0
  32. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_Log.py +0 -0
  33. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_Phenotypes.py +0 -0
  34. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_SumstatsPair.py +0 -0
  35. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_SumstatsT.py +0 -0
  36. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_Sumstats_summary.py +0 -0
  37. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_meta.py +0 -0
  38. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/g_vchange_status.py +0 -0
  39. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/hm_casting.py +0 -0
  40. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/hm_harmonize_sumstats.py +0 -0
  41. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/hm_rsid_to_chrpos.py +0 -0
  42. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/io_preformat_input.py +0 -0
  43. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/io_read_ldsc.py +0 -0
  44. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/io_read_tabular.py +0 -0
  45. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/io_to_formats.py +0 -0
  46. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/io_to_pickle.py +0 -0
  47. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/ldsc_irwls.py +0 -0
  48. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/ldsc_jackknife.py +0 -0
  49. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/ldsc_ldscore.py +0 -0
  50. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/ldsc_parse.py +0 -0
  51. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/ldsc_regressions.py +0 -0
  52. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/ldsc_sumstats.py +0 -0
  53. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/qc_check_datatype.py +0 -0
  54. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/qc_fix_sumstats.py +0 -0
  55. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/run_script.py +0 -0
  56. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_abf_finemapping.py +0 -0
  57. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_calculate_ldmatrix.py +0 -0
  58. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_calculate_prs.py +0 -0
  59. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_gwascatalog.py +0 -0
  60. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_ldproxyfinder.py +0 -0
  61. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_ldsc.py +0 -0
  62. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_plink_filter.py +0 -0
  63. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_process_h5.py +0 -0
  64. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_process_ref.py +0 -0
  65. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_run_2samplemr.py +0 -0
  66. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_run_clumping.py +0 -0
  67. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_run_coloc.py +0 -0
  68. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_ex_run_susie.py +0 -0
  69. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_calculate_gc.py +0 -0
  70. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_calculate_power.py +0 -0
  71. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_convert_h2.py +0 -0
  72. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_correct_winnerscurse.py +0 -0
  73. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_fill_data.py +0 -0
  74. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_filter_value.py +0 -0
  75. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_get_density.py +0 -0
  76. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_meta.py +0 -0
  77. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/util_in_snphwe.py +0 -0
  78. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_aux_chromatin.py +0 -0
  79. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_aux_reposition_text.py +0 -0
  80. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_compare_af.py +0 -0
  81. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_forestplot.py +0 -0
  82. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_miamiplot.py +0 -0
  83. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_miamiplot2.py +0 -0
  84. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_qqplot.py +0 -0
  85. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_regional2.py +0 -0
  86. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_regionalplot.py +0 -0
  87. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_rg_heatmap.py +0 -0
  88. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_stackedregional.py +0 -0
  89. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab/viz_plot_trumpetplot.py +0 -0
  90. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab.egg-info/dependency_links.txt +0 -0
  91. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab.egg-info/requires.txt +0 -0
  92. {gwaslab-3.4.49 → gwaslab-3.5.0}/src/gwaslab.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gwaslab
3
- Version: 3.4.49
3
+ Version: 3.5.0
4
4
  Summary: A collection of handy tools for GWAS SumStats
5
5
  Author-email: Yunye <yunye@gwaslab.com>
6
6
  Project-URL: Homepage, https://cloufield.github.io/gwaslab/
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "gwaslab"
10
- version = "3.4.49"
10
+ version = "3.5.0"
11
11
  authors = [
12
12
  { name="Yunye", email="yunye@gwaslab.com" },
13
13
  ]
@@ -81,6 +81,7 @@ from gwaslab.bd_get_hapmap3 import gethapmap3
81
81
  from gwaslab.util_abf_finemapping import abf_finemapping
82
82
  from gwaslab.util_abf_finemapping import make_cs
83
83
  import gc
84
+ from gwaslab.viz_plot_phe_heatmap import _gwheatmap
84
85
 
85
86
  #20220309
86
87
  class Sumstats():
@@ -602,6 +603,11 @@ class Sumstats():
602
603
  def plot_daf(self, **kwargs):
603
604
  fig,outliers = plotdaf(self.data, **kwargs)
604
605
  return fig, outliers
606
+
607
+ def plot_gwheatmap(self, **kwargs):
608
+ fig = _gwheatmap(self.data, **kwargs)
609
+ return fig
610
+
605
611
  def plot_mqq(self, build=None, **kwargs):
606
612
 
607
613
  chrom="CHR"
@@ -705,7 +711,7 @@ class Sumstats():
705
711
  # return sumstats object
706
712
  return output
707
713
 
708
- def check_cis(self, **kwargs):
714
+ def check_cis(self, gls=False, **kwargs):
709
715
  if "SNPID" in self.data.columns:
710
716
  id_to_use = "SNPID"
711
717
  else:
@@ -717,7 +723,13 @@ class Sumstats():
717
723
  p="P",
718
724
  log=self.log,
719
725
  **kwargs)
720
- # return sumstats object
726
+
727
+ # return sumstats object
728
+ if gls == True:
729
+ new_Sumstats_object = copy.deepcopy(self)
730
+ new_Sumstats_object.data = output
731
+ gc.collect()
732
+ return new_Sumstats_object
721
733
  return output
722
734
 
723
735
  def check_novel_set(self, **kwargs):
@@ -15,8 +15,8 @@ def _get_version():
15
15
  def gwaslab_info():
16
16
  # version meta information
17
17
  dic={
18
- "version":"3.4.49",
19
- "release_date":"20241019"
18
+ "version":"3.5.0",
19
+ "release_date":"20241029"
20
20
  }
21
21
  return dic
22
22
 
@@ -619,8 +619,10 @@ def _check_cis(insumstats,
619
619
  except:
620
620
  pass
621
621
 
622
- allsig["CIS/TRANS"] = allsig.apply(lambda x: determine_if_cis(x, group_key,windowsizekb, reference_dict), axis=1)
623
-
622
+ #allsig["CIS/TRANS"] = allsig.apply(lambda x: determine_if_cis(x, group_key,windowsizekb, reference_dict), axis=1)
623
+ cis_tuples = allsig.apply(lambda x: determine_if_cis2(x, group_key,windowsizekb, reference_dict), axis=1)
624
+ allsig[["CIS/TRANS","REF_CHR","REF_START","REF_END"]] = pd.DataFrame(cis_tuples.tolist(), index=allsig.index)
625
+
624
626
  try:
625
627
  allsig = allsig.where(~pd.isna(allsig), pd.NA)
626
628
  except:
@@ -689,6 +691,20 @@ def determine_if_cis(x, group_key,windowsizekb, reference_dict):
689
691
  else:
690
692
  return "NoReference"
691
693
 
694
+ def determine_if_cis2(x, group_key,windowsizekb, reference_dict):
695
+ if x[group_key] in reference_dict.keys():
696
+ is_same_chr = str(reference_dict[x[group_key]][0]) == str(x["CHR"])
697
+ is_large_than_start = int(reference_dict[x[group_key]][1]) - windowsizekb*1000 <= x["POS"]
698
+ is_smaller_than_end = int(reference_dict[x[group_key]][2]) + windowsizekb*1000 >= x["POS"]
699
+
700
+ if is_same_chr and is_large_than_start and is_smaller_than_end:
701
+ return "Cis", int(reference_dict[x[group_key]][0]), int(reference_dict[x[group_key]][1]), int(reference_dict[x[group_key]][2])
702
+ else:
703
+ return "Trans", int(reference_dict[x[group_key]][0]), int(reference_dict[x[group_key]][1]), int(reference_dict[x[group_key]][2])
704
+ else:
705
+ return "NoReference", pd.NA, pd.NA, pd.NA
706
+
707
+
692
708
  def determine_distance(allsig, knownsig):
693
709
  if len(allsig)==0:
694
710
  return allsig
@@ -60,21 +60,21 @@ def annotate_single(
60
60
  elif anno:
61
61
  annotation_col=anno
62
62
  log.write(" -Annotating using column "+annotation_col+"...", verbose=verbose)
63
-
63
+ ################################################################################################################################
64
64
  ## calculate y span
65
65
  if region is not None:
66
66
  y_span = region[2] - region[1]
67
67
  else:
68
68
  y_span = sumstats["i"].max()-sumstats["i"].min()
69
-
70
69
  log.write(" -Adjusting text positions with repel_force={}...".format(repel_force), verbose=verbose)
71
70
  if anno_style == "expand" :
72
71
  to_annotate.loc[:, "ADJUSTED_i"] = adjust_text_position(to_annotate["i"].values.copy(), y_span, repel_force,max_iter=anno_max_iter,log=log,amode=amode,verbose=verbose)
73
72
  ## iterate through variants to be annotated
73
+ ################################################################################################################################
74
+
74
75
  anno_to_adjust_list = list()
75
76
 
76
77
  for rowi,row in to_annotate.iterrows():
77
-
78
78
  # avoid text overlapping
79
79
  ## adjust x to avoid overlapping################################################################
80
80
  if anno_style == "right" :
@@ -93,7 +93,7 @@ def annotate_single(
93
93
  else:
94
94
  pass
95
95
  ################################################################
96
- #shrink or increase the arm
96
+ # shrink or increase the arm by a factor (arm_scale)
97
97
  if arm_scale_d is not None:
98
98
  if anno_count not in arm_scale_d.keys():
99
99
  arm_scale =1
@@ -102,20 +102,32 @@ def annotate_single(
102
102
  ################################################################
103
103
 
104
104
  # vertical arm length in pixels
105
- #to_annotate["scaled_P"] = to_annotate5["scaled_P_2"].copy()
106
- # arm length in pixels
107
- #armB_length_in_point = ax1.transData.transform((skip,1.15*maxy))[1]-ax1.transData.transform((skip, row["scaled_P"]+1))[1]-arm_offset/2
108
- armB_length_in_point = ax1.transData.transform((skip,1.15*maxy))[1]-ax1.transData.transform((skip, row["scaled_P"]+0.01*maxy))[1]-arm_offset/2
109
- # scale if needed
110
- armB_length_in_point = armB_length_in_point*arm_scale
105
+ # Annotation y : 1.15 * maxy_anno
106
+ # Top dot: 1 * maxy_anno
107
+ # armB_length_in_point_raw = 0.15 * maxy_anno -> gap_pixel
108
+ # Fixed Offset: 0.5 * 0.15 * gap_pixel
109
+
110
+ #Calculate armB length in pixels
111
+ # arm_scale: raise up the ceiling
112
+
113
+ # gap : 0.5* space between top variant and annotation text
114
+ gap_pixel = (ax1.transData.transform((0,1.15*maxy*arm_scale))[1]-ax1.transData.transform((0, maxy*arm_scale))[1])*0.5
115
+
116
+ # armB_length_in_pixel_raw : distance between variant to annotate and annotation text
117
+ armB_length_in_pixel_raw = ax1.transData.transform((0,1.15*maxy*arm_scale))[1]-ax1.transData.transform((0, row["scaled_P"]+1))[1]
118
+
119
+ armB_length_in_pixel = armB_length_in_pixel_raw - gap_pixel
120
+
111
121
  ################################################################
122
+ # armB_length_in_pixel should not be negative
112
123
  if arm_scale>=1:
113
- #armB_length_in_point= armB_length_in_point if armB_length_in_point>0 else ax1.transData.transform((skip, maxy+2))[1]-ax1.transData.transform((skip, row["scaled_P"]+1))[1]
114
- armB_length_in_point= armB_length_in_point if armB_length_in_point>0 else ax1.transData.transform((skip, maxy+0.02*maxy))[1]-ax1.transData.transform((skip, row["scaled_P"]+0.01*maxy))[1]
115
- ###if anno_fixed_arm_length #############################################################
124
+ armB_length_in_pixel = max(0, armB_length_in_pixel)
125
+
126
+ ################################################################
127
+ #if setting anno_fixed_arm_length
116
128
  if anno_fixed_arm_length is not None:
117
- anno_fixed_arm_length_factor = ax1.transData.transform((skip,anno_fixed_arm_length))[1]-ax1.transData.transform((skip,0))[1]
118
- armB_length_in_point = anno_fixed_arm_length_factor
129
+ armB_length_in_pixel = ax1.transData.transform((skip,anno_fixed_arm_length))[1]-ax1.transData.transform((skip,0))[1]
130
+
119
131
  ################################################################################################################################
120
132
  # annotation alias
121
133
  if anno==True:
@@ -129,26 +141,31 @@ def annotate_single(
129
141
  else:
130
142
  annotation_text=row["Annotation"]
131
143
 
132
-
133
- #xy=(row["i"],row["scaled_P"]+0.2)
144
+ ################################################################################################################################
145
+ # setting arrow xy and text xy
146
+ # add a small space between variant and arrow head
134
147
  xy=(row["i"],row["scaled_P"]+0.01*maxy)
135
- xytext=(last_pos,1.15*maxy*arm_scale*anno_height)
148
+
149
+ # text xy is of the same height
150
+ # anno_height can be used to adjust the height of annotation text
151
+ xytext=(last_pos,1.15*maxy*(arm_scale + anno_height -1))
136
152
 
153
+ # for anno_fixed_arm_length
137
154
  if anno_fixed_arm_length is not None:
138
- armB_length_in_point = anno_fixed_arm_length
139
- xytext=(row["i"],row["scaled_P"]+0.2+anno_fixed_arm_length)
140
-
155
+ xytext=(row["i"],row["scaled_P"] + 0.2 + anno_fixed_arm_length)
156
+
157
+ ################################################################################################################################
158
+ # if not changing the directions of some annotation arror arms
141
159
  if anno_count not in anno_d.keys():
142
- #arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
143
- # connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_point)+",rad=0")
144
160
  if _invert==False:
145
161
  arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
146
- connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_point)+",rad=0")
162
+ connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_pixel)+",rad=0")
147
163
  else:
148
164
  arrowargs = dict(arrowstyle="-|>",relpos=(0,1),color="#ebebeb",
149
- connectionstyle="arc,angleA=0,armA=0,angleB=-90,armB="+str(armB_length_in_point)+",rad=0")
165
+ connectionstyle="arc,angleA=0,armA=0,angleB=-90,armB="+str(armB_length_in_pixel)+",rad=0")
150
166
  else:
151
- # adjuest horizontal direction
167
+ # if not changing the directions of some annotation arror arms
168
+ # adjust horizontal direction
152
169
  xy=(row["i"],row["scaled_P"])
153
170
  if anno_d[anno_count] in ["right","left","l","r"]:
154
171
  if anno_d[anno_count]=="right" or anno_d[anno_count]=="r":
@@ -170,7 +187,7 @@ def annotate_single(
170
187
  elif anno_d[anno_count]=="left" or anno_d[anno_count]=="l":
171
188
  arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
172
189
  connectionstyle="arc,angleA=-135,armA="+str( anno_d[anno_count][1])+",angleB=135,armB="+str( anno_d[anno_count][1])+",rad=0")
173
-
190
+ ################################################################################################################################
174
191
 
175
192
  if "r" in mode:
176
193
  arrowargs["color"] = "black"
@@ -179,16 +196,19 @@ def annotate_single(
179
196
  bbox_para[key]=value
180
197
  else:
181
198
  bbox_para=None
182
-
199
+
200
+ ################################################################################################################################
183
201
  if _invert==False:
184
- anno_default = {"rotation":40,"fontstyle":"italic","ha":"left","va":"bottom","fontsize":anno_fontsize,"fontweight":"normal","fontfamily":font_family}
202
+ anno_default = {"rotation":40, "fontstyle":"italic","ha":"left","va":"bottom","fontsize":anno_fontsize,"fontweight":"normal","fontfamily":font_family}
185
203
  else:
186
- anno_default = {"rotation":-40,"fontstyle":"italic","ha":"left","va":"top","fontsize":anno_fontsize,"fontweight":"normal","fontfamily":font_family}
204
+ anno_default = {"rotation":-40,"fontstyle":"italic","ha":"left","va":"top", "fontsize":anno_fontsize,"fontweight":"normal","fontfamily":font_family}
187
205
 
206
+ ################################################################################################################################
188
207
  if anno_style == "expand" :
189
208
  anno_default["rotation"] = 90
190
209
  if anno_style == "tight" :
191
210
  anno_default["rotation"] = 90
211
+ ################################################################################################################################
192
212
 
193
213
  for key,value in anno_args.items():
194
214
  anno_default[key]=value
@@ -196,12 +216,13 @@ def annotate_single(
196
216
  if row["i"] in highlight_i:
197
217
  for key,value in highlight_anno_args.items():
198
218
  anno_default[key]=value
199
-
219
+ ################################################################################################################################
200
220
  if anno_adjust==True:
201
221
  if _invert==False:
202
222
  arrowargs=dict(arrowstyle='-|>', color='grey', shrinkA=10, linewidth=0.1, relpos=(0,0.5))
203
223
  else:
204
224
  arrowargs=dict(arrowstyle='-|>', color='grey', shrinkA=10, linewidth=0.1, relpos=(1,0.5))
225
+ ################################################################################################################################
205
226
 
206
227
  anno_to_adjust = ax1.annotate(annotation_text,
207
228
  xy=xy,
@@ -213,6 +234,8 @@ def annotate_single(
213
234
  )
214
235
  anno_to_adjust_list.append(anno_to_adjust)
215
236
  anno_count +=1
237
+ ################################################################################################################################
238
+
216
239
  #anno_adjust_keyargs = {"arrowprops":dict(arrowstyle='->', color='grey', linewidth=0.1,relpos=(0.5,0.5))}
217
240
  if anno_adjust==True:
218
241
  log.write(" -Auto-adjusting text positions...", verbose=verbose)
@@ -354,15 +377,25 @@ def annotate_pair(
354
377
  arm_scale = arm_scale_d[anno_count]
355
378
 
356
379
  # vertical arm length in pixels
357
- armB_length_in_point = ax.transData.transform((skip,1.15*maxy_anno))[1]-ax.transData.transform((skip, row["scaled_P"]+1))[1]-arm_offset/2
358
- # times arm_scale to increase or reduce the length
359
- armB_length_in_point = armB_length_in_point*arm_scale
380
+ # Annotation y : 1.15 * maxy_anno
381
+ # Top dot: 1 * maxy_anno
382
+ # armB_length_in_point_raw = 0.15 * maxy_anno -> gap_pixel
383
+ # Fixed Offset: 0.5 * 0.15 * gap_pixel
384
+
385
+ #Calculate armB length in pixels
386
+ # arm_scale: raise up the ceiling
387
+ gap_pixel = (ax1.transData.transform((0,1.15*maxy_anno*arm_scale))[1]-ax1.transData.transform((0, maxy_anno*arm_scale))[1])*0.5
388
+
389
+ armB_length_in_pixel_raw = ax1.transData.transform((0,1.15*maxy_anno*arm_scale))[1]-ax1.transData.transform((0, row["scaled_P"]+1))[1]
390
+
391
+ armB_length_in_pixel = armB_length_in_pixel_raw - gap_pixel
360
392
 
361
393
  if arm_scale>=1:
362
- armB_length_in_point= armB_length_in_point if armB_length_in_point>0 else 0 #ax.transData.transform((skip, maxy_anno+2))[1]-ax.transData.transform((skip, row["scaled_P"]+1))[1]
394
+ armB_length_in_pixel= armB_length_in_pixel if armB_length_in_pixel>0 else 0
395
+
363
396
  if anno_fixed_arm_length is not None:
364
397
  anno_fixed_arm_length_factor = ax.transData.transform((skip,anno_fixed_arm_length))[1]-ax.transData.transform((skip,0))[1]
365
- armB_length_in_point = anno_fixed_arm_length_factor
398
+ armB_length_in_pixel = anno_fixed_arm_length_factor
366
399
 
367
400
  if anno==True:
368
401
  if row[snpid] in anno_alias.keys():
@@ -383,24 +416,24 @@ def annotate_pair(
383
416
  xytext=(last_pos,1.15*maxy_anno*arm_scale)
384
417
 
385
418
  if anno_fixed_arm_length is not None:
386
- armB_length_in_point = anno_fixed_arm_length
419
+ armB_length_in_pixel = anno_fixed_arm_length
387
420
  xytext=(row["i"],row["scaled_P"]+0.2+anno_fixed_arm_length)
388
421
 
389
422
  if anno_count not in anno_d.keys():
390
423
  if index==0:
391
424
  #upper panel
392
- if armB_length_in_point <5:
425
+ if armB_length_in_pixel <5:
393
426
  arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",connectionstyle="arc,armA=0,armB=0,rad=0.")
394
427
  else:
395
428
  arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
396
- connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_point)+",rad=0")
429
+ connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_pixel)+",rad=0")
397
430
  else:
398
431
  #lower panel
399
- if armB_length_in_point <5:
432
+ if armB_length_in_pixel <5:
400
433
  arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",connectionstyle="arc,armA=0,armB=0,rad=0.")
401
434
  else:
402
435
  arrowargs = dict(arrowstyle="-|>",relpos=(0,1),color="#ebebeb",
403
- connectionstyle="arc,angleA=0,armA=0,angleB=-90,armB="+str(armB_length_in_point)+",rad=0")
436
+ connectionstyle="arc,angleA=0,armA=0,angleB=-90,armB="+str(armB_length_in_pixel)+",rad=0")
404
437
 
405
438
  else:
406
439
  xy=(row["i"],row["scaled_P"])
@@ -478,204 +511,4 @@ def annotate_pair(
478
511
  )
479
512
  else:
480
513
  log.write(" -Skip annotating", verbose=verbose)
481
- return ax1,ax5
482
-
483
-
484
- # subtype plot
485
- def annotate_subtype(
486
- sumstats,
487
- anno,
488
- mode,
489
- ax1,
490
- highlight_i,
491
- to_annotate,
492
- anno_d,
493
- anno_alias,
494
- anno_style,
495
- anno_args,
496
- arm_scale,
497
- anno_max_iter,
498
- arm_scale_d,
499
- arm_offset,
500
- anno_adjust,
501
- anno_fixed_arm_length,
502
- maxy,
503
- anno_fontsize,
504
- region,
505
- region_anno_bbox_args,
506
- skip,
507
- snpid="SNPID",
508
- chrom="CHR",
509
- pos="POS",
510
- repel_force=0.02,
511
- verbose=True,
512
- log=Log()
513
- ):
514
- if anno and (to_annotate.empty is not True):
515
- #initiate a list for text and a starting position
516
- text = []
517
- last_pos=0
518
- anno_count=0
519
- to_annotate = to_annotate.sort_values(by=[chrom,pos])
520
- ## log : annotation column
521
- if anno==True:
522
- annotation_col="CHR:POS"
523
- elif anno:
524
- annotation_col=anno
525
- log.write(" -Annotating using column "+annotation_col+"...", verbose=verbose)
526
-
527
- ## calculate y span
528
- if region is not None:
529
- y_span = region[2] - region[1]
530
- else:
531
- y_span = sumstats["i"].max()-sumstats["i"].min()
532
-
533
- log.write(" -Adjusting text positions with repel_force={}...".format(repel_force), verbose=verbose)
534
- if anno_style == "expand" :
535
- to_annotate.loc[:, "ADJUSTED_i"] = adjust_text_position(to_annotate["i"].values.copy(), y_span, repel_force,max_iter=anno_max_iter,log=log,verbose=verbose)
536
- ## iterate through variants to be annotated
537
- anno_to_adjust_list = list()
538
-
539
- for rowi,row in to_annotate.iterrows():
540
-
541
- # avoid text overlapping
542
- ## adjust x to avoid overlapping################################################################
543
- if anno_style == "right" :
544
- #right style
545
- if row["i"]>last_pos+repel_force*y_span:
546
- last_pos=row["i"]
547
- else:
548
- last_pos+=repel_force*y_span
549
- elif anno_style == "expand" :
550
- #expand style
551
- last_pos = row["ADJUSTED_i"]
552
- anno_args["rotation"] = 90
553
- elif anno_style == "tight" :
554
- #tight style
555
- anno_fixed_arm_length = 1
556
- anno_adjust = True
557
- anno_args["rotation"] = 90
558
- else:
559
- pass
560
- ################################################################
561
- #shrink or increase the arm
562
- if arm_scale_d is not None:
563
- if anno_count not in arm_scale_d.keys():
564
- arm_scale =1
565
- else:
566
- arm_scale = arm_scale_d[anno_count]
567
- ################################################################
568
-
569
- # vertical arm length in pixels
570
- armB_length_in_point = ax1.transData.transform((skip,1.15*maxy))[1]-ax1.transData.transform((skip, row["scaled_P"]+1))[1]-arm_offset/2
571
- # scale if needed
572
- armB_length_in_point = armB_length_in_point*arm_scale
573
- ################################################################
574
- if arm_scale>=1:
575
- armB_length_in_point= armB_length_in_point if armB_length_in_point>0 else ax1.transData.transform((skip, maxy+2))[1]-ax1.transData.transform((skip, row["scaled_P"]+1))[1]
576
- ###if anno_fixed_arm_length #############################################################
577
- if anno_fixed_arm_length is not None:
578
- anno_fixed_arm_length_factor = ax1.transData.transform((skip,anno_fixed_arm_length))[1]-ax1.transData.transform((skip,0))[1]
579
- armB_length_in_point = anno_fixed_arm_length_factor
580
- ################################################################################################################################
581
- # annotation alias
582
- if anno==True:
583
- if row[snpid] in anno_alias.keys():
584
- annotation_text = anno_alias[row[snpid]]
585
- else:
586
- annotation_text="Chr"+ str(row[chrom]) +":"+ str(int(row[pos]))
587
- elif anno:
588
- annotation_text=row["Annotation"]
589
-
590
- #
591
- fontweight = "normal"
592
- if len(highlight_i) >0:
593
- if row["i"] in highlight_i:
594
- fontweight = "bold"
595
-
596
-
597
- xy=(row["i"],row["scaled_P"]+0.2)
598
- xytext=(last_pos, 1.15*maxy*arm_scale)
599
-
600
- if anno_fixed_arm_length is not None:
601
- armB_length_in_point = anno_fixed_arm_length
602
- xytext=(row["i"],row["scaled_P"]+0.2+anno_fixed_arm_length)
603
-
604
- if anno_count not in anno_d.keys():
605
- #arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
606
- # connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_point)+",rad=0")
607
- arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
608
- connectionstyle="arc,angleA=0,armA=0,angleB=90,armB="+str(armB_length_in_point)+",rad=0")
609
- else:
610
- # adjuest direction
611
- xy=(row["i"],row["scaled_P"])
612
- if anno_d[anno_count] in ["right","left","l","r"]:
613
- if anno_d[anno_count]=="right" or anno_d[anno_count]=="r":
614
- armoffsetall = (ax1.transData.transform(xytext)[0]-ax1.transData.transform(xy)[0])*np.sqrt(2)
615
- armoffsetb = arm_offset
616
- armoffseta = armoffsetall - armoffsetb
617
- arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
618
- connectionstyle="arc,angleA=-135,armA="+str(armoffseta)+",angleB=45,armB="+str(armoffsetb)+",rad=0")
619
- elif anno_d[anno_count]=="left" or anno_d[anno_count]=="l":
620
- arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
621
- connectionstyle="arc,angleA=-135,armA="+str(arm_offset)+",angleB=135,armB="+str(arm_offset)+",rad=0")
622
- else:
623
- if anno_d[anno_count][0]=="right" or anno_d[anno_count][0]=="r":
624
- armoffsetall = (ax1.transData.transform(xytext)[0]-ax1.transData.transform(xy)[0])*np.sqrt(2)
625
- armoffsetb = anno_d[anno_count][1]
626
- armoffseta = armoffsetall - armoffsetb
627
- arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
628
- connectionstyle="arc,angleA=-135,armA="+str(armoffseta)+",angleB=45,armB="+str(armoffsetb)+",rad=0")
629
- elif anno_d[anno_count]=="left" or anno_d[anno_count]=="l":
630
- arrowargs = dict(arrowstyle="-|>",relpos=(0,0),color="#ebebeb",
631
- connectionstyle="arc,angleA=-135,armA="+str( anno_d[anno_count][1])+",angleB=135,armB="+str( anno_d[anno_count][1])+",rad=0")
632
-
633
-
634
- if "r" in mode:
635
- arrowargs["color"] = "black"
636
- bbox_para=dict(boxstyle="round", fc="white",zorder=3)
637
- for key,value in region_anno_bbox_args.items():
638
- bbox_para[key]=value
639
- else:
640
- bbox_para=None
641
-
642
- anno_default = {"rotation":40,"style":"italic","ha":"left","va":"bottom","fontsize":anno_fontsize,"fontweight":fontweight}
643
- for key,value in anno_args.items():
644
- anno_default[key]=value
645
-
646
- if anno_adjust==True:
647
- arrowargs=dict(arrowstyle='-|>', color='grey', shrinkA=10, linewidth=0.1, relpos=(0,0.5))
648
- anno_to_adjust = ax1.annotate(annotation_text,
649
- xy=xy,
650
- xytext=xytext,
651
- bbox=bbox_para,
652
- arrowprops=arrowargs,
653
- zorder=100,
654
- **anno_default
655
- )
656
- anno_to_adjust_list.append(anno_to_adjust)
657
- anno_count +=1
658
- #anno_adjust_keyargs = {"arrowprops":dict(arrowstyle='->', color='grey', linewidth=0.1,relpos=(0.5,0.5))}
659
- if anno_adjust==True:
660
- log.write(" -Auto-adjusting text positions...", verbose=verbose)
661
- adjust_text(texts = anno_to_adjust_list,
662
- autoalign=False,
663
- only_move={'points':'x', 'text':'x', 'objects':'x'},
664
- ax=ax1,
665
- precision=0.02,
666
- force_text=(repel_force,repel_force),
667
- expand_text=(1,1),
668
- expand_objects=(0,0),
669
- expand_points=(0,0),
670
- va="bottom",
671
- ha='left',
672
- avoid_points=False,
673
- lim =100
674
- #kwargs = anno_adjust_keyargs
675
- )
676
-
677
- else:
678
- log.write(" -Skip annotating", verbose=verbose)
679
-
680
- return ax1
681
-
514
+ return ax1,ax5
@@ -80,6 +80,7 @@ def _quick_fix_chr(seires, chr_dict,log=Log(), verbose=True):
80
80
  '''
81
81
  if pd.api.types.is_string_dtype(seires) == True:
82
82
  # if chr is string dtype: convert using chr_dict
83
+ seires = seires.astype("string")
83
84
  seires = seires.map(chr_dict, na_action="ignore")
84
85
  seires = np.floor(pd.to_numeric(seires, errors='coerce')).astype('Int64')
85
86
  return seires
@@ -93,6 +94,12 @@ def _quick_fix_pos(seires,log=Log(), verbose=True):
93
94
  return seires
94
95
 
95
96
 
97
+ def _dropna_in_cols(sumstats, cols, log=Log(), verbose=True):
98
+ to_drop = sumstats[cols].isna().any(axis=1)
99
+ log.write(" -Dropping {} variants due to missing values in {}.".format(sum(to_drop),cols))
100
+ return sumstats.loc[~to_drop,:]
101
+
102
+
96
103
  def _get_largenumber(*args,log=Log(), verbose=True):
97
104
  '''
98
105
  get a helper large number, >> max(pos)
@@ -330,7 +337,7 @@ def _cut(series, mode,cutfactor,cut,skip, ylabels, cut_log, verbose, lines_to_pl
330
337
  if "b" not in mode:
331
338
  log.write(" -Minus log10(P) values above " + str(cut)+" will be shrunk with a shrinkage factor of " + str(cutfactor)+"...", verbose=verbose)
332
339
  else:
333
- log.write(" -Minus DENSITY values above " + str(cut)+" will be shrunk with a shrinkage factor of " + str(cutfactor)+"...", verbose=verbose)
340
+ log.write(" -DENSITY values above " + str(cut)+" will be shrunk with a shrinkage factor of " + str(cutfactor)+"...", verbose=verbose)
334
341
 
335
342
  maxticker=int(np.round(series.max(skipna=True)))
336
343
 
@@ -448,4 +455,4 @@ def _jagged_y(cut,skip,ax1,mode,mqqratio,jagged_len,jagged_wid, log=Log(), verbo
448
455
  ax1.plot((x0,-dx), (tycut,tycut+dy), zorder=1001, **kwargs)
449
456
  ax1.plot((-dx,+dx), (tycut+dy,tycut+3*dy), zorder=1001, **kwargs)
450
457
  ax1.plot((+dx,x0), (tycut+3*dy,tycut+4*dy), zorder=1001, **kwargs)
451
- return ax1
458
+ return ax1
@@ -50,7 +50,8 @@ def get_default_path(keyword,fmt="png"):
50
50
  "ldscrg":"ldscrg_heatmap",
51
51
  "miami":"miami",
52
52
  "esc":"effect_size_comparision",
53
- "afc":"allele_frequency_comparision"
53
+ "afc":"allele_frequency_comparision",
54
+ "gwheatmap":"genome_wide_heatmap"
54
55
  }
55
56
  prefix = path_dictionary[keyword]
56
57
  count = 1