def boxplot_single_factor(df='dataframe', column_names=None, grid=False, ar=(0, 0), axtickfontsize=9, axtickfontname='Arial', dim=(6, 4), show=False, figtype='png', figname='boxplot', r=300, ylm=None, box_line_style='-', box_line_width=1, box_line_color='b', med_line_style='-', med_line_width=1, med_line_color='g', whisk_line_color='b', cap_color='b', add_sign_symbol=False, symb_dist=None, sign_symbol_opts={'symbol': '*', 'fontsize': 8 }, pv=None, notch=False, outliers=True, fill_box_color=True, dotplot=False, dotsize=6, colordot=['#101820ff'], valphadot=1, markerdot='o', theme=None): if theme == 'dark': general.dark_bg() plt.subplots() if column_names: xbar = column_names else: xbar = list(df.columns) # rot is x axis rotation other_args = {'grid': grid, 'rot': ar[0], 'fontsize': axtickfontsize, 'notch':notch, 'showfliers':outliers, 'figsize': dim, 'patch_artist': fill_box_color} color_args = {'medians': med_line_color, 'boxes': box_line_color, 'whiskers': whisk_line_color, 'caps': cap_color} medianprops_args = {'linestyle': med_line_style, 'linewidth': med_line_width} boxprops_args = {'linestyle': box_line_style, 'linewidth': box_line_width} if isinstance(column_names, list): df.boxplot(column=column_names, **other_args, boxprops=boxprops_args, medianprops=medianprops_args, color=color_args) else: df.boxplot(**other_args, boxprops=boxprops_args, color=color_args, medianprops=medianprops_args) # ylm must be tuple of start, end, interval if ylm: plt.ylim(bottom=ylm[0], top=ylm[1]) plt.yticks(np.arange(ylm[0], ylm[1], ylm[2]), fontsize=axtickfontsize, fontname=axtickfontname) plt.yticks(fontsize=axtickfontsize, rotation=ar[1], fontname=axtickfontname) color_list_dot = colordot if len(color_list_dot) == 1: color_list_dot = colordot * len(xbar) # checked for unstacked data if dotplot: for cols in range(len(xbar)): plt.scatter( x=np.linspace(xbar[cols] - bw / 2, xbar[cols] + bw / 2, int(bar_counts[cols])), y=df[df.columns[cols]].dropna(), s=dotsize, color=color_list_dot[cols], zorder=10, alpha=valphadot, marker=markerdot) size_factor_to_start_line = max(df.max()) / 20 if add_sign_symbol: # p and symb_dist should be dict if isinstance(pv, dict): for k, v in pv.items(): if isinstance(symb_dist, dict): if k not in symb_dist: symb_dist[k] = 0 y_pos = df[k].max() + size_factor_to_start_line + symb_dist[k] else: y_pos = df[k].max() + size_factor_to_start_line if y_pos > 0 and v <= 0.05: pv_symb = general.pvalue_symbol(v, sign_symbol_opts['symbol']) if pv_symb: plt.annotate(pv_symb, xy=((xbar.index(k))+1, y_pos), fontsize=sign_symbol_opts['fontsize'], ha="center") general.get_figure(show, r, figtype, figname, theme)