visualize_5_33.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. def multi_bar(df="dataframe", dim=(5, 4), colbar=None, colerrorbar=None, bw=0.4, colorbar=None, xbarcol=None, r=300,
  2. show=False, axtickfontname="Arial", axtickfontsize=9, ax_x_ticklabel=None, ar=90, figtype='png',
  3. figname='multi_bar', valphabar=1, legendpos='best', errorbar=False, yerrlw=None, yerrcw=None,
  4. plotlegend=False, hbsize=4, ylm=None, add_sign_line=False, pv=None,
  5. sign_line_opts={'symbol': '*', 'fontsize': 8, 'linewidth':0.8, 'arrowstyle': '-', 'dist_y_pos': 2.5,
  6. 'dist_y_neg': 4.2}, add_sign_symbol=False, sign_symbol_opts={'symbol': '*',
  7. 'fontsize': 8 },
  8. dotplot=False, sub_cat=None,
  9. sub_cat_opts={'y_neg_dist': 3.5, 'fontsize': 8}, sub_cat_label_dist=None, theme=None):
  10. xbar = np.arange(df.shape[0])
  11. xbar_temp = xbar
  12. if theme == 'dark':
  13. general.dark_bg()
  14. fig, ax = plt.subplots(figsize=dim)
  15. assert len(colbar) >= 2, "number of bar should be atleast 2"
  16. assert len(colbar) == len(colorbar), "number of color should be equivalent to number of column bars"
  17. if colbar is not None and isinstance(colbar, (tuple, list)):
  18. for i in range(len(colbar)):
  19. if errorbar:
  20. ax.bar(x=xbar_temp, height=df[colbar[i]], yerr=df[colerrorbar[i]], width=bw, color=colorbar[i],
  21. alpha=valphabar, capsize=hbsize, label=colbar[i], error_kw={'elinewidth': yerrlw,
  22. 'capthick': yerrcw})
  23. xbar_temp = xbar_temp+bw
  24. else:
  25. ax.bar(x=xbar_temp, height=df[colbar[i]], width=bw, color=colorbar[i], alpha=valphabar,
  26. label=colbar[i])
  27. xbar_temp = xbar_temp + bw
  28. ax.set_xticks(xbar+( (bw*(len(colbar)-1)) / (1+(len(colbar)-1)) ))
  29. if ax_x_ticklabel:
  30. x_ticklabel = ax_x_ticklabel
  31. else:
  32. x_ticklabel = df[xbarcol]
  33. ax.set_xticklabels(x_ticklabel, fontsize=axtickfontsize, rotation=ar, fontname=axtickfontname)
  34. # ylm must be tuple of start, end, interval
  35. if ylm:
  36. plt.ylim(bottom=ylm[0], top=ylm[1])
  37. plt.yticks(np.arange(ylm[0], ylm[1], ylm[2]), fontsize=axtickfontsize, fontname=axtickfontname)
  38. if plotlegend:
  39. plt.legend(loc=legendpos)
  40. if dotplot:
  41. for cols in range(len(df2['factors'].unique())):
  42. ax.scatter(x=np.linspace(xbar[cols] - bw / 2, xbar[cols] + bw / 2, int(reps)),
  43. y=df2[(df2['factors'] == df2['factors'].unique()[cols]) & (df2['sample'] == 'M')]['value'],
  44. s=dotsize, color="#7d0013", zorder=1, alpha=valphadot,
  45. marker=markerdot)
  46. if add_sign_line:
  47. if len(colbar) == 2:
  48. for i in xbar:
  49. x_pos = xbar[i]
  50. x_pos_2 = xbar[i] + bw
  51. y_pos = df[colbar[0]].to_numpy()[i] + df[colerrorbar[0]].to_numpy()[i]
  52. y_pos_2 = df[colbar[1]].to_numpy()[i] + df[colerrorbar[1]].to_numpy()[i]
  53. # only if y axis is positive
  54. if y_pos > 0:
  55. y_pos += 0.5
  56. y_pos_2 += 0.5
  57. pv_symb = general.pvalue_symbol(pv[i], sign_line_opts['symbol'])
  58. if pv_symb:
  59. ax.annotate('', xy=(x_pos, y_pos), xytext=(x_pos_2, y_pos),
  60. arrowprops={'connectionstyle': 'bar, armA=50, armB=50, angle=180, fraction=0 ',
  61. 'arrowstyle': sign_line_opts['arrowstyle'],
  62. 'linewidth': sign_line_opts['linewidth']})
  63. ax.annotate(pv_symb, xy=(np.mean([x_pos, x_pos_2]), max(y_pos, y_pos_2) +
  64. sign_line_opts['dist_y_pos']),
  65. fontsize=sign_line_opts['fontsize'], ha="center")
  66. else:
  67. y_pos -= 0.5
  68. y_pos_2 -= 0.5
  69. pv_symb = general.pvalue_symbol(pv[i], sign_line_opts['symbol'])
  70. if pv_symb:
  71. ax.annotate('', xy=(x_pos, y_pos), xytext=(x_pos_2, y_pos),
  72. arrowprops={'connectionstyle': 'bar, armA=50, armB=50, angle=180, fraction=-1 ',
  73. 'arrowstyle': sign_line_opts['arrowstyle'],
  74. 'linewidth': sign_line_opts['linewidth']})
  75. ax.annotate(pv_symb, xy=(np.mean([x_pos, x_pos_2]), min(y_pos_2, y_pos) -
  76. sign_line_opts['dist_y_neg']),
  77. fontsize=sign_line_opts['fontsize'], ha="center")
  78. if add_sign_symbol:
  79. if len(colbar) == 2:
  80. for i in xbar:
  81. x_pos = xbar[i]
  82. x_pos_2 = xbar[i] + bw
  83. # max value size factor is essential for rel pos of symbol
  84. y_pos = df[colbar[0]].to_numpy()[i] + df[colerrorbar[0]].to_numpy()[i] + \
  85. (max(df[colbar[0]].to_numpy()) / 20)
  86. y_pos_2 = df[colbar[1]].to_numpy()[i] + df[colerrorbar[1]].to_numpy()[i] + \
  87. (max(df[colbar[1]].to_numpy()) / 20)
  88. # only if y axis is positive
  89. if y_pos > 0:
  90. pv_symb_1 = general.pvalue_symbol(pv[i][0], sign_symbol_opts['symbol'])
  91. pv_symb_2 = general.pvalue_symbol(pv[i][1], sign_symbol_opts['symbol'])
  92. if pv_symb_1:
  93. plt.annotate(pv_symb_1, xy=(x_pos, y_pos), fontsize=sign_symbol_opts['fontsize'],
  94. ha="center")
  95. if pv_symb_2:
  96. plt.annotate(pv_symb_2, xy=(x_pos_2, y_pos_2), fontsize=sign_symbol_opts['fontsize'],
  97. ha="center")
  98. elif len(colbar) == 3:
  99. for i in xbar:
  100. x_pos = xbar[i]
  101. x_pos_2 = xbar[i] + bw
  102. x_pos_3 = xbar[i] + (2 * bw)
  103. # max value size factor is essential for rel pos of symbol
  104. y_pos = df[colbar[0]].to_numpy()[i] + df[colerrorbar[0]].to_numpy()[i] + \
  105. (max(df[colbar[0]].to_numpy()) / 20)
  106. y_pos_2 = df[colbar[1]].to_numpy()[i] + df[colerrorbar[1]].to_numpy()[i] + \
  107. (max(df[colbar[1]].to_numpy()) / 20)
  108. y_pos_3 = df[colbar[2]].to_numpy()[i] + df[colerrorbar[2]].to_numpy()[i] + \
  109. (max(df[colbar[2]].to_numpy()) / 20)
  110. # only if y axis is positive
  111. if y_pos > 0:
  112. pv_symb_1 = general.pvalue_symbol(pv[i][0], sign_symbol_opts['symbol'])
  113. pv_symb_2 = general.pvalue_symbol(pv[i][1], sign_symbol_opts['symbol'])
  114. pv_symb_3 = general.pvalue_symbol(pv[i][2], sign_symbol_opts['symbol'])
  115. if pv_symb_1:
  116. plt.annotate(pv_symb_1, xy=(x_pos, y_pos), fontsize=sign_symbol_opts['fontsize'],
  117. ha="center")
  118. if pv_symb_2:
  119. plt.annotate(pv_symb_2, xy=(x_pos_2, y_pos_2), fontsize=sign_symbol_opts['fontsize'],
  120. ha="center")
  121. if pv_symb_3:
  122. plt.annotate(pv_symb_3, xy=(x_pos_3, y_pos_3), fontsize=sign_symbol_opts['fontsize'],
  123. ha="center")
  124. # update this later for min_value
  125. min_value = 0
  126. sub_cat_i = 0
  127. if sub_cat:
  128. if isinstance(sub_cat, dict):
  129. for k in sub_cat:
  130. if isinstance(k, tuple) and len(k) == 2:
  131. cat_x_pos, cat_y_pos, cat_x_pos_2 = k[0], min_value - \
  132. (sub_cat_opts[
  133. 'y_neg_dist'] * size_factor_to_start_line), k[1]
  134. plt.annotate('', xy=(cat_x_pos - (bw / 2), cat_y_pos),
  135. xytext=(cat_x_pos_2 + (bw / 2), cat_y_pos),
  136. arrowprops={'arrowstyle': '-', 'linewidth': 0.5}, annotation_clip=False)
  137. if sub_cat_label_dist and isinstance(sub_cat_label_dist, list):
  138. plt.annotate(sub_cat[k], xy=(np.mean([cat_x_pos, cat_x_pos_2]),
  139. cat_y_pos - size_factor_to_start_line - sub_cat_label_dist[
  140. sub_cat_i]),
  141. ha="center", fontsize=sub_cat_opts['fontsize'], annotation_clip=False)
  142. sub_cat_i += 1
  143. else:
  144. plt.annotate(sub_cat[k], xy=(np.mean([cat_x_pos, cat_x_pos_2]),
  145. cat_y_pos - size_factor_to_start_line),
  146. ha="center", fontsize=sub_cat_opts['fontsize'], annotation_clip=False)
  147. else:
  148. raise KeyError("Sub category keys must be tuple of size 2")
  149. general.get_figure(show, r, figtype, figname, theme)
  150. # with replicates values stacked replicates
  151. # need to work on this later