def __init__(self, width, height, ipewriter, basename): self.width = width self.height = height self.writer = XMLWriter(ipewriter) self.basename = basename RendererBase.__init__(self) # use same latex as Ipe (default is xelatex) rcParams['pgf.texsystem'] = "pdflatex" self.latexManager = None if rcParams.get("ipe.textsize", False): self.latexManager = LatexManagerFactory.get_latex_manager() self._start_id = self.writer.start(u'ipe', version=u"70005", creator="matplotlib") pre = rcParams.get('ipe.preamble', "") if pre <> "": self.writer.start(u'preamble') self.writer.data(pre) self.writer.end(indent=False) sheet = rcParams.get('ipe.stylesheet', "") if sheet <> "": self.writer.insertSheet(sheet) self.writer.start(u'ipestyle', name=u"opacity") for i in range(10, 100, 10): self.writer.element(u'opacity', name=u'%02d%%' % i, value=u'%g' % (i / 100.0)) self.writer.end() self.writer.start(u'page')
def __init__(self, width, height, ipewriter, basename): self.width = width self.height = height self.writer = XMLWriter(ipewriter) self.basename = basename RendererBase.__init__(self) # use same latex as Ipe (default is xelatex) rcParams['pgf.texsystem'] = "pdflatex" self.latexManager = None if rcParams.get("ipe.textsize", False): self.latexManager = LatexManagerFactory.get_latex_manager() self._start_id = self.writer.start( u'ipe', version=u"70005", creator="matplotlib") pre = rcParams.get('ipe.preamble', "") if pre != "": self.writer.start(u'preamble') self.writer.data(pre) self.writer.end(indent=False) sheet = rcParams.get('ipe.stylesheet', "") if sheet != "": self.writer.insertSheet(sheet) self.writer.start(u'ipestyle', name=u"opacity") for i in range(10,100,10): self.writer.element(u'opacity', name=u'%02d%%'% i, value=u'%g'% (i/100.0)) self.writer.end() self.writer.start(u'page')
def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, **kwargs): # adir identifies which axes this is self.adir = adir # data and viewing intervals for this direction self.d_interval = d_intervalx self.v_interval = v_intervalx # This is a temporary member variable. # Do not depend on this existing in future releases! self._axinfo = self._AXINFO[adir].copy() if rcParams['_internal.classic_mode']: self._axinfo.update({'label': {'va': 'center', 'ha': 'center'}, 'tick': {'inward_factor': 0.2, 'outward_factor': 0.1, 'linewidth': rcParams['lines.linewidth'], 'color': 'k'}, 'axisline': {'linewidth': 0.75, 'color': (0, 0, 0, 1)}, 'grid' : {'color': (0.9, 0.9, 0.9, 1), 'linewidth': 1.0, 'linestyle': '-'}, }) else: self._axinfo.update({'label' : {'va': 'center', 'ha': 'center'}, 'tick' : {'inward_factor': 0.2, 'outward_factor': 0.1, 'linewidth': rcParams.get( adir + 'tick.major.width', rcParams['xtick.major.width']), 'color': rcParams.get( adir + 'tick.color', rcParams['xtick.color'])}, 'axisline': {'linewidth': rcParams['axes.linewidth'], 'color': rcParams['axes.edgecolor']}, 'grid' : {'color': rcParams['grid.color'], 'linewidth': rcParams['grid.linewidth'], 'linestyle': rcParams['grid.linestyle']}, }) maxis.XAxis.__init__(self, axes, *args, **kwargs) self.set_rotate_label(kwargs.get('rotate_label', None))
def __init__(self, ticksize=None, tick_out=None, **kwargs): if ticksize is None: ticksize = rcParams['xtick.major.size'] self.set_ticksize(ticksize) self.set_tick_out(rcParams.get('xtick.direction', 'in') == 'out') self.clear() line2d_kwargs = {'color': rcParams['xtick.color'], # For the linewidth we need to set a default since old versions of # matplotlib don't have this. 'linewidth': rcParams.get('xtick.major.width', 1)} line2d_kwargs.update(kwargs) Line2D.__init__(self, [0.], [0.], **line2d_kwargs) self.set_visible_axes('all') self._display_minor_ticks = False
def get_gwpy_tex_settings(): """Return a dict of rcParams similar to GWPY_TEX_RCPARAMS Returns ------- rcParams : `dict` a dictionary of matplotlib rcParams """ # custom GW-DetChar formatting params = { 'font.size': 10, 'xtick.labelsize': 18, 'ytick.labelsize': 18, 'axes.labelsize': 20, 'axes.titlesize': 24, 'grid.alpha': 0.5, } if has_tex() and bool_env("GWPY_USETEX", True): params.update({ 'text.usetex': True, 'text.latex.preamble': (rcParams.get('text.latex.preamble', []) + GWPY_TEX_MACROS), 'font.family': ['serif'], 'axes.formatter.use_mathtext': False, }) return params
def __init__(self, ticksize=None, tick_out=None, **kwargs): if ticksize is None: ticksize = rcParams["xtick.major.size"] self.set_ticksize(ticksize) self.set_tick_out(rcParams.get("xtick.direction", "in") == "out") self.clear() line2d_kwargs = { "color": rcParams["xtick.color"], # For the linewidth we need to set a default since old versions of # matplotlib don't have this. "linewidth": rcParams.get("xtick.major.width", 1), } line2d_kwargs.update(kwargs) Line2D.__init__(self, [0.0], [0.0], **line2d_kwargs) self.set_visible_axes("all") self._display_minor_ticks = False
def as_species(name, leave_path=False): """Cleans up a filename into a species name, italicizing it in latex.""" #trim extension if present dot_location = name.rfind('.') if dot_location > -1: name = name[:dot_location] #get rid of _small if present -- used for debugging if name.endswith('_small'): name = name[:-len('_small')] if name.endswith('_codon_usage'): name = name[:-len('_codon_usage')] #get rid of path unless told to leave it name = split(name)[-1] #replace underscores with spaces name = name.replace('_', ' ') #make sure the first letter of the genus is caps, and not the first letter #of the species fields = name.split() fields[0] = fields[0].title() #assume second field is species name if len(fields) > 1: fields[1] = fields[1].lower() binomial = ' '.join(fields) if rcParams.get('text.usetex'): binomial = r'\emph{' + binomial + '}' return binomial
def get_gwpy_tex_settings(): """Return a dict of rcParams similar to GWPY_TEX_RCPARAMS Returns ------- rcParams : `dict` a dictionary of matplotlib rcParams """ # custom GW-DetChar formatting params = { 'font.size': 10, 'xtick.labelsize': 18, 'ytick.labelsize': 18, 'axes.labelsize': 20, 'axes.titlesize': 24, 'grid.alpha': 0.5, } if has_tex() and bool_env("GWPY_USETEX", True): params.update({ 'text.usetex': True, 'text.latex.preamble': ( rcParams.get('text.latex.preamble', []) + GWPY_TEX_MACROS), 'font.family': ['serif'], 'axes.formatter.use_mathtext': False, }) return params
def print_jpg(self, filename_or_obj, *args, **kwargs): """ Supported kwargs: *quality*: The image quality, on a scale from 1 (worst) to 95 (best). The default is 95, if not given in the matplotlibrc file in the savefig.jpeg_quality parameter. Values above 95 should be avoided; 100 completely disables the JPEG quantization stage. *optimize*: If present, indicates that the encoder should make an extra pass over the image in order to select optimal encoder settings. *progressive*: If present, indicates that this image should be stored as a progressive JPEG file. """ buf, size = self.print_to_buffer() if kwargs.pop("dryrun", False): return # The image is "pasted" onto a white background image to safely # handle any transparency image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1) rgba = mcolors.to_rgba(rcParams.get('savefig.facecolor', 'white')) color = tuple([int(x * 255.0) for x in rgba[:3]]) background = Image.new('RGB', size, color) background.paste(image, image) options = restrict_dict(kwargs, ['quality', 'optimize', 'progressive']) if 'quality' not in options: options['quality'] = rcParams['savefig.jpeg_quality'] return background.save(filename_or_obj, format='jpeg', **options)
def get_latex_manager(): texcommand = get_texcommand() latex_header = LatexManager._build_latex_header() prev = LatexManagerFactory.previous_instance # check if the previous instance of LatexManager can be reused if prev and prev.latex_header == latex_header and prev.texcommand == texcommand: if rcParams.get("pgf.debug", False): print("reusing LatexManager") return prev else: if rcParams.get("pgf.debug", False): print("creating LatexManager") new_inst = LatexManager() LatexManagerFactory.previous_instance = new_inst return new_inst
def print_jpg(self, filename_or_obj, *args, **kwargs): """ Supported kwargs: *quality*: The image quality, on a scale from 1 (worst) to 95 (best). The default is 95, if not given in the matplotlibrc file in the savefig.jpeg_quality parameter. Values above 95 should be avoided; 100 completely disables the JPEG quantization stage. *optimize*: If present, indicates that the encoder should make an extra pass over the image in order to select optimal encoder settings. *progressive*: If present, indicates that this image should be stored as a progressive JPEG file. """ buf, size = self.print_to_buffer() if kwargs.pop("dryrun", False): return # The image is "pasted" onto a white background image to safely # handle any transparency image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1) color = mcolors.colorConverter.to_rgb( rcParams.get('savefig.facecolor', 'white')) color = tuple([int(x * 255.0) for x in color]) background = Image.new('RGB', size, color) background.paste(image, image) options = restrict_dict(kwargs, ['quality', 'optimize', 'progressive']) if 'quality' not in options: options['quality'] = rcParams['savefig.jpeg_quality'] return background.save(filename_or_obj, format='jpeg', **options)
def plot_nullclines(vecfld, lw=3, background=None, save_show_or_return='return', save_kwargs={}, ax=None): """Plot nullclines stored in the VectorField2D class. Arguments --------- vecfld: :class:`~VectorField2D` An instance of the VectorField2D class which presumably has fixed points computed and stored. lw: `float` (default: 3) The linewidth of the nullcline. background: `str` or None (default: None) The background color of the plot. save_show_or_return: {'show', 'save', 'return'} (default: `return`) Whether to save, show or return the figure. save_kwargs: `dict` (default: `{}`) A dictionary that will passed to the save_fig function. By default it is an empty dictionary and the save_fig function will use the {"path": None, "prefix": 'plot_nullclines', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} as its parameters. Otherwise you can provide a dictionary that properly modify those keys according to your needs. ax: :class:`~matplotlib.axes.Axes` The matplotlib axes used for plotting. Default is to use the current axis. """ from matplotlib import rcParams from matplotlib.colors import to_hex if background is None: _background = rcParams.get("figure.facecolor") _background = to_hex(_background) if type(_background) is tuple else _background else: _background = background if _background in ["#ffffff", "black"]: colors = ["#189e1a", "#1f77b4"] else: colors = ["#189e1a", "#1f77b4"] if ax is None: ax = plt.gca() for ncx in vecfld.NCx: ax.plot(*ncx.T, c=colors[0], lw=lw) for ncy in vecfld.NCy: ax.plot(*ncy.T, c=colors[1], lw=lw) if save_show_or_return == "save": s_kwargs = {"path": None, "prefix": 'plot_nullclines', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} s_kwargs = update_dict(s_kwargs, save_kwargs) save_fig(**s_kwargs) elif save_show_or_return == "show": plt.tight_layout() plt.show() elif save_show_or_return == "return": return ax
def get_filechooser(self): fc = FileChooserDialog( title='Save the figure', parent=self.win, path=os.path.expanduser(rcParams.get('savefig.directory', '')), filetypes=self.canvas.get_supported_filetypes(), default_filetype=self.canvas.get_default_filetype()) fc.set_current_name(self.canvas.get_default_filename()) return fc
def get_filechooser(self): fc = FileChooserDialog( title='Save the figure', parent=self.figure.canvas.manager.window, path=os.path.expanduser(rcParams.get('savefig.directory', '')), filetypes=self.figure.canvas.get_supported_filetypes(), default_filetype=self.figure.canvas.get_default_filetype()) fc.set_current_name(self.figure.canvas.get_default_filename()) return fc
def __init__(self, ax, label, bar_length, **props): ''' Draw a horizontal bar with the size in data coordinate of the give axes. A label will be drawn above (center-aligned). ''' label_size = props['label_size'] if 'label_size' in props else \ rcParams.get('scalebar.label_size', 16) label_family = props['label_family'] if 'label_family' in props else \ rcParams.get('scalebar.label_family', 'sans-serif') label_color = props['label_color'] if 'label_color' in props else \ rcParams.get('scalebar.label_color', 'black') location = props['location'] if 'location' in props else \ rcParams.get('scalebar.location', 4) padding = props['padding'] if 'padding' in props else \ rcParams.get('scalebar.padding', 0.5) sep = props['sep'] if 'sep' in props else \ rcParams.get('scalebar.sep', 2) bar_color = props['bar_color'] if 'bar_color' in props else \ rcParams.get('scalebar.bar_color', 'black') bar_width = props['bar_width'] if 'bar_width' in props else \ rcParams.get('scalebar.bar_width', 0.1) bar_length = props['bar_length'] if 'bar_length' in props else \ rcParams.get('scalebar.bar_length', 0.8) frameon = False prop = None self.scale_bar = AuxTransformBox(ax.transData) rect = mpatches.Rectangle((0, 0), bar_length, bar_width, linewidth=0, edgecolor=None, facecolor=bar_color) self.scale_bar.add_artist(rect) textprops = {'size': label_size} self.txt_label = TextArea(label, textprops=textprops, minimumdescent=False) self._box = VPacker(children=[self.txt_label, self.scale_bar], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, location, pad=padding, borderpad=0, child=self._box, prop=prop, frameon=frameon)
def get_filechooser(self): fc = FileChooserDialog( title="Save the figure", parent=self.win, path=os.path.expanduser(rcParams.get("savefig.directory", "")), filetypes=self.canvas.get_supported_filetypes(), default_filetype=self.canvas.get_default_filetype(), ) fc.set_current_name(self.canvas.get_default_filename()) return fc
def __init__(self, parent_axes=None, parent_map=None, transform=None, coord_index=None, coord_type='scalar', coord_unit=None, coord_wrap=None, frame=None): # Keep a reference to the parent axes and the transform self.parent_axes = parent_axes self.parent_map = parent_map self.transform = transform self.coord_index = coord_index self.coord_unit = coord_unit self.frame = frame self.set_coord_type(coord_type, coord_wrap) # Initialize ticks self.dpi_transform = Affine2D() self.offset_transform = ScaledTranslation(0, 0, self.dpi_transform) self.ticks = Ticks(transform=parent_axes.transData + self.offset_transform) # Initialize tick labels self.ticklabels = TickLabels(self.frame, transform=None, # display coordinates figure=parent_axes.get_figure()) self.ticks.display_minor_ticks(False) self.minor_frequency = 5 # Initialize axis labels self.axislabels = AxisLabels(self.frame, transform=None, # display coordinates figure=parent_axes.get_figure()) # Initialize container for the grid lines self.grid_lines = [] # Initialize grid style. Take defaults from matplotlib.rcParams. # Based on matplotlib.axis.YTick._get_gridline. # # Matplotlib's gridlines use Line2D, but ours use PathPatch. # Patches take a slightly different format of linestyle argument. lines_to_patches_linestyle = { '-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted', 'none': 'none', 'None': 'none', ' ': 'none', '': 'none' } self.grid_lines_kwargs = {'visible': False, 'facecolor': 'none', 'edgecolor': rcParams['grid.color'], 'linestyle': lines_to_patches_linestyle[rcParams['grid.linestyle']], 'linewidth': rcParams['grid.linewidth'], 'alpha': rcParams.get('grid.alpha', 1.0), 'transform': self.parent_axes.transData}
def __init__(self, parent_axes=None, parent_map=None, transform=None, coord_index=None, coord_type='scalar', coord_unit=None, coord_wrap=None, frame=None): # Keep a reference to the parent axes and the transform self.parent_axes = parent_axes self.parent_map = parent_map self.transform = transform self.coord_index = coord_index self.coord_unit = coord_unit self.frame = frame self.set_coord_type(coord_type, coord_wrap) # Initialize ticks self.dpi_transform = Affine2D() self.offset_transform = ScaledTranslation(0, 0, self.dpi_transform) self.ticks = Ticks(transform=parent_axes.transData + self.offset_transform) # Initialize tick labels self.ticklabels = TickLabels(self.frame, transform=None, # display coordinates figure=parent_axes.get_figure()) self.ticks.display_minor_ticks(False) self.minor_frequency = 5 # Initialize axis labels self.axislabels = AxisLabels(self.frame, transform=None, # display coordinates figure=parent_axes.get_figure()) # Initialize container for the grid lines self.grid_lines = [] # Initialize grid style. Take defaults from matplotlib.rcParams. # Based on matplotlib.axis.YTick._get_gridline. # # Matplotlib's gridlines use Line2D, but ours use PathPatch. # Patches take a slightly different format of linestyle argument. lines_to_patches_linestyle = {'-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted', 'none': 'none', 'None': 'none', ' ': 'none', '': 'none'} self.grid_lines_kwargs = {'visible': False, 'facecolor': 'none', 'edgecolor': rcParams['grid.color'], 'linestyle': lines_to_patches_linestyle[rcParams['grid.linestyle']], 'linewidth': rcParams['grid.linewidth'], 'alpha': rcParams.get('grid.alpha', 1.0), 'transform': self.parent_axes.transData}
def add_label_unit(self, unit, axis='x'): label = getattr(self, 'get_%slabel' % axis)() if not label: label = unit.__doc__ if rcParams.get("text.usetex", False): unitstr = tex.unit_to_latex(unit) else: unitstr = unit.to_string() set_ = getattr(self, 'set_%slabel' % axis) if label: set_("%s [%s]" % (label, unitstr)) else: set_(unitstr)
def __del__(self): if rcParams.get("pgf.debug", False): print "deleting LatexManager" try: self.latex.terminate() self.latex.wait() except: pass try: os.remove("texput.log") os.remove("texput.aux") except: pass
def __del__(self): if rcParams.get("pgf.debug", False): print "deleting LatexManager" try: self.latex_stdin_utf8.close() self.latex.communicate() except: pass try: os.remove("texput.log") os.remove("texput.aux") except: pass
def save_figure(self, *args): fname, format = self.get_filechooser().get_filename_from_user() if fname: startpath = os.path.expanduser(rcParams.get('savefig.directory', '')) if startpath == '': # explicitly missing key or empty str signals to use cwd rcParams['savefig.directory'] = startpath else: # save dir for next time rcParams['savefig.directory'] = os.path.dirname(unicode(fname)) try: self.canvas.print_figure(fname, format=format) except Exception as e: error_msg_gtk(str(e), parent=self)
def __init__(self): # store references for __del__ self._os_path = os.path self._shutil = shutil self._debug = rcParams.get("pgf.debug", False) # create a tmp directory for running latex, remember to cleanup self.tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_lm_") LatexManager._unclean_instances.add(self) # test the LaTeX setup to ensure a clean startup of the subprocess self.texcommand = get_texcommand() self.latex_header = LatexManager._build_latex_header() latex_end = "\n\\makeatletter\n\\@@end\n" try: latex = subprocess.Popen([self.texcommand, "-halt-on-error"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=self.tmpdir) except OSError as e: if e.errno == errno.ENOENT: raise RuntimeError( "Latex command not found. " "Install '%s' or change pgf.texsystem to the desired command." % self.texcommand) else: raise RuntimeError("Error starting process '%s'" % self.texcommand) test_input = self.latex_header + latex_end stdout, stderr = latex.communicate(test_input.encode("utf-8")) if latex.returncode != 0: raise LatexError( "LaTeX returned an error, probably missing font or error in preamble:\n%s" % stdout) # open LaTeX process for real work latex = subprocess.Popen([self.texcommand, "-halt-on-error"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=self.tmpdir) self.latex = latex self.latex_stdin_utf8 = codecs.getwriter("utf8")(self.latex.stdin) # write header with 'pgf_backend_query_start' token self._stdin_writeln(self._build_latex_header()) # read all lines until our 'pgf_backend_query_start' token appears self._expect("*pgf_backend_query_start") self._expect_prompt() # cache for strings already processed self.str_cache = {}
def save_figure(self, *args): chooser = self.get_filechooser() fname, format = chooser.get_filename_from_user() chooser.destroy() if fname: startpath = os.path.expanduser(rcParams.get("savefig.directory", "")) if startpath == "": # explicitly missing key or empty str signals to use cwd rcParams["savefig.directory"] = startpath else: # save dir for next time rcParams["savefig.directory"] = os.path.dirname(six.text_type(fname)) try: self.canvas.print_figure(fname, format=format) except Exception as e: error_msg_gtk(str(e), parent=self)
def __init__(self): # store references for __del__ self._os_path = os.path self._shutil = shutil self._debug = rcParams.get("pgf.debug", False) # create a tmp directory for running latex, remember to cleanup self.tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_lm_") LatexManager._unclean_instances.add(self) # test the LaTeX setup to ensure a clean startup of the subprocess self.texcommand = get_texcommand() self.latex_header = LatexManager._build_latex_header() latex_end = "\n\\makeatletter\n\\@@end\n" try: latex = subprocess.Popen([self.texcommand, "-halt-on-error"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=self.tmpdir) except OSError as e: if e.errno == errno.ENOENT: raise RuntimeError("Latex command not found. " "Install '%s' or change pgf.texsystem to the desired command." % self.texcommand ) else: raise RuntimeError("Error starting process '%s'" % self.texcommand) test_input = self.latex_header + latex_end stdout, stderr = latex.communicate(test_input.encode("utf-8")) if latex.returncode != 0: raise LatexError("LaTeX returned an error, probably missing font or error in preamble:\n%s" % stdout) # open LaTeX process for real work latex = subprocess.Popen([self.texcommand, "-halt-on-error"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=self.tmpdir) self.latex = latex self.latex_stdin_utf8 = codecs.getwriter("utf8")(self.latex.stdin) # write header with 'pgf_backend_query_start' token self._stdin_writeln(self._build_latex_header()) # read all lines until our 'pgf_backend_query_start' token appears self._expect("*pgf_backend_query_start") self._expect_prompt() # cache for strings already processed self.str_cache = {}
def trigger(self, *args, **kwargs): chooser = self.get_filechooser() fname, format_ = chooser.get_filename_from_user() chooser.destroy() if fname: startpath = os.path.expanduser( rcParams.get('savefig.directory', '')) if startpath == '': # explicitly missing key or empty str signals to use cwd rcParams['savefig.directory'] = startpath else: # save dir for next time rcParams['savefig.directory'] = os.path.dirname( six.text_type(fname)) try: self.figure.canvas.print_figure(fname, format=format_) except Exception as e: error_msg_gtk(str(e), parent=self)
def get_fontspec(): latex_fontspec = [] texcommand = get_texcommand() if texcommand is not "pdflatex": latex_fontspec.append(r"\usepackage{fontspec}") if texcommand is not "pdflatex" and rcParams.get("pgf.rcfonts", True): # try to find fonts from rc parameters families = ["serif", "sans-serif", "monospace"] fontspecs = [r"\setmainfont{%s}", r"\setsansfont{%s}", r"\setmonofont{%s}"] for family, fontspec in zip(families, fontspecs): matches = [f for f in rcParams["font."+family] if f in system_fonts] if matches: latex_fontspec.append(fontspec % matches[0]) else: pass # no fonts found, fallback to LaTeX defaule return "\n".join(latex_fontspec)
def plot_data(ax, data, labels, idx, change_marker): """ Actual plotting """ color = get_color(idx) marker_color = get_color(idx, True) if "Model" in data.columns: color = get_color(idx/2) marker_color = get_color(idx/2, True) ax.plot(data["S"], data["Model"], marker=get_marker(idx, change_marker), markersize=rcParams.get("lines.markersize") * 0.6, color=ps.change_color_brightness(color, 0.2), markeredgecolor=ps.change_color_brightness(marker_color, 0.2), label=labels[idx]) idx += 1 ax.errorbar(data["S"], data["Value"], yerr=data["Error"], fmt=get_marker(idx, change_marker), color=color, markeredgecolor=marker_color, label=labels[idx])
def hist(self, x, *args, **kwargs): x = numpy.asarray(x) # re-format weights as array if given as float weights = kwargs.get('weights', None) if isinstance(weights, Number): kwargs['weights'] = numpy.ones_like(x) * weights # calculate log-spaced bins on-the-fly if ( kwargs.pop('logbins', False) and not numpy.iterable(kwargs.get('bins', None)) ): nbins = kwargs.get('bins', None) or rcParams.get('hist.bins', 30) # get range hrange = kwargs.pop('range', None) if hrange is None: try: hrange = numpy.min(x), numpy.max(x) except ValueError as exc: if str(exc).startswith('zero-size array'): # no data exc.args = ('cannot generate log-spaced histogram ' 'bins for zero-size array, ' 'please pass `bins` or `range` manually',) raise # log-scale the axis and extract the base if kwargs.get('orientation') == 'horizontal': self.set_yscale('log', nonpositive='clip') logbase = self.yaxis._scale.base else: self.set_xscale('log', nonpositive='clip') logbase = self.xaxis._scale.base # generate the bins kwargs['bins'] = numpy.logspace( log(hrange[0], logbase), log(hrange[1], logbase), nbins+1, endpoint=True) return super().hist(x, *args, **kwargs)
def plot_data(ax, data, labels, idx, change_marker): """ Actual plotting """ color = get_color(idx) marker_color = get_color(idx, True) if "Model" in data.columns: color = get_color(idx / 2) marker_color = get_color(idx / 2, True) ax.plot(data["S"], data["Model"], marker=get_marker(idx, change_marker), markersize=rcParams.get("lines.markersize") * 0.6, color=ps.change_color_brightness(color, 0.2), markeredgecolor=ps.change_color_brightness(marker_color, 0.2), label=labels[idx]) idx += 1 ax.errorbar(data["S"], data["Value"], yerr=data["Error"], fmt=get_marker(idx, change_marker), color=color, markeredgecolor=marker_color, label=labels[idx])
def hist(self, x, *args, **kwargs): x = numpy.asarray(x) # re-format weights as array if given as float weights = kwargs.get('weights', None) if isinstance(weights, Number): kwargs['weights'] = numpy.ones_like(x) * weights # calculate log-spaced bins on-the-fly if (kwargs.pop('logbins', False) and not numpy.iterable(kwargs.get('bins', None))): nbins = kwargs.get('bins', None) or rcParams.get('hist.bins', 30) # get range hrange = kwargs.pop('range', None) if hrange is None: try: hrange = numpy.min(x), numpy.max(x) except ValueError as exc: if str(exc).startswith('zero-size array'): # no data exc.args = ('cannot generate log-spaced histogram ' 'bins for zero-size array, ' 'please pass `bins` or `range` manually',) raise # log-scale the axis and extract the base if kwargs.get('orientation') == 'horizontal': self.set_yscale('log', nonposy='clip') logbase = self.yaxis._scale.base else: self.set_xscale('log', nonposx='clip') logbase = self.xaxis._scale.base # generate the bins kwargs['bins'] = numpy.logspace( log(hrange[0], logbase), log(hrange[1], logbase), nbins+1, endpoint=True) return super(Axes, self).hist(x, *args, **kwargs)
def _get_value(attr, default): value = getattr(self, attr) if value is None: value = rcParams.get('colorbar.' + attr, default) return value
def __del__(self): if rcParams.get("pgf.debug", False): print("deleting LatexManager") self._cleanup()
def get_taylor_diagram_options(*args,**kwargs): ''' Get optional arguments for taylor_diagram function. Retrieves the optional arguments supplied to the TAYLOR_DIAGRAM function as a variable-length input argument list (*ARGS), and returns the values in an OPTION dictionary. Default values are assigned to selected optional arguments. The function will terminate with an error if an unrecognized optional argument is supplied. INPUTS: *kwargs : variable-length keyword argument list. The keywords by definition are dictionaries with keys that must correspond to one choices given in OUTPUTS below. OUTPUTS: option : dictionary containing option values. (Refer to display_taylor_diagram_options function for more information.) option['alpha'] : blending of symbol face color (0.0 transparent through 1.0 opaque). (Default : 1.0) option['axismax'] : maximum for the radial contours option['checkstats'] : Check input statistics satisfy Taylor relationship (Default : 'off') option['cmapzdata'] : data values to use for color mapping of markers, e.g. RMSD or BIAS. (Default empty) option['colcor'] : color for correlation coefficient labels (Default : blue) option['colobs'] : color for observation labels (Default : magenta) option['colrms'] : color for RMS labels (Default : medium green) option['colstd'] : color for STD labels (Default : black) option['colormap'] : 'on'/'off' switch to map color shading of markers to CMapZData values ('on') or min to max range of CMapZData values ('off'). (Default : 'on') option['locationcolorbar'] : location for the colorbar, 'NorthOutside' or 'EastOutside' option['markercolor'] : single color to use for all markers (Default: red) option['markerdisplayed'] : markers to use for individual experiments option['markerlabel'] : name of the experiment to use for marker option['markerlabelcolor']: marker label color (Default : 'k') option['markerlegend'] : 'on'/'off' switch to display marker legend (Default 'off') option['markerobs' ] : marker to use for x-axis indicating observed STD. A choice of 'none' will suppress appearance of marker. (Default 'none') option['markersize'] : marker size (Default 10) option['numberpanels'] : Number of panels to display = 1 for positive correlations = 2 for positive and negative correlations (Default value depends on correlations (CORs)) option['overlay'] : 'on'/'off' switch to overlay current statistics on Taylor diagram (Default 'off') Only markers will be displayed. option['rincrms'] : axis tick increment for RMS values option['rincstd'] : axis tick increment for STD values option['rmslabelformat'] : string format for RMS contour labels, e.g. '0:.2f'. (Default '0', format as specified by str function) option['showlabelscor'] : show correlation coefficient labels (Default: 'on') option['showlabelsrms'] : show RMS labels (Default: 'on') option['showlabelsstd'] : show STD labels (Default: 'on') option['stylecor'] : line style for correlation coefficient grid lines (Default: dash-dot '-.') option['styleobs'] : line style for observation grid line. A choice of empty string '' will suppress appearance of the grid line (Default: '') option['stylerms'] : line style for RMS grid lines (Default: dash '--') option['stylestd'] : line style for STD grid lines (Default: dotted ':') option['tickcor'][panel]: tick values for correlation coefficients for two types of panels option['tickrms'] : RMS values to plot grid circles from observation point option['tickstd'] : STD values to plot grid circles from origin option['tickrmsangle'] : tick RMS angle (Default: 135 degrees) option['titleColorBar'] : title for the colorbar option['titlecor'] : show correlation coefficient axis label (Default: 'on') option['titleobs'] : label for observation point (Default: '') option['titlerms'] : show RMS axis label (Default: 'on') option['titlestd'] : show STD axis label (Default: 'on') option['widthcor'] : linewidth for correlation coefficient grid lines (Default: .8) option['widthobs'] : linewidth for observation grid line (Default: .8) option['widthrms'] : linewidth for RMS grid lines (Default: .8) option['widthstd'] : linewidth for STD grid lines (Default: .8) Author: Peter A. Rochford Symplectic, LLC www.thesymplectic.com [email protected] Created on Nov 25, 2016 Revised on Apr 22, 2017 ''' from skill_metrics import check_on_off from matplotlib import rcParams CORs = args[0] nargin = len(kwargs) # Set default parameters for all options option = {} option['alpha'] = 1.0 option['axismax'] = 0.0 option['bias'] = [] option['checkstats'] = 'off' option['cmapzdata'] = [] option['colcor'] = (0, 0, 1) # blue option['colobs'] = 'm' # magenta option['colrms'] = (0, .6, 0) # medium green option['colstd'] = (0, 0, 0) # black option['colormap'] = 'on' option['locationcolorbar'] = 'NorthOutside' option['markercolor'] = 'r' option['markerdisplayed'] = 'marker' option['markerlabel'] = '' option['markerlabelcolor'] = 'k' option['markerlegend'] = 'off' option['markerobs'] = 'none' option['markersize'] = 10 negative = CORs[np.where(CORs < 0.0)] if len(negative) > 0: option['numberpanels'] = 2 # double panel else: option['numberpanels'] = 1 # single panel option['overlay'] = 'off' option['rincrms'] = [] option['rincstd'] = [] option['rmslabelformat'] = '0' option['showlabelscor'] = 'on' option['showlabelsrms'] = 'on' option['showlabelsstd'] = 'on' option['stylecor'] = '-.' option['styleobs'] = '' option['stylerms'] = '--' option['stylestd'] = ':' # Note that "0" must be explicitly given or a scientific number is # stored tickval1 = [1, 0.99, 0.95, 0] middle = np.linspace(0.9, 0.1, 9) tickval1[3:3] = middle tickval2 = tickval1[:] values = np.linspace(-0.1,-0.9,9) tickval2.extend(values) tickval2.extend([-0.95, -0.99, -1]) option['tickcor'] = (tickval1, tickval2) # store as tuple option['tickrms'] = [] option['tickstd'] = [] option['tickrmsangle'] = -1 option['titlecolorbar'] = '' option['titlecor'] = 'on' option['titleobs'] = '' option['titlerms'] = 'on' option['titlestd'] = 'on' lineWidth = rcParams.get('lines.linewidth') option['widthcor'] = lineWidth option['widthobs'] = lineWidth option['widthrms'] = lineWidth option['widthstd'] = lineWidth if nargin == 0: # No options requested, so return with only defaults return option # Check for valid keys and values in dictionary for optname, optvalue in kwargs.items(): optname = optname.lower() if optname == 'nonrmsdz': raise ValueError('nonrmsdz is an obsolete option. Use cmapzdata instead.') if not optname in option: raise ValueError('Unrecognized option: ' + optname) else: # Replace option value with that from arguments if optname == 'tickcor': list1 = option['tickcor'][0] list2 = option['tickcor'][1] if option['numberpanels'] == 1: list1 = optvalue else: list2 = optvalue option['tickcor'] = (list1, list2) else: option[optname] = optvalue # Check values for specific options if optname == 'checkstats': option['checkstats'] = check_on_off(option['checkstats']) elif optname == 'cmapzdata': if isinstance(option[optname], str): raise ValueError('cmapzdata cannot be a string!') elif isinstance(option[optname], bool): raise ValueError('cmapzdata cannot be a boolean!') option['cmapzdata'] = optvalue elif optname == 'markerlabel': if not type(optvalue) is list: raise ValueError('Option value is not a list: ' + str(optvalue)) option['markerlabel'] = optvalue[1:] elif optname == 'markerlegend': option['markerlegend'] = check_on_off(option['markerlegend']) elif optname == 'overlay': option['overlay'] = check_on_off(option['overlay']) elif optname == 'rmslabelformat': # Check for valid string format labelFormat = '{' + optvalue + '}' try: labelFormat.format(99.0) except ValueError: raise ValueError('Invalid string format for rmslabelformat: ' + optvalue) elif optname == 'showlabelscor': option['showlabelscor'] = check_on_off(option['showlabelscor']) elif optname == 'showlabelsrms': option['showlabelsrms'] = check_on_off(option['showlabelsrms']) elif optname == 'showlabelsstd': option['showlabelsstd'] = check_on_off(option['showlabelsstd']) elif optname == 'tickrms': option['tickrms'] = np.sort(optvalue) option['rincrms'] = (max(option['tickrms']) - \ min(option['tickrms']))/ \ len(option['tickrms']) elif optname == 'tickstd': option['tickstd'] = np.sort(optvalue) option['rincstd'] = (max(option['tickstd']) - \ min(option['tickstd']))/ \ len(option['tickstd']) elif optname == 'titlecor': option['titlecor'] = check_on_off(option['titlecor']) elif optname == 'titlerms': option['titlerms'] = check_on_off(option['titlerms']) elif optname == 'titlestd': option['titlestd'] = check_on_off(option['titlestd']) return option
def plot_pattern_diagram_colorbar(X,Y,Z,option): ''' Plots color markers on a pattern diagram shaded according to a supplied value. Values are indicated via a color bar on the plot. Plots color markers on a target diagram according their (X,Y) locations. The color shading is accomplished by plotting the markers as a scatter plot in (X,Y) with the colors of each point specified using Z as a vector. The color range is controlled by option['cmapzdata']. option['colormap'] = 'on' : the scatter function maps the elements in Z to colors in the current colormap option['colormap']= 'off' : the color axis is mapped to the range [min(Z) max(Z)] option.locationColorBar : location for the colorbar, 'NorthOutside' or 'eastoutside' The color bar is titled using the content of option['titleColorBar'] (if non-empty string). INPUTS: x : x-coordinates of markers y : y-coordinates of markers z : z-coordinates of markers (used for color shading) option : dictionary containing option values. option['colormap'] : 'on'/'off' switch to map color shading of markers to colormap ('on') or min to max range of Z values ('off'). option['titleColorBar'] : title for the color bar OUTPUTS: None. Created on Nov 30, 2016 Revised on Jan 1, 2019 Author: Peter A. Rochford Symplectic, LLC www.thesymplectic.com [email protected] ''' ''' Plot color shaded data points using scatter plot Keyword s defines marker size in points^2 c defines the sequence of numbers to be mapped to colors using the cmap and norm ''' fontSize = rcParams.get('font.size') cxscale = fontSize/10 # scale color bar by font size markerSize = option['markersize']**2 hp = plt.scatter(X,Y, s=markerSize, c=Z, marker = 'd') hp.set_facecolor(hp.get_edgecolor()) for i in range(len(X)): # Check if marker labels provided if type(option['markerlabel']) is list: # Label marker xlim = plt.gca().get_xlim()[1] offset = 0.02*xlim xtextpos = X[i] - offset ytextpos = Y[i] + offset plt.text(xtextpos,ytextpos,option['markerlabel'][i], color = option['markerlabelcolor'], verticalalignment = 'bottom', horizontalalignment = 'right', fontsize = fontSize) # Set parameters for color bar location location = option['locationcolorbar'].lower() xscale= 1.0 labelpad = -25 if location == 'northoutside': orientation = 'horizontal' aspect = 6 fraction = 0.04 elif location == 'eastoutside': orientation = 'vertical' aspect = 25 fraction = 0.15 if 'checkstats' in option: # Taylor diagram xscale = 0.5 cxscale = 6*fontSize/10 labelpad = -30 else: raise ValueError('Invalid color bar location: ' + option['locationcolorbar']); # Add color bar to plot if option['colormap'] == 'on': # map color shading of markers to colormap hc = plt.colorbar(orientation = orientation, aspect = aspect, fraction = fraction, pad=0.06) # Limit number of ticks on color bar to reasonable number if orientation == 'horizontal': _setColorBarTicks(hc,5,20) elif option['colormap'] == 'off': # map color shading of markers to min to max range of Z values if len(Z) > 1: plt.clim(min(Z), max(Z)) hc = plt.colorbar(orientation = orientation, aspect = aspect, fraction = fraction, pad=0.06, ticks=[min(Z), max(Z)]) # Label just min/max range hc.set_ticklabels(['Min.', 'Max.']) else: raise ValueError('Invalid option for option.colormap: ' + option['colormap']); if orientation == 'horizontal': location = _getColorBarLocation(hc, option, xscale = xscale, yscale = 7.5, cxscale = cxscale) else: location = _getColorBarLocation(hc, option, xscale = xscale, yscale = 1.0, cxscale = cxscale) hc.ax.set_position(location) # set new position hc.ax.tick_params(labelsize=fontSize) # set tick label size hc.ax.xaxis.set_ticks_position('top') hc.ax.xaxis.set_label_position('top') # Title the color bar if option['titlecolorbar']: if orientation == 'horizontal': hc.set_label(option['titlecolorbar'],fontsize=fontSize) else: hc.set_label(option['titlecolorbar'],fontsize=fontSize, labelpad=labelpad, y=1.05, rotation=0) else: hc.set_label(hc,'Color Scale',fontsize=fontSize)
def grid_vectors( adata: AnnData, basis: str = "umap", x: int = 0, y: int = 1, color: Union[str, List[str]] = "ntr", layer: str = "X", highlights: Optional[list] = None, labels: Optional[list] = None, values: Optional[list] = None, theme: Optional[str] = None, cmap: Optional[str] = None, color_key: Union[dict, list] = None, color_key_cmap: Optional[str] = None, background: Optional[str] = "white", ncols: int = 4, pointsize: Union[None, float] = None, figsize: tuple = (6, 4), show_legend="on data", use_smoothed: bool = True, ax: Optional[Axes] = None, sort: str = "raw", aggregate: Optional[str] = None, show_arrowed_spines: bool = False, inverse: bool = False, cell_inds: Union[str, list] = "all", method: str = "gaussian", xy_grid_nums: list = [50, 50], cut_off_velocity: bool = True, quiver_size: Optional[float] = None, quiver_length: Optional[float] = None, vector: str = "velocity", frontier: bool = False, save_show_or_return: str = "show", save_kwargs: dict = {}, s_kwargs_dict: dict = {}, q_kwargs_dict: dict = {}, **grid_kwargs, ): """Plot the velocity or acceleration vector of each cell on a grid. Parameters ---------- %(scatters.parameters.no_show_legend|kwargs|save_kwargs)s inverse: `bool` (default: False) Whether to inverse the direction of the velocity vectors. cell_inds: `str` or `list` (default: all) the cell index that will be chosen to draw velocity vectors. Can be a list of integers (cell integer indices) or str (Cell names). method: `str` (default: `SparseVFC`) Method to reconstruct the vector field. Currently it supports either SparseVFC (default) or the empirical method Gaussian kernel method from RNA velocity (Gaussian). xy_grid_nums: `tuple` (default: (50, 50)) the number of grids in either x or y axis. cut_off_velocity: `bool` (default: True) Whether to remove small velocity vectors from the recovered the vector field grid, either through the simple Gaussian kernel (applicable to 2D) or the powerful sparseVFC approach. quiver_size: `float` or None (default: None) The size of quiver. If None, we will use set quiver_size to be 1. Note that quiver quiver_size is used to calculate the head_width (10 x quiver_size), head_length (12 x quiver_size) and headaxislength (8 x quiver_size) of the quiver. This is done via the `default_quiver_args` function which also calculate the scale of the quiver (1 / quiver_length). quiver_length: `float` or None (default: None) The length of quiver. The quiver length which will be used to calculate scale of quiver. Note that befoe applying `default_quiver_args` velocity values are first rescaled via the quiver_autoscaler function. Scale of quiver indicates the nuumber of data units per arrow length unit, e.g., m/s per plot width; a smaller scale parameter makes the arrow longer. vector: `str` (default: `velocity`) Which vector type will be used for plotting, one of {'velocity', 'acceleration'} or either velocity field or acceleration field will be plotted. frontier: `bool` (default: `False`) Whether to add the frontier. Scatter plots can be enhanced by using transparency (alpha) in order to show area of high density and multiple scatter plots can be used to delineate a frontier. See matplotlib tips & tricks cheatsheet (https://github.com/matplotlib/cheatsheets). Originally inspired by figures from scEU-seq paper: https://science.sciencemag.org/content/367/6482/1151. save_kwargs: `dict` (default: `{}`) A dictionary that will passed to the save_fig function. By default it is an empty dictionary and the save_fig function will use the {"path": None, "prefix": 'grid_velocity', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} as its parameters. Otherwise you can provide a dictionary that properly modify those keys according to your needs. s_kwargs_dict: `dict` (default: {}) The dictionary of the scatter arguments. q_kwargs_dict: `dict` (default: {}) The dictionary of the quiver arguments. grid_kwargs: Additional parameters that will be passed to velocity_on_grid function. Returns ------- Nothing but a quiver plot on the grid. """ import matplotlib.pyplot as plt from matplotlib import rcParams from matplotlib.colors import to_hex if type(x) == str and type(y) == str: if len(adata.var_names[adata.var.use_for_dynamics].intersection( [x, y])) != 2: raise ValueError( "If you want to plot the vector flow of two genes, please make sure those two genes " "belongs to dynamics genes or .var.use_for_dynamics is True.") X = adata[:, [x, y]].layers["M_s"].A V = adata[:, [x, y]].layers["velocity_S"].A else: if ("X_" + basis in adata.obsm.keys()) and (vector + "_" + basis in adata.obsm.keys()): X = adata.obsm["X_" + basis][:, [x, y]] V = adata.obsm[vector + "_" + basis][:, [x, y]] else: if "X_" + basis not in adata.obsm.keys(): layer, basis = basis.split("_") reduceDimension(adata, layer=layer, reduction_method=basis) if "kmc" not in adata.uns_keys(): cell_velocities(adata, vkey="velocity_S", basis=basis) X = adata.obsm["X_" + basis][:, [x, y]] V = adata.obsm[vector + "_" + basis][:, [x, y]] else: kmc = adata.uns["kmc"] X = adata.obsm["X_" + basis][:, [x, y]] V = kmc.compute_density_corrected_drift(X, kmc.Idx, normalize_vector=True) adata.obsm[vector + "_" + basis] = V X, V = X.copy(), V.copy() if cell_inds == "all": ix_choice = np.arange(adata.shape[0]) elif cell_inds == "random": ix_choice = np.random.choice(np.range(adata.shape[0]), size=1000, replace=False) elif type(cell_inds) is int: ix_choice = np.random.choice(np.range(adata.shape[0]), size=cell_inds, replace=False) elif type(cell_inds) is list: if type(cell_inds[0]) is str: cell_inds = [adata.obs_names.to_list().index(i) for i in cell_inds] ix_choice = cell_inds X, V = X[ix_choice, :], V[ix_choice, :] # 0, 0 grid_kwargs_dict = { "density": None, "smooth": None, "n_neighbors": None, "min_mass": None, "autoscale": False, "adjust_for_stream": True, "V_threshold": None, } grid_kwargs_dict = update_dict(grid_kwargs_dict, grid_kwargs) if method.lower() == "sparsevfc": if "VecFld_" + basis not in adata.uns.keys(): VectorField(adata, basis=basis, dims=[x, y]) X_grid, V_grid = ( adata.uns["VecFld_" + basis]["grid"], adata.uns["VecFld_" + basis]["grid_V"], ) N = int(np.sqrt(V_grid.shape[0])) if cut_off_velocity: X_grid, p_mass, neighs, weight = prepare_velocity_grid_data( X, xy_grid_nums, density=grid_kwargs_dict["density"], smooth=grid_kwargs_dict["smooth"], n_neighbors=grid_kwargs_dict["n_neighbors"], ) for i in ["density", "smooth", "n_neighbors"]: grid_kwargs_dict.pop(i) VecFld, func = vecfld_from_adata(adata, basis) V_emb = func(X) V_grid = (V_emb[neighs] * weight[:, :, None]).sum(1) / np.maximum( 1, p_mass)[:, None] X_grid, V_grid = grid_velocity_filter( V_emb=V, neighs=neighs, p_mass=p_mass, X_grid=X_grid, V_grid=V_grid, **grid_kwargs_dict, ) else: X_grid, V_grid = ( np.array([np.unique(X_grid[:, 0]), np.unique(X_grid[:, 1])]), np.array([ V_grid[:, 0].reshape((N, N)), V_grid[:, 1].reshape((N, N)) ]), ) elif method.lower() == "gaussian": X_grid, V_grid, D = velocity_on_grid( X, V, xy_grid_nums, cut_off_velocity=cut_off_velocity, **grid_kwargs_dict, ) elif "grid_velocity_" + basis in adata.uns.keys(): X_grid, V_grid, _ = ( adata.uns["grid_velocity_" + basis]["VecFld"]["X_grid"], adata.uns["grid_velocity_" + basis]["VecFld"]["V_grid"], adata.uns["grid_velocity_" + basis]["VecFld"]["D"], ) else: raise Exception( "Vector field learning method {} is not supported or the grid velocity is collected for " "the current adata object.".format(method)) V_grid /= 3 * quiver_autoscaler(X_grid, V_grid) if inverse: V_grid = -V_grid if background is None: _background = rcParams.get("figure.facecolor") background = to_hex( _background) if type(_background) is tuple else _background if quiver_size is None: quiver_size = 1 if background == "black": edgecolors = "white" else: edgecolors = "black" head_w, head_l, ax_l, scale = default_quiver_args(quiver_size, quiver_length) quiver_kwargs = { "angles": "xy", "scale": scale, "scale_units": "xy", "width": 0.0005, "headwidth": head_w, "headlength": head_l, "headaxislength": ax_l, "minshaft": 1, "minlength": 1, "pivot": "tail", "edgecolors": edgecolors, "linewidth": 0.2, "facecolors": edgecolors, "color": edgecolors, "alpha": 1, "zorder": 3, } quiver_kwargs = update_dict(quiver_kwargs, q_kwargs_dict) # if ax is None: # plt.figure(facecolor=background) axes_list, _, font_color = scatters( adata=adata, basis=basis, x=x, y=y, color=color, layer=layer, highlights=highlights, labels=labels, values=values, theme=theme, cmap=cmap, color_key=color_key, color_key_cmap=color_key_cmap, background=background, ncols=ncols, pointsize=pointsize, figsize=figsize, show_legend=show_legend, use_smoothed=use_smoothed, aggregate=aggregate, show_arrowed_spines=show_arrowed_spines, ax=ax, sort=sort, save_show_or_return="return", frontier=frontier, **s_kwargs_dict, return_all=True, ) if type(axes_list) == list: for i in range(len(axes_list)): axes_list[i].quiver(X_grid[0], X_grid[1], V_grid[0], V_grid[1], **quiver_kwargs) axes_list[i].set_facecolor(background) else: axes_list.quiver(X_grid[0], X_grid[1], V_grid[0], V_grid[1], **quiver_kwargs) axes_list.set_facecolor(background) if save_show_or_return == "save": s_kwargs = { "path": None, "prefix": "grid_velocity", "dpi": None, "ext": "pdf", "transparent": True, "close": True, "verbose": True, } s_kwargs = update_dict(s_kwargs, save_kwargs) save_fig(**s_kwargs) elif save_show_or_return == "show": plt.tight_layout() plt.show() elif save_show_or_return == "return": return axes_list
def plot_taylor_axes(axes, cax, option): ''' Plot axes for Taylor diagram. Plots the x & y axes for a Taylor diagram using the information provided in the AXES dictionary returned by the GET_TAYLOR_DIAGRAM_AXES function. INPUTS: axes : data structure containing axes information for Taylor diagram cax : handle for plot axes option : data structure containing option values. (Refer to GET_TAYLOR_DIAGRAM_OPTIONS function for more information.) option['colcor'] : CORs grid and tick labels color (Default: blue) option['colrms'] : RMS grid and tick labels color (Default: green) option['colstd'] : STD grid and tick labels color (Default: black) option['labelrms'] : RMS axis label, e.g. 'RMSD' option['numberpanels'] : number of panels (quadrants) to use for Taylor diagram option['tickrms'] : RMS values to plot gridding circles from observation point option['titlecor'] : title for CORRELATION axis option['titlerms'] : title for RMS axis option['titlestd'] : title for STD axis OUTPUTS: ax: returns a list of handles of axis labels Author: Peter A. Rochford Acorn Science & Innovation [email protected] Created on Dec 3, 2016 Revised on Dec 31, 2018 Author: Peter A. Rochford Symplectic, LLC www.thesymplectic.com [email protected] ''' ax = [] axlabweight = 'bold' fontSize = rcParams.get('font.size') + 2 lineWidth = rcParams.get('lines.linewidth') if option['numberpanels'] == 1: # Single panel if option['titlestd'] == 'on': handle = plt.ylabel('Standard Deviation', color=option['colstd'], fontweight=axlabweight, fontsize=fontSize) ax.append(handle) if option['titlecor'] == 'on': pos1 = 45 DA = 15 lab = 'Correlation Coefficient' c = np.fliplr([np.linspace(pos1 - DA, pos1 + DA, len(lab))])[0] dd = 1.1 * axes['rmax'] for ii, ith in enumerate(c): handle = plt.text(dd * np.cos(ith * np.pi / 180), dd * np.sin(ith * np.pi / 180), lab[ii]) handle.set(rotation=ith - 90, color=option['colcor'], horizontalalignment='center', verticalalignment='bottom', fontsize=fontSize, fontweight=axlabweight) ax.append(handle) if option['titlerms'] == 'on': lab = option['labelrms'] pos1 = option['titlermsdangle'] DA = 10 c = np.fliplr([np.linspace(pos1 - DA, pos1 + DA, len(lab))])[0] if option['tickrms'][0] > 0: dd = 0.8 * option['tickrms'][0] + 0.2 * option['tickrms'][1] else: dd = 0.8 * option['tickrms'][1] + 0.2 * option['tickrms'][2] # Adjust spacing of label letters if on too small an arc posFraction = dd / axes['rmax'] if posFraction < 0.35: DA = 2 * DA c = np.fliplr([np.linspace(pos1 - DA, pos1 + DA, len(lab))])[0] # Write label in a circular arc for ii, ith in enumerate(c): xtextpos = axes['dx'] + dd * np.cos(ith * np.pi / 180) ytextpos = dd * np.sin(ith * np.pi / 180) handle = plt.text(xtextpos, ytextpos, lab[ii]) handle.set(rotation=ith - 90, color=option['colrms'], horizontalalignment='center', verticalalignment='top', fontsize=fontSize, fontweight=axlabweight) ax.append(handle) else: # Double panel if option['titlestd'] == 'on': handle = plt.xlabel('Standard Deviation', color=option['colstd'], fontweight=axlabweight, fontsize=fontSize) ax.append(handle) if option['titlecor'] == 'on': pos1 = 90 DA = 25 lab = 'Correlation Coefficient' c = np.fliplr([np.linspace(pos1 - DA, pos1 + DA, len(lab))])[0] dd = 1.1 * axes['rmax'] # Write label in a circular arc for ii, ith in enumerate(c): handle = plt.text(dd * np.cos(ith * np.pi / 180), dd * np.sin(ith * np.pi / 180), lab[ii]) handle.set(rotation=ith - 90, color=option['colcor'], horizontalalignment='center', verticalalignment='bottom', fontsize=fontSize, fontweight=axlabweight) ax.append(handle) if option['titlerms'] == 'on': lab = option['labelrms'] pos1 = option['titlermsdangle'] DA = 10 c = np.fliplr([np.linspace(pos1 - DA, pos1 + DA, len(lab))])[0] if option['tickrms'][0] > 0: dd = 0.7 * option['tickrms'][0] + 0.3 * option['tickrms'][1] else: dd = 0.7 * option['tickrms'][1] + 0.3 * option['tickrms'][2] # Adjust spacing of label letters if on too small an arc posFraction = dd / axes['rmax'] if posFraction < 0.35: DA = 2 * DA c = np.fliplr([np.linspace(pos1 - DA, pos1 + DA, len(lab))])[0] for ii, ith in enumerate(c): xtextpos = axes['dx'] + dd * np.cos(ith * np.pi / 180) ytextpos = dd * np.sin(ith * np.pi / 180) handle = plt.text(xtextpos, ytextpos, lab[ii]) handle.set(rotation=ith - 90, color=option['colrms'], horizontalalignment='center', verticalalignment='bottom', fontsize=fontSize, fontweight=axlabweight) ax.append(handle) # Set color of tick labels to that specified for STD contours plt.gca().tick_params(axis='x', colors=option['colstd']) plt.gca().tick_params(axis='y', colors=option['colstd']) # VARIOUS ADJUSTMENTS TO THE PLOT: cax.set_aspect('equal') plt.box(on=None) # set axes limits, set ticks, and draw axes lines if option['numberpanels'] == 2: xtick = [-option['tickstd'], option['tickstd']] xtick = np.concatenate((-option['tickstd'][1:], option['tickstd']), axis=None) xtick = np.sort(xtick) plt.xticks(xtick) axislim = [axes['rmax'] * x for x in [-1, 1, 0, 1]] plt.axis(axislim) plt.plot([-axes['rmax'], axes['rmax']], [0, 0], color=axes['tc'], linewidth=lineWidth + 1) plt.plot([0, 0], [0, axes['rmax']], color=axes['tc']) # hide y-axis line plt.gca().axes.get_yaxis().set_visible(False) else: ytick, ylab = plt.yticks() ytick = list(filter(lambda x: x >= 0 and x <= axes['rmax'], ytick)) axislim = [axes['rmax'] * x for x in [0, 1, 0, 1]] plt.axis(axislim) plt.xticks(ytick) plt.yticks(ytick) plt.plot([0, axes['rmax']], [0, 0], color=axes['tc'], linewidth=lineWidth + 2) plt.plot([0, 0], [0, axes['rmax']], color=axes['tc'], linewidth=lineWidth + 1) return ax
def get_texcommand(): """Get chosen TeX system from rc.""" texsystem_options = ["xelatex", "lualatex", "pdflatex"] texsystem = rcParams.get("pgf.texsystem", "xelatex") return texsystem if texsystem in texsystem_options else "xelatex"
'figure.subplot.top': 0.90, 'xtick.labelsize': 16, 'ytick.labelsize': 16, 'axes.labelsize': 24, 'axes.labelpad': 2, 'axes.titlesize': 24, 'grid.color': 'gray', 'grid.alpha': 0.5, }) if has_tex(): rcParams.update({ # reproduce GWPY_TEX_RCPARAMS 'text.usetex': True, 'text.latex.preamble': ( rcParams.get('text.latex.preamble', []) + GWPY_TEX_MACROS), 'font.family': ['serif'], 'font.size': 10, 'axes.formatter.use_mathtext': False, }) SHOW_HIDE_JAVASCRIPT = """ <script type="text/ecmascript"> <![CDATA[ function init(evt) { if ( window.svgDocument == null ) { svgDocument = evt.target.ownerDocument; } }
def get_texcommand(): texsystem_options = ["xelatex", "lualatex", "pdflatex"] texsystem = rcParams.get("pgf.texsystem", "xelatex") return texsystem if texsystem in texsystem_options else "xelatex"
# set parameters only supported in matplotlib >= 1.5 # https://matplotlib.org/1.5.1/users/whats_new.html#configuration-rcparams try: GWPY_RCPARAMS.update({ 'axes.labelpad': 5, 'legend.edgecolor': 'inherit', }) except KeyError: # matplotlib < 1.5 pass # set latex options GWPY_TEX_RCPARAMS = RcParams(**{ # use latex styling 'text.usetex': True, 'text.latex.preamble': ( rcParams.get('text.latex.preamble', []) + tex.MACROS), # use bigger font for labels (since the font is good) 'font.family': ['serif'], 'font.size': 16, # don't use mathtext for offset 'axes.formatter.use_mathtext': False, }) if mpl_version < '2.0': GWPY_TEX_RCPARAMS['font.serif'] = ['Computer Modern'] if mpl_version < '1.3': # really old matplotlib stored font.family as a str, not a list GWPY_RCPARAMS['font.family'] = GWPY_RCPARAMS['font.family'][0] GWPY_TEX_RCPARAMS['font.family'] = GWPY_TEX_RCPARAMS['font.family'][0]
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if not self.get_mappable(): return # Get parameters from matplotlib import rcParams # late import cmap = self.mappable.get_cmap() array = self.mappable.get_array() label = self.label orientation = self.orientation or \ rcParams.get('colorbar.orientation', 'vertical') nbins = self.nbins or rcParams.get('colorbar.nbins', 50) length_fraction = self.length_fraction or \ rcParams.get('colorbar.length_fraction', 0.2) width_fraction = self.width_fraction or \ rcParams.get('colorbar.width_fraction', 0.01) location = self.location or \ self._LOCATIONS[rcParams.get('colorbar.location', 'upper right')] pad = self.pad or rcParams.get('colorbar.pad', 0.2) border_pad = self.border_pad or \ rcParams.get('colorbar.border_pad', 0.1) sep = self.sep or rcParams.get('colorbar.sep', 5) frameon = self.frameon or rcParams.get('colorbar.frameon', True) color = self.color or rcParams.get('colorbar.color', 'k') box_color = self.box_color or rcParams.get('colorbar.box_color', 'w') box_alpha = self.box_alpha or rcParams.get('colorbar.box_alpha', 1.0) font_properties = self.font_properties ticks = self.ticks ticklabels = self.ticklabels ax = self.axes children = [] # Create colorbar colorbarbox = AuxTransformBox(ax.transData) xlim, ylim = ax.get_xlim(), ax.get_ylim() if orientation == 'horizontal': length = abs(xlim[1] - xlim[0]) * length_fraction width = abs(ylim[1] - ylim[0]) * width_fraction else: length = abs(ylim[1] - ylim[0]) * length_fraction width = abs(xlim[1] - xlim[0]) * width_fraction step_length = length / nbins patches = [] for x in np.arange(0, length, step_length): if orientation == 'horizontal': patch = Rectangle((x, 0), step_length, width) else: patch = Rectangle((0, x), width, step_length) patches.append(patch) values = np.linspace(np.min(array), np.max(array), nbins) minvalue, maxvalue = values[0], values[-1] col = PatchCollection(patches, cmap=cmap, edgecolors='none') col.set_array(values) colorbarbox.add_artist(col) if orientation == 'horizontal': patch = Rectangle((0, 0), length, width, fill=False, ec=color) else: patch = Rectangle((0, 0), width, length, fill=False, ec=color) colorbarbox.add_artist(patch) children.append(colorbarbox) # Create ticks tickbox = AuxTransformBox(ax.transData) if ticks is None: ticks = [minvalue, maxvalue] # default if not ticklabels: ticklabels = ticks[:] # tick label by default if minvalue not in ticks: # little hack to get right layout position ticks.append(minvalue) ticklabels.append('') # no label for this extra tick if maxvalue not in ticks: # little hack to get right layout position ticks.append(maxvalue) ticklabels.append('') # no label for this extra tick for itick, tick in enumerate(ticks): if tick > maxvalue or tick < minvalue: continue # ignore it # Fraction of colorbar depending of min and max values of colorbar a = 1 / (maxvalue - minvalue) b = -a * minvalue tickfrac = a * tick + b if orientation == 'horizontal': tickx = tickfrac * length ticky = 0 ha = 'center' va = 'top' else: tickx = width ticky = tickfrac * length ha = 'left' va = 'center' ticktext = Text(tickx, ticky, ticklabels[itick], color=color, fontproperties=font_properties, horizontalalignment=ha, verticalalignment=va) tickbox.add_artist(ticktext) children.append(tickbox) # Create label if label: labelbox = AuxTransformBox(ax.transData) va = 'baseline' if orientation == 'horizontal' else 'center' text = Text(0, 0, label, fontproperties=font_properties, verticalalignment=va, rotation=orientation) labelbox.add_artist(text) children.insert(0, labelbox) # Create final offset box Packer = VPacker if orientation == 'horizontal' else HPacker child = Packer(children=children, align="center", pad=0, sep=sep) box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
def get_preamble(): latex_preamble = rcParams.get("pgf.preamble", "") if type(latex_preamble) == list: latex_preamble = "\n".join(latex_preamble) return latex_preamble
def cell_wise_vectors( adata, basis="umap", x=0, y=1, color='ntr', layer="X", highlights=None, labels=None, values=None, theme=None, cmap=None, color_key=None, color_key_cmap=None, background='white', ncols=4, pointsize=None, figsize=(6, 4), show_legend='on data', use_smoothed=True, ax=None, sort='raw', aggregate=None, show_arrowed_spines=True, inverse=False, cell_ind="all", quiver_size=None, quiver_length=None, vector='velocity', frontier=False, save_show_or_return='show', save_kwargs={}, s_kwargs_dict={}, **cell_wise_kwargs, ): """Plot the velocity or acceleration vector of each cell. Parameters ---------- %(scatters.parameters.no_show_legend|kwargs|save_kwargs)s inverse: `bool` (default: False) Whether to inverse the direction of the velocity vectors. cell_ind: `str` or `list` (default: all) the cell index that will be chosen to draw velocity vectors. quiver_size: `float` or None (default: None) The size of quiver. If None, we will use set quiver_size to be 1. Note that quiver quiver_size is used to calculate the head_width (10 x quiver_size), head_length (12 x quiver_size) and headaxislength (8 x quiver_size) of the quiver. This is done via the `default_quiver_args` function which also calculate the scale of the quiver (1 / quiver_length). quiver_length: `float` or None (default: None) The length of quiver. The quiver length which will be used to calculate scale of quiver. Note that befoe applying `default_quiver_args` velocity values are first rescaled via the quiver_autoscaler function. Scale of quiver indicates the nuumber of data units per arrow length unit, e.g., m/s per plot width; a smaller scale parameter makes the arrow longer. vector: `str` (default: `velocity`) Which vector type will be used for plotting, one of {'velocity', 'acceleration'} or either velocity field or acceleration field will be plotted. frontier: `bool` (default: `False`) Whether to add the frontier. Scatter plots can be enhanced by using transparency (alpha) in order to show area of high density and multiple scatter plots can be used to delineate a frontier. See matplotlib tips & tricks cheatsheet (https://github.com/matplotlib/cheatsheets). Originally inspired by figures from scEU-seq paper: https://science.sciencemag.org/content/367/6482/1151. save_kwargs: `dict` (default: `{}`) A dictionary that will passed to the save_fig function. By default it is an empty dictionary and the save_fig function will use the {"path": None, "prefix": 'cell_wise_velocity', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} as its parameters. Otherwise you can provide a dictionary that properly modify those keys according to your needs. s_kwargs_dict: `dict` (default: {}) The dictionary of the scatter arguments. cell_wise_kwargs: Additional parameters that will be passed to plt.quiver function Returns ------- Nothing but a cell wise quiver plot. """ import matplotlib.pyplot as plt from matplotlib import rcParams from matplotlib.colors import to_hex if type(x) == str and type(y) == str: if len(adata.var_names[adata.var.use_for_dynamics].intersection([x, y])) != 2: raise ValueError(f'If you want to plot the vector flow of two genes, please make sure those two genes ' f'belongs to dynamics genes or .var.use_for_dynamics is True.') X = adata[:, [x, y]].layers['M_s'].A V = adata[:, [x, y]].layers['velocity_S'].A else: if ("X_" + basis in adata.obsm.keys()) and ( vector + "_" + basis in adata.obsm.keys() ): X = adata.obsm["X_" + basis][:, [x, y]] V = adata.obsm[vector + "_" + basis][:, [x, y]] else: if "X_" + basis not in adata.obsm.keys(): layer, basis = basis.split("_") reduceDimension(adata, layer=layer, reduction_method=basis) if "kmc" not in adata.uns_keys(): cell_velocities(adata, vkey="velocity_S", basis=basis) X = adata.obsm["X_" + basis][:, [x, y]] V = adata.obsm[vector + "_" + basis][:, [x, y]] else: kmc = adata.uns["kmc"] X = adata.obsm["X_" + basis][:, [x, y]] V = kmc.compute_density_corrected_drift(X, kmc.Idx, normalize_vector=True) adata.obsm[vector + "_" + basis] = V V /= 3 * quiver_autoscaler(X, V) if inverse: V = -V df = pd.DataFrame({"x": X[:, 0], "y": X[:, 1], "u": V[:, 0], "v": V[:, 1]}) if background is None: _background = rcParams.get("figure.facecolor") background = to_hex(_background) if type(_background) is tuple else _background if quiver_size is None: quiver_size = 1 if background == "black": edgecolors = "white" else: edgecolors = "black" head_w, head_l, ax_l, scale = default_quiver_args(quiver_size, quiver_length) # quiver_kwargs = { "angles": "xy", "scale": scale, "scale_units": "xy", "width": 0.0005, "headwidth": head_w, "headlength": head_l, "headaxislength": ax_l, "minshaft": 1, "minlength": 1, "pivot": "tail", "linewidth": 0.1, "edgecolors": edgecolors, "alpha": 1, "zorder": 10, } quiver_kwargs = update_dict(quiver_kwargs, cell_wise_kwargs) # if ax is None: # plt.figure(facecolor=background) axes_list, color_list, _ = scatters( adata=adata, basis=basis, x=x, y=y, color=color, layer=layer, highlights=highlights, labels=labels, values=values, theme=theme, cmap=cmap, color_key=color_key, color_key_cmap=color_key_cmap, background=background, ncols=ncols, pointsize=pointsize, figsize=figsize, show_legend=show_legend, use_smoothed=use_smoothed, aggregate=aggregate, show_arrowed_spines=show_arrowed_spines, ax=ax, sort=sort, save_show_or_return="return", frontier=frontier, **s_kwargs_dict, return_all=True, ) if cell_ind == "all": ix_choice = np.arange(adata.shape[0]) elif cell_ind == "random": ix_choice = np.random.choice(np.range(adata.shape[0]), size=1000, replace=False) elif type(cell_ind) is int: ix_choice = np.random.choice( np.range(adata.shape[0]), size=cell_ind, replace=False ) elif type(cell_ind) is list: ix_choice = cell_ind if type(axes_list) == list: for i in range(len(axes_list)): axes_list[i].quiver( df.iloc[ix_choice, 0], df.iloc[ix_choice, 1], df.iloc[ix_choice, 2], df.iloc[ix_choice, 3], color=color_list[i], facecolors=color_list[i], **quiver_kwargs, ) axes_list[i].set_facecolor(background) else: axes_list.quiver( df.iloc[ix_choice, 0], df.iloc[ix_choice, 1], df.iloc[ix_choice, 2], df.iloc[ix_choice, 3], color=color_list, facecolors=color_list, **quiver_kwargs, ) axes_list.set_facecolor(background) if save_show_or_return == "save": s_kwargs = {"path": None, "prefix": 'cell_wise_vector', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} s_kwargs = update_dict(s_kwargs, save_kwargs) save_fig(**s_kwargs) elif save_show_or_return == "show": plt.tight_layout() plt.show() elif save_show_or_return == "return": return axes_list
def get_preamble(): """Get LaTeX preamble from rc.""" latex_preamble = rcParams.get("pgf.preamble", "") if type(latex_preamble) == list: latex_preamble = "\n".join(latex_preamble) return latex_preamble
def streamline_plot( adata, basis="umap", x=0, y=1, color='ntr', layer="X", highlights=None, labels=None, values=None, theme=None, cmap=None, color_key=None, color_key_cmap=None, background='white', ncols=4, pointsize=None, figsize=(6, 4), show_legend='on data', use_smoothed=True, ax=None, sort='raw', aggregate=None, show_arrowed_spines=True, inverse=False, method="gaussian", xy_grid_nums=[50, 50], cut_off_velocity=True, density=1, linewidth=1, streamline_alpha=1, vector='velocity', frontier=False, save_show_or_return='show', save_kwargs={}, s_kwargs_dict={}, **streamline_kwargs, ): """Plot the velocity vector of each cell. Parameters ---------- %(scatters.parameters.no_show_legend|kwargs|save_kwargs)s inverse: `bool` (default: False) Whether to inverse the direction of the velocity vectors. method: `str` (default: `SparseVFC`) Method to reconstruct the vector field. Currently it supports either SparseVFC (default) or the empirical method Gaussian kernel method from RNA velocity (Gaussian). xy_grid_nums: `tuple` (default: (50, 50)) the number of grids in either x or y axis. cut_off_velocity: `bool` (default: True) Whether to remove small velocity vectors from the recovered the vector field grid, either through the simple Gaussian kernel (applicable only to 2D) or the powerful sparseVFC approach. density: `float` or None (default: 1) density of the plt.streamplot function. linewidth: `float` or None (default: 1) multiplier of automatically calculated linewidth passed to the plt.streamplot function. streamline_alpha: `float` or None (default: 1) The alpha value applied to the vector field stream lines. vector: `str` (default: `velocity`) Which vector type will be used for plotting, one of {'velocity', 'acceleration'} or either velocity field or acceleration field will be plotted. frontier: `bool` (default: `False`) Whether to add the frontier. Scatter plots can be enhanced by using transparency (alpha) in order to show area of high density and multiple scatter plots can be used to delineate a frontier. See matplotlib tips & tricks cheatsheet (https://github.com/matplotlib/cheatsheets). Originally inspired by figures from scEU-seq paper: https://science.sciencemag.org/content/367/6482/1151. save_kwargs: `dict` (default: `{}`) A dictionary that will passed to the save_fig function. By default it is an empty dictionary and the save_fig function will use the {"path": None, "prefix": 'streamline_plot', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} as its parameters. Otherwise you can provide a dictionary that properly modify those keys according to your needs. s_kwargs_dict: `dict` (default: {}) The dictionary of the scatter arguments. streamline_kwargs: Additional parameters that will be passed to plt.streamplot function Returns ------- Nothing but a streamline plot that integrates paths in the vector field. """ import matplotlib.pyplot as plt from matplotlib import rcParams from matplotlib.colors import to_hex if type(x) == str and type(y) == str: if len(adata.var_names[adata.var.use_for_dynamics].intersection([x, y])) != 2: raise ValueError(f'If you want to plot the vector flow of two genes, please make sure those two genes ' f'belongs to dynamics genes or .var.use_for_dynamics is True.') X = adata[:, [x, y]].layers['M_s'].A V = adata[:, [x, y]].layers['velocity_S'].A else: if ("X_" + basis in adata.obsm.keys()) and ( vector + "_" + basis in adata.obsm.keys() ): X = adata.obsm["X_" + basis][:, [x, y]] V = adata.obsm[vector + '_' + basis][:, [x, y]] else: if "X_" + basis not in adata.obsm.keys(): layer, basis = basis.split("_") reduceDimension(adata, layer=layer, reduction_method=basis) if "kmc" not in adata.uns_keys(): cell_velocities(adata, vkey="velocity_S", basis=basis) X = adata.obsm["X_" + basis][:, [x, y]] V = adata.obsm[vector + '_' + basis][:, [x, y]] else: kmc = adata.uns["kmc"] X = adata.obsm["X_" + basis][:, [x, y]] V = kmc.compute_density_corrected_drift(X, kmc.Idx, normalize_vector=True) adata.obsm[vector + '_' + basis] = V grid_kwargs_dict = { "density": None, "smooth": None, "n_neighbors": None, "min_mass": None, "autoscale": False, "adjust_for_stream": True, "V_threshold": None, } grid_kwargs_dict = update_dict(grid_kwargs_dict, streamline_kwargs) if method.lower() == "sparsevfc": if "VecFld_" + basis not in adata.uns.keys(): VectorField(adata, basis=basis, dims=[x, y]) X_grid, V_grid = ( adata.uns["VecFld_" + basis]["VecFld"]["grid"], adata.uns["VecFld_" + basis]["VecFld"]["grid_V"], ) N = int(np.sqrt(V_grid.shape[0])) if cut_off_velocity: X_grid, p_mass, neighs, weight = prepare_velocity_grid_data(X, xy_grid_nums, density=grid_kwargs_dict['density'], smooth=grid_kwargs_dict['smooth'], n_neighbors=grid_kwargs_dict['n_neighbors'], ) for i in ['density', 'smooth', 'n_neighbors']: grid_kwargs_dict.pop(i) VecFld, func = vecfld_from_adata(adata, basis) V_emb = func(X) V_grid = (V_emb[neighs] * weight[:, :, None]).sum(1) / np.maximum(1, p_mass)[:, None] X_grid, V_grid = grid_velocity_filter( V_emb=V, neighs=neighs, p_mass=p_mass, X_grid=X_grid, V_grid=V_grid, **grid_kwargs_dict ) else: X_grid, V_grid = ( np.array([np.unique(X_grid[:, 0]), np.unique(X_grid[:, 1])]), np.array([V_grid[:, 0].reshape((N, N)), V_grid[:, 1].reshape((N, N))]), ) elif method.lower() == "gaussian": X_grid, V_grid, D = velocity_on_grid( X, V, xy_grid_nums, cut_off_velocity=cut_off_velocity, **grid_kwargs_dict ) elif "grid_velocity_" + basis in adata.uns.keys(): X_grid, V_grid, _ = ( adata.uns["grid_velocity_" + basis]["VecFld"]["X_grid"], adata.uns["grid_velocity_" + basis]["VecFld"]["V_grid"], adata.uns["grid_velocity_" + basis]["VecFld"]["D"], ) else: raise Exception( "Vector field learning method {} is not supported or the grid velocity is collected for " "the current adata object.".format(method) ) if inverse: V_grid = -V_grid streamplot_kwargs = { "density": density * 2, "linewidth": None, "cmap": None, "norm": None, "arrowsize": 1, "arrowstyle": "fancy", "minlength": 0.1, "transform": None, "start_points": None, "maxlength": 4.0, "integration_direction": "both", "zorder": 3, } mass = np.sqrt((V_grid ** 2).sum(0)) linewidth *= 2 * mass / mass[~np.isnan(mass)].max() streamplot_kwargs.update({"linewidth": linewidth}) streamplot_kwargs = update_dict(streamplot_kwargs, streamline_kwargs) if background is None: _background = rcParams.get("figure.facecolor") background = to_hex(_background) if type(_background) is tuple else _background if background in ["black", "#ffffff"]: streamline_color = "red" else: streamline_color = "black" # if ax is None: # plt.figure(facecolor=background) axes_list, _, _ = scatters( adata=adata, basis=basis, x=x, y=y, color=color, layer=layer, highlights=highlights, labels=labels, values=values, theme=theme, cmap=cmap, color_key=color_key, color_key_cmap=color_key_cmap, background=background, ncols=ncols, pointsize=pointsize, figsize=figsize, show_legend=show_legend, use_smoothed=use_smoothed, aggregate=aggregate, show_arrowed_spines=show_arrowed_spines, ax=ax, sort=sort, save_show_or_return="return", frontier=frontier, **s_kwargs_dict, return_all=True, ) if type(axes_list) == list: for i in range(len(axes_list)): axes_list[i].set_facecolor(background) s = axes_list[i].streamplot( X_grid[0], X_grid[1], V_grid[0], V_grid[1], color=streamline_color, **streamplot_kwargs, ) set_arrow_alpha(axes_list[i], streamline_alpha) set_stream_line_alpha(s, streamline_alpha) else: axes_list.set_facecolor(background) s = axes_list.streamplot( X_grid[0], X_grid[1], V_grid[0], V_grid[1], color=streamline_color, **streamplot_kwargs, ) set_arrow_alpha(axes_list, streamline_alpha) set_stream_line_alpha(s, streamline_alpha) if save_show_or_return == "save": s_kwargs = {"path": None, "prefix": 'streamline_plot', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} s_kwargs = update_dict(s_kwargs, save_kwargs) save_fig(**s_kwargs) elif save_show_or_return == "show": plt.tight_layout() plt.show() elif save_show_or_return == "return": return axes_list
def jacobian(adata, regulators=None, effectors=None, basis="umap", J_basis="pca", x=0, y=1, layer='M_s', highlights=None, cmap='bwr', background=None, pointsize=None, figsize=(6, 4), show_legend=True, frontier=True, sym_c=True, sort='abs', show_arrowed_spines=False, stacked_fraction=False, save_show_or_return="show", save_kwargs={}, **kwargs): """\ Scatter plot with pca basis. Parameters ---------- adata: :class:`~anndata.AnnData` an Annodata object with Jacobian matrix estimated. regulators: `list` or `None` (default: `None`) The list of genes that will be used as regulators for plotting the Jacobian heatmap, only limited to genes that have already performed Jacobian analysis. effectors: `List` or `None` (default: `None`) The list of genes that will be used as targets for plotting the Jacobian heatmap, only limited to genes that have already performed Jacobian analysis. basis: `str` (default: `umap`) The reduced dimension basis. J_basis: `str` (default: `pca`) The reduced dimension space that will be used to calculate the jacobian matrix. x: `int` (default: `0`) The column index of the low dimensional embedding for the x-axis. y: `int` (default: `1`) The column index of the low dimensional embedding for the y-axis. highlights: `list` (default: None) Which color group will be highlighted. if highligts is a list of lists - each list is relate to each color element. cmap: string (optional, default 'Blues') The name of a matplotlib colormap to use for coloring or shading points. If no labels or values are passed this will be used for shading points according to density (largely only of relevance for very large datasets). If values are passed this will be used for shading according the value. Note that if theme is passed then this value will be overridden by the corresponding option of the theme. background: string or None (optional, default 'None`) The color of the background. Usually this will be either 'white' or 'black', but any color name will work. Ideally one wants to match this appropriately to the colors being used for points etc. This is one of the things that themes handle for you. Note that if theme is passed then this value will be overridden by the corresponding option of the theme. figsize: `None` or `[float, float]` (default: (6, 4)) The width and height of each panel in the figure. show_legend: bool (optional, default True) Whether to display a legend of the labels frontier: `bool` (default: `False`) Whether to add the frontier. Scatter plots can be enhanced by using transparency (alpha) in order to show area of high density and multiple scatter plots can be used to delineate a frontier. See matplotlib tips & tricks cheatsheet (https://github.com/matplotlib/cheatsheets). Originally inspired by figures from scEU-seq paper: https://science.sciencemag.org/content/367/6482/1151. sym_c: `bool` (default: `True`) Whether do you want to make the limits of continuous color to be symmetric, normally this should be used for plotting velocity, jacobian, curl, divergence or other types of data with both positive or negative values. sort: `str` (optional, default `abs`) The method to reorder data so that high values points will be on top of background points. Can be one of {'raw', 'abs', 'neg'}, i.e. sorted by raw data, sort by absolute values or sort by negative values. show_arrowed_spines: bool (optional, default False) Whether to show a pair of arrowed spines representing the basis of the scatter is currently using. stacked_fraction: bool (default: False) If True the jacobian will be represented as a stacked fraction in the title, otherwise a linear fraction style is used. save_show_or_return: `str` {'save', 'show', 'return'} (default: `show`) Whether to save, show or return the figure. save_kwargs: `dict` (default: `{}`) A dictionary that will passed to the save_fig function. By default it is an empty dictionary and the save_fig function will use the {"path": None, "prefix": 'scatter', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} as its parameters. Otherwise you can provide a dictionary that properly modify those keys according to your needs. kwargs: Additional arguments passed to plt._matplotlib_points. Returns ------- Nothing but plots the n_source x n_targets scatter plots of low dimensional embedding of the adata object, each corresponds to one element in the Jacobian matrix for all sampled cells. Examples -------- >>> import dynamo as dyn >>> adata = dyn.sample_data.hgForebrainGlutamatergic() >>> adata = dyn.pp.recipe_monocle(adata) >>> dyn.tl.dynamics(adata) >>> dyn.vf.VectorField(adata, basis='pca') >>> valid_gene_list = adata[:, adata.var.use_for_transition].var.index[:2] >>> dyn.vf.jacobian(adata, regulators=valid_gene_list[0], effectors=valid_gene_list[1]) >>> dyn.pl.jacobian(adata) """ import matplotlib.pyplot as plt from matplotlib import rcParams from matplotlib.colors import to_hex if background is None: _background = rcParams.get("figure.facecolor") _background = to_hex( _background) if type(_background) is tuple else _background else: _background = background Jacobian_ = "jacobian" if J_basis is None else "jacobian_" + J_basis Der, cell_indx, jacobian_gene, regulators_, effectors_ = adata.uns[Jacobian_].get('jacobian'), \ adata.uns[Jacobian_].get('cell_idx'), \ adata.uns[Jacobian_].get('jacobian_gene'), \ adata.uns[Jacobian_].get('regulators'), \ adata.uns[Jacobian_].get('effectors') adata_ = adata[cell_indx, :] # test the simulation data here if (regulators_ is None or effectors_ is None): if Der.shape[0] != adata_.n_vars: source_genes = [ J_basis + '_' + str(i) for i in range(Der.shape[0]) ] target_genes = [ J_basis + '_' + str(i) for i in range(Der.shape[1]) ] else: source_genes, target_genes = adata_.var_names, adata_.var_names else: Der, source_genes, target_genes = intersect_sources_targets( regulators, regulators_, effectors, effectors_, Der if jacobian_gene is None else jacobian_gene) ## integrate this with the code in scatter ## if type(x) is int and type(y) is int: prefix = 'X_' cur_pd = pd.DataFrame({ basis + "_" + str(x): adata_.obsm[prefix + basis][:, x], basis + "_" + str(y): adata_.obsm[prefix + basis][:, y], }) elif is_gene_name(adata_, x) and is_gene_name(adata_, y): cur_pd = pd.DataFrame({ x: adata_.obs_vector(k=x, layer=None) if layer == 'X' else adata_.obs_vector(k=x, layer=layer), y: adata_.obs_vector(k=y, layer=None) if layer == 'X' else adata_.obs_vector(k=y, layer=layer), }) # cur_pd = cur_pd.loc[(cur_pd > 0).sum(1) > 1, :] cur_pd.columns = [ x + " (" + layer + ")", y + " (" + layer + ")", ] elif is_cell_anno_column(adata_, x) and is_cell_anno_column(adata_, y): cur_pd = pd.DataFrame({ x: adata_.obs_vector(x), y: adata_.obs_vector(y), }) cur_pd.columns = [x, y] elif is_cell_anno_column(adata_, x) and is_gene_name(adata_, y): cur_pd = pd.DataFrame({ x: adata_.obs_vector(x), y: adata_.obs_vector(k=y, layer=None) if layer == 'X' else adata_.obs_vector(k=y, layer=layer), }) cur_pd.columns = [x, y + " (" + layer + ")"] elif is_gene_name(adata_, x) and is_cell_anno_column(adata_, y): cur_pd = pd.DataFrame({ x: adata_.obs_vector(k=x, layer=None) if layer == 'X' else adata_.obs_vector(k=x, layer=layer), y: adata_.obs_vector(y) }) # cur_pd = cur_pd.loc[cur_pd.iloc[:, 0] > 0, :] cur_pd.columns = [x + " (" + layer + ")", y] elif is_layer_keys(adata_, x) and is_layer_keys(adata_, y): x_, y_ = adata_[:, basis].layers[x], adata_[:, basis].layers[y] cur_pd = pd.DataFrame({x: flatten(x_), y: flatten(y_)}) # cur_pd = cur_pd.loc[cur_pd.iloc[:, 0] > 0, :] cur_pd.columns = [x, y] elif type(x) in [anndata._core.views.ArrayView, np.ndarray] and \ type(y) in [anndata._core.views.ArrayView, np.ndarray]: cur_pd = pd.DataFrame({'x': flatten(x), 'y': flatten(y)}) cur_pd.columns = ['x', 'y'] point_size = (500.0 / np.sqrt(adata_.shape[0]) if pointsize is None else 500.0 / np.sqrt(adata_.shape[0]) * pointsize) point_size = 4 * point_size scatter_kwargs = dict( alpha=0.2, s=point_size, edgecolor=None, linewidth=0, ) # (0, 0, 0, 1) if kwargs is not None: scatter_kwargs.update(kwargs) nrow, ncol = len(source_genes), len(target_genes) if figsize is None: g = plt.figure(None, (3 * ncol, 3 * nrow), facecolor=_background) # , dpi=160 else: g = plt.figure(None, (figsize[0] * ncol, figsize[1] * nrow), facecolor=_background) # , dpi=160 gs = plt.GridSpec(nrow, ncol, wspace=0.12) for i, source in enumerate(source_genes): for j, target in enumerate(target_genes): ax = plt.subplot(gs[i * ncol + j]) J = Der[j, i, :] # dim 0: target; dim 1: source cur_pd["jacobian"] = J # cur_pd.loc[:, "jacobian"] = np.array([scinot(i) for i in cur_pd.loc[:, "jacobian"].values]) v_max = np.max(np.abs(J)) scatter_kwargs.update({"vmin": -v_max, "vmax": v_max}) ax, color = _matplotlib_points(cur_pd.iloc[:, [0, 1]].values, ax=ax, labels=None, values=J, highlights=highlights, cmap=cmap, color_key=None, color_key_cmap=None, background=_background, width=figsize[0], height=figsize[1], show_legend=show_legend, frontier=frontier, sort=sort, sym_c=sym_c, **scatter_kwargs) if stacked_fraction: ax.set_title(r'$\frac{\partial f_{%s}}{\partial x_{%s}}$' % (target, source)) else: ax.set_title(r'$\partial f_{%s} / \partial x_{%s}$' % (target, source)) if i + j == 0 and show_arrowed_spines: arrowed_spines(ax, basis, background) else: despline_all(ax) deaxis_all(ax) if save_show_or_return == "save": s_kwargs = { "path": None, "prefix": 'jacobian', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True } s_kwargs = update_dict(s_kwargs, save_kwargs) save_fig(**s_kwargs) elif save_show_or_return == "show": plt.tight_layout() plt.show() elif save_show_or_return == "return": return gs
def state_graph(adata, group, basis="umap", x=0, y=1, color="ntr", layer="X", highlights=None, labels=None, values=None, theme=None, cmap=None, color_key=None, color_key_cmap=None, background=None, ncols=1, pointsize=None, figsize=(6, 4), show_legend=True, use_smoothed=True, show_arrowed_spines=True, ax=None, sort="raw", frontier=False, save_show_or_return="show", save_kwargs={}, s_kwargs_dict={}, **kwargs): """Plot a summarized cell type (state) transition graph. This function tries to create a model that summarizes the possible cell type transitions based on the reconstructed vector field function. Parameters ---------- group: `str` or `None` (default: `None`) The column in adata.obs that will be used to aggregate data points for the purpose of creating a cell type transition model. %(scatters.parameters.no_aggregate|kwargs|save_kwargs)s save_kwargs: `dict` (default: `{}`) A dictionary that will passed to the save_fig function. By default it is an empty dictionary and the save_fig function will use the {"path": None, "prefix": 'state_graph', "dpi": None, "ext": 'pdf', "transparent": True, "close": True, "verbose": True} as its parameters. Otherwise you can provide a dictionary that properly modify those keys according to your needs. s_kwargs_dict: `dict` (default: {}) The dictionary of the scatter arguments. Returns ------- Plot the a model of cell fate transition that summarizes the possible lineage commitments between different cell types. """ import matplotlib.pyplot as plt from matplotlib import rcParams from matplotlib.colors import to_hex aggregate = group points = adata.obsm["X_" + basis][:, [x, y]] unique_group_obs = adata.obs[group].unique() if type(unique_group_obs) is np.ndarray: groups, uniq_grp = adata.obs[group], unique_group_obs.tolist() elif type(unique_group_obs) is pd.Series: groups, uniq_grp = adata.obs[group], unique_group_obs.to_list() else: groups, uniq_grp = adata.obs[group], list(unique_group_obs) group_median = np.zeros((len(uniq_grp), 2)) grp_size = adata.obs[group].value_counts().values s_kwargs_dict.update({"s": grp_size}) Pl = adata.uns[group + "_graph"]["group_graph"] Pl[Pl - Pl.T < 0] = 0 Pl /= Pl.sum(1)[:, None] for i, cur_grp in enumerate(uniq_grp): group_median[i, :] = np.nanmedian( points[np.where(groups == cur_grp)[0], :2], 0) if background is None: _background = rcParams.get("figure.facecolor") background = to_hex( _background) if type(_background) is tuple else _background plt.figure(facecolor=_background) axes_list, color_list, font_color = scatters( adata=adata, basis=basis, x=x, y=y, color=color, layer=layer, highlights=highlights, labels=labels, values=values, theme=theme, cmap=cmap, color_key=color_key, color_key_cmap=color_key_cmap, background=background, ncols=ncols, pointsize=pointsize, figsize=figsize, show_legend=show_legend, use_smoothed=use_smoothed, aggregate=aggregate, show_arrowed_spines=show_arrowed_spines, ax=ax, sort=sort, save_show_or_return="return", frontier=frontier, **s_kwargs_dict, return_all=True, ) arrows = create_edge_patches_from_markov_chain(Pl, group_median, tol=0.01, node_rad=15) if type(axes_list) == list: for i in range(len(axes_list)): for arrow in arrows: axes_list[i].add_patch(arrow) axes_list[i].set_facecolor(background) else: for arrow in arrows: axes_list.add_patch(arrow) axes_list.set_facecolor(background) plt.axis("off") plt.show() if save_show_or_return == "save": s_kwargs = { "path": None, "prefix": "state_graph", "dpi": None, "ext": "pdf", "transparent": True, "close": True, "verbose": True, } s_kwargs = update_dict(s_kwargs, save_kwargs) save_fig(**s_kwargs) elif save_show_or_return == "show": if show_legend: plt.subplots_adjust(right=0.85) plt.tight_layout() plt.show() elif save_show_or_return == "return": return axes_list, color_list, font_color