diff --git a/plot_scatterplot.py b/plot_scatterplot.py index b4d43781e4bd1fc52d57cf24b85a147107ff3d81..94bb79bad09b1462cf5738944fe594feb4e376f7 100755 --- a/plot_scatterplot.py +++ b/plot_scatterplot.py @@ -152,9 +152,11 @@ class Scatterplot: if gene_id in chose_from] return [gene_id for gene_id in self.data.query(selector).index] - def plot_maker(self, grouping=None, group2colour=None, **kwargs): + def plot_maker(self, annotate_folds=True, grouping=None, group2colour=None, **kwargs): """Builds a plotting function that can colour dots based on them - belonging to a group defined by *grouping*.""" + belonging to a group defined by *grouping*. + If *annotate_folds* is True, lines indicating 2-fold thresholds + will be added to the plot, as well as counts in each quadrants.""" def plotting_function(): """Generates the scatterplot, returns its legend so that *save_plot* can include it in the bounding box.""" @@ -173,110 +175,111 @@ class Scatterplot: return None else: raise - # Lines indicating 2-fold threshold. - # Assumes the data are in log2 fold changes - line_style = { - "linewidth": 0.5, "color": "0.5", "linestyle": "dashed"} - if "x_range" in kwargs: - (x_annot_loc, _) = kwargs["x_range"] - else: - x_annot_loc = min(self.data.x) - if "y_range" in kwargs: - (y_annot_loc, _) = kwargs["y_range"] - else: - y_annot_loc = min(self.data.y) - axis.axhline(y=1, **line_style) - axis.annotate( - f"y = 1", xy=(x_annot_loc, 1), xycoords="data", - horizontalalignment='left', - verticalalignment='bottom', - size="x-small", - color=line_style["color"]) - axis.axhline(y=-1, **line_style) - axis.annotate( - f"y = -1", xy=(x_annot_loc, -1), xycoords="data", - horizontalalignment='left', - verticalalignment='top', - size="x-small", - color=line_style["color"]) - axis.axvline(x=1, **line_style) - axis.annotate( - f"x = -1", xy=(-1, y_annot_loc), xycoords="data", - horizontalalignment='right', - verticalalignment='bottom', - rotation=90, size="x-small", - color=line_style["color"]) - axis.axvline(x=-1, **line_style) - axis.annotate( - f"x = 1", xy=(1, y_annot_loc), xycoords="data", - horizontalalignment='left', - verticalalignment='bottom', - rotation=90, size="x-small", - color=line_style["color"]) - # Number of genes beyond lfc thresholds, in each quadrant - # up_up = 100 * len(self.data.query( - # f"x > 1 & y > 1")) / len(self.data) - # up_down = 100 * len(self.data.query( - # f"x > 1 & y < 1")) / len(self.data) - # down_up = 100 * len(self.data.query( - # f"x < 1 & y > 1")) / len(self.data) - # down_down = 100 * len(self.data.query( - # f"x < 1 & y < 1")) / len(self.data) - up_up = self.data.query( - "x > 1 & y > 1") - up_down = self.data.query( - "x > 1 & y < -1") - down_up = self.data.query( - "x < -1 & y > 1") - down_down = self.data.query( - "x < -1 & y < -1") - if isinstance(grouping, (list, tuple)): - try: - (_, colour) = group2colour - except (ValueError, TypeError): - colour = "black" - select_ingroup = pd.Index(grouping).intersection - ingroup_up_up = " (\\textcolor{%s}{%d})" % ( - colour, - len(up_up.loc[select_ingroup(up_up.index)]),) - ingroup_up_down = " (\\textcolor{%s}{%d})" % ( - colour, - len(up_down.loc[select_ingroup(up_down.index)])) - ingroup_down_up = " (\\textcolor{%s}{%d})" % ( - colour, - len(down_up.loc[select_ingroup(down_up.index)])) - ingroup_down_down = " (\\textcolor{%s}{%d})" % ( - colour, - len(down_down.loc[select_ingroup(down_down.index)])) - else: - ingroup_up_up = "" - ingroup_up_down = "" - ingroup_down_up = "" - ingroup_down_down = "" - axis.annotate( - f"{len(up_up)}{ingroup_up_up}", - xy=(0.95, 0.95), xycoords="axes fraction", - size="x-small", color=line_style["color"], - horizontalalignment="right", - verticalalignment="top") - axis.annotate( - f"{len(up_down)}{ingroup_up_down}", - xy=(0.95, 0.05), xycoords="axes fraction", - size="x-small", color=line_style["color"], - horizontalalignment="right", - verticalalignment="bottom") - axis.annotate( - f"{len(down_up)}{ingroup_down_up}", - xy=(0.05, 0.95), xycoords="axes fraction", - size="x-small", color=line_style["color"], - horizontalalignment="left", - verticalalignment="top") - axis.annotate( - f"{len(down_down)}{ingroup_down_down}", - xy=(0.05, 0.05), xycoords="axes fraction", - size="x-small", color=line_style["color"], - horizontalalignment="left", - verticalalignment="bottom") + if annotate_folds: + # Lines indicating 2-fold threshold. + # Assumes the data are in log2 fold changes + line_style = { + "linewidth": 0.5, "color": "0.5", "linestyle": "dashed"} + if "x_range" in kwargs: + (x_annot_loc, _) = kwargs["x_range"] + else: + x_annot_loc = min(self.data.x) + if "y_range" in kwargs: + (y_annot_loc, _) = kwargs["y_range"] + else: + y_annot_loc = min(self.data.y) + axis.axhline(y=1, **line_style) + axis.annotate( + f"y = 1", xy=(x_annot_loc, 1), xycoords="data", + horizontalalignment='left', + verticalalignment='bottom', + size="x-small", + color=line_style["color"]) + axis.axhline(y=-1, **line_style) + axis.annotate( + f"y = -1", xy=(x_annot_loc, -1), xycoords="data", + horizontalalignment='left', + verticalalignment='top', + size="x-small", + color=line_style["color"]) + axis.axvline(x=1, **line_style) + axis.annotate( + f"x = -1", xy=(-1, y_annot_loc), xycoords="data", + horizontalalignment='right', + verticalalignment='bottom', + rotation=90, size="x-small", + color=line_style["color"]) + axis.axvline(x=-1, **line_style) + axis.annotate( + f"x = 1", xy=(1, y_annot_loc), xycoords="data", + horizontalalignment='left', + verticalalignment='bottom', + rotation=90, size="x-small", + color=line_style["color"]) + # Number of genes beyond lfc thresholds, in each quadrant + # up_up = 100 * len(self.data.query( + # f"x > 1 & y > 1")) / len(self.data) + # up_down = 100 * len(self.data.query( + # f"x > 1 & y < 1")) / len(self.data) + # down_up = 100 * len(self.data.query( + # f"x < 1 & y > 1")) / len(self.data) + # down_down = 100 * len(self.data.query( + # f"x < 1 & y < 1")) / len(self.data) + up_up = self.data.query( + "x > 1 & y > 1") + up_down = self.data.query( + "x > 1 & y < -1") + down_up = self.data.query( + "x < -1 & y > 1") + down_down = self.data.query( + "x < -1 & y < -1") + if isinstance(grouping, (list, tuple)): + try: + (_, colour) = group2colour + except (ValueError, TypeError): + colour = "black" + select_ingroup = pd.Index(grouping).intersection + ingroup_up_up = " (\\textcolor{%s}{%d})" % ( + colour, + len(up_up.loc[select_ingroup(up_up.index)]),) + ingroup_up_down = " (\\textcolor{%s}{%d})" % ( + colour, + len(up_down.loc[select_ingroup(up_down.index)])) + ingroup_down_up = " (\\textcolor{%s}{%d})" % ( + colour, + len(down_up.loc[select_ingroup(down_up.index)])) + ingroup_down_down = " (\\textcolor{%s}{%d})" % ( + colour, + len(down_down.loc[select_ingroup(down_down.index)])) + else: + ingroup_up_up = "" + ingroup_up_down = "" + ingroup_down_up = "" + ingroup_down_down = "" + axis.annotate( + f"{len(up_up)}{ingroup_up_up}", + xy=(0.95, 0.95), xycoords="axes fraction", + size="x-small", color=line_style["color"], + horizontalalignment="right", + verticalalignment="top") + axis.annotate( + f"{len(up_down)}{ingroup_up_down}", + xy=(0.95, 0.05), xycoords="axes fraction", + size="x-small", color=line_style["color"], + horizontalalignment="right", + verticalalignment="bottom") + axis.annotate( + f"{len(down_up)}{ingroup_down_up}", + xy=(0.05, 0.95), xycoords="axes fraction", + size="x-small", color=line_style["color"], + horizontalalignment="left", + verticalalignment="top") + axis.annotate( + f"{len(down_down)}{ingroup_down_down}", + xy=(0.05, 0.05), xycoords="axes fraction", + size="x-small", color=line_style["color"], + horizontalalignment="left", + verticalalignment="bottom") axis.set_xlabel(self.x_label, fontsize=17) axis.set_ylabel(self.y_label, fontsize=17) # This doesn't work with plt.axis("equal") @@ -307,7 +310,7 @@ class Scatterplot: return plotting_function def save_plot(self, outfile, - grouping=None, group2colour=None, + annotate_folds=True, grouping=None, group2colour=None, **kwargs): """Creates the plotting function and transmits it for execution to the function that really does the saving.""" @@ -318,10 +321,14 @@ class Scatterplot: # equal_axes = False # else: # equal_axes = True - equal_axes = True + if annotate_folds: + equal_axes = True + else: + equal_axes = False save_plot( outfile, self.plot_maker( + annotate_folds, grouping=grouping, group2colour=group2colour, **kwargs), equal_axes=equal_axes, tight=True) @@ -407,6 +414,12 @@ def main(): # "-t", "--transform", # help="log2, log10, or a linear scale to apply.", # default=0) + parser.add_argument( + "--not_foldchanges", + help="Use this option to inactivate plotting options for " + "log2FoldChange.", + default=False, + action="store_true") parser.add_argument( "--plot_regression", help="Use this option to plot the regression line.", @@ -476,6 +489,7 @@ def main(): plot_data.save_plot( # args.x_axis, args.y_axis, out_pdf, + annotate_folds=not args.not_foldchanges, grouping=gene_list, group2colour=(list_name, args.colour), x_range=args.data_range, y_range=args.data_range, @@ -489,6 +503,7 @@ def main(): plot_data.save_plot( # args.x_axis, args.y_axis, out_pdf, + annotate_folds=not args.not_foldchanges, x_range=args.data_range, y_range=args.data_range, regression=args.plot_regression)