def __init__(self, parent=None, base_dir=None, short_name=None): # Save parent # self.parent = parent # If we got a file # if isinstance(base_dir, FilePath): self.base_dir = base_dir.directory short_name = base_dir.short_prefix # If no parent and no directory # if base_dir is None and parent is None: file_name = os.path.abspath((inspect.stack()[1])[1]) self.base_dir = os.path.dirname(os.path.abspath(file_name)) + '/' self.base_dir = Path(self.base_dir) # If no directory but a parent is present # if base_dir is None: if hasattr(self.parent, 'p'): self.base_dir = self.parent.p.graphs_dir if hasattr(self.parent, 'paths'): self.base_dir = self.parent.paths.graphs_dir else: self.base_dir = Path(self.base_dir) self.base_dir.create_if_not_exists() # Short name # if short_name: self.short_name = short_name # Use the base class name # if not hasattr(self, 'short_name'): self.short_name = camel_to_snake(self.__class__.__name__)
def __init__(self, source_path, dest_path, **kwargs): # Record attributes # self.source = Path(source_path) self.dest = Path(dest_path) # Keep the kwargs too # self.kwargs = kwargs # Check directory case # if self.dest.endswith('/'): self.dest = self.dest + self.source.filename self.dest = self.dest.replace_extension('csv')
def __init__(self, path=None, caption=None, label=None, table=None, **kwargs): # Check inputs # if path is None and table is None: raise Exception("You need to specify a table or a path.") # Path # if path is not None: self.path = Path(path) else: self.path = table.path # Caption # if caption is not None: self.caption = caption else: self.caption = '' if table is not None and hasattr(table, 'caption'): self.caption = table.caption # Label # if label is not None: self.label = r"\label{" + label + "}\n" elif table is not None: self.label = r"\label{" + table.short_name + "}\n" else: self.label = '' # Graph # if table is not None: self.table = table # Keyword arguments # self.kwargs = kwargs # Call the graph if it's not generated # if table is not None and not table: table.save() # Check the file was created # if not self.path.exists: raise Exception("No file at '%s'." % self.path)
def __init__(self, continent): # Save parent # self.continent = continent # The combos dir used for all output # self.combos_dir = self.continent.combos_dir # The base dir for our output # self.base_dir = Path(self.combos_dir + self.short_name + '/')
class ConvertExcelToCSV: """ Will convert an excel file into its CSV equivalent. Can support multiple work sheets into a single CSV. """ def __init__(self, source_path, dest_path, **kwargs): # Record attributes # self.source = Path(source_path) self.dest = Path(dest_path) # Keep the kwargs too # self.kwargs = kwargs # Check directory case # if self.dest.endswith('/'): self.dest = self.dest + self.source.filename self.dest = self.dest.replace_extension('csv') def __call__(self): """Are we mono or multi sheet?""" if len(self.handle.sheet_names) > 1: self.multi_sheet() else: self.mono_sheet() @property_cached def handle(self): """Pandas handle to the excel file.""" return pandas.ExcelFile(str(self.source)) def mono_sheet(self): """Supports only one work sheet per file.""" xls = pandas.read_excel(str(self.source)) xls.to_csv(str(self.dest), **self.kwargs) def multi_sheet(self): """ Supports multiple work sheets per file. Will concatenate sheets together by adding an extra column containing the original sheet name. """ # Initialize # all_sheets = [] # Loop # for name in self.handle.sheet_names: sheet = self.handle.parse(name) sheet.insert(0, "nace", name) all_sheets.append(sheet) # Write # df = pandas.concat(all_sheets) df.to_csv(str(self.dest), **self.kwargs)
def __init__(self, input_path, output_path=None, builtin_template=None): # Input # self.input_path = Path(input_path) # Output # if output_path is None: self.output_path = self.default_output_name else: self.output_path = output_path # Template # self.builtin_template = builtin_template if builtin_template else 'sinclair_bio'
def __init__(self, parent=None, base_dir=None, short_name=None): # Save parent if it was given # self.parent = parent # If we got a file # if isinstance(base_dir, FilePath): self.base_dir = base_dir.directory short_name = base_dir.short_prefix else: self.base_dir = Path(base_dir) # Short name # if short_name: self.short_name = short_name # Use the parents name or the base class name # if not hasattr(self, 'short_name'): if hasattr(self.parent, 'short_name'): self.short_name = self.parent.short_name else: self.short_name = camel_to_snake(self.__class__.__name__)
def handle_destination(url, destination): """ The destination can be either unspecified or can contain either a file path or a directory path. """ # Choose a default for destination # if destination is None: destination = autopaths.tmp_path.new_temp_file() # Directory case - choose a filename # elif destination.endswith('/'): filename = url.split("/")[-1].split("?")[0] destination = Path(destination + filename) destination.directory.create_if_not_exists() # Normal case # else: destination = Path(destination) destination.directory.create_if_not_exists() # Return # return destination
def link_to(self, path, safe=False, absolute=False): """ Create a link somewhere else pointing to this file. The destination is hence *path* and the source is self.path. """ # Get source and destination # from autopaths import Path source = self.path destination = Path(path) # Call method # self._symlink(source, destination, safe, absolute)
def link_from(self, path, safe=False, absolute=False): """ Make a link here pointing to another file/directory somewhere else. The destination is hence self.path and the source is *path*. """ # Get source and destination # from autopaths import Path source = Path(path) destination = self.path # Call method # self._symlink(source, destination, safe, absolute)
def get_pickle_path(self, instance): # First check if an `at` parameter was specified # if self.at is not None: path = Path(getattr(instance, self.at)) # Secondly check if the instance has a cache_dir specified # elif 'cache_dir' in instance.__dict__: path = Path(instance.cache_dir + self.name + '.pickle') # Otherwise we go the default route (no instance passed) # else: path = Path(self.get_default_path()) # Make the directory # path.make_directory() return path
def __init__(self, path_one, path_two, caption_one, caption_two, label_one, label_two, caption_main, label_main): # Both paths # self.path_one, self.path_two = Path(path_one), Path(path_two) # Both subcaptions # self.caption_one = self.escape_underscore(caption_one) self.caption_two = self.escape_underscore(caption_two) # The main caption # self.caption_main = self.escape_underscore(caption_main) # Both reference labels # self.label_one = r"\label{" + label_one + "}\n" if label_one is not None else '' self.label_two = r"\label{" + label_two + "}\n" if label_two is not None else '' # The main reference label # self.label_main = r"\label{" + label_main + "}\n" if label_main is not None else '' # Check existance # if not self.path_one.exists or not self.path_two.exists: raise Exception("File missing.") # Check extension # if self.path_one.filename.count( '.') > 1 or self.path_two.filename.count('.') > 1: raise Exception( "Can't have several extension in a LaTeX figure file name.")
def get_one_xls(self, row): """Download one xls file and put it in the cache directory.""" # We are not interested in all countries # if row['country'] not in country_codes['country'].values: return # Get the matching iso2_code # iso2_code = country_codes.query("country == '%s'" % row['country']) iso2_code = iso2_code['iso2_code'].iloc[0] # The destination directory # destination = Path(self.cache_dir + iso2_code + '.xls') # Save to disk # result = download_from_url(row['xls'], destination, user_agent=None) # We don't want to flood the server # time.sleep(2) # Return # return result
def get_one_zip(self, row): """Download one zip file and put it in the right directory.""" # We are not interested in all countries # if row['country'] not in country_codes['country'].values: return # Get the matching iso2_code # iso2_code = country_codes.query("country == '%s'" % row['country']) iso2_code = iso2_code['iso2_code'].iloc[0] # The destination directory # destination = Path(self.cache_dir + iso2_code + '/') # Save to disk # result = download_via_browser(row['zip'], destination, uncompress=False) # Check if we were blocked # check_blocked_request(result) # We don't want to flood the server # time.sleep(2)
def make_driver(): """ Create a headless webdriver with selenium. Note: #TODO Change the download dir to a temp dir # Otherwise it will append (1) and (2) etc. to the filename before the extension e.g. 'data.zip (1).crdownload' """ # Paths # chrome_driver_path = shutil.which('chromedriver') # Start a service # service = webdriver.chrome.service.Service(chrome_driver_path) service.start() # Add options # options = webdriver.ChromeOptions() options.add_argument('--headless') options = options.to_capabilities() # Create the driver # driver = webdriver.Remote(service.service_url, options) # #TODO Change the download dir to a temp dir # dl_dir = Path(os.getcwd() + '/') # Return # return driver, dl_dir
def __init__(self, path=None, caption=None, label=None, graph=None, **kwargs): # Check inputs # if path is None and graph is None: raise Exception("You need to specify a graph or a path.") # Path # if path is not None: self.path = Path(path) else: self.path = graph.path # Caption # if caption is not None: self.caption = caption else: self.caption = '' if graph is not None and hasattr(graph, 'caption'): self.caption = graph.caption # Label # if label is not None: self.label = r"\label{" + label + "}\n" elif graph is not None: self.label = r"\label{" + graph.short_name + "}\n" else: self.label = '' # Graph # if graph is not None: self.graph = graph # Keyword arguments # self.kwargs = kwargs # Call the graph if it's not generated # if graph is not None and not graph: graph() # Check the file was created # if not self.path.exists: raise Exception("No file at '%s'." % self.path) # Check unique extension # if self.path.filename.count('.') > 1: raise Exception( "Can't have several extensions in a LaTeX figure file name.")
class Table: """ A table with different headers and values that is destined to be exported both to CSV and to TeX format, for instance for display in publications or manuscripts. """ # Default options # formats = ('csv', 'tex') index = True bold_rows = True na_rep = '-' # Float formatting # float_format_csv = '%g' float_format_tex = '%g' # Extra formatting # capital_index = True upper_columns = False column_format = None escape_tex = True def __init__(self, parent=None, base_dir=None, short_name=None): # Save parent if it was given # self.parent = parent # If we got a file # if isinstance(base_dir, FilePath): self.base_dir = base_dir.directory short_name = base_dir.short_prefix else: self.base_dir = Path(base_dir) # Short name # if short_name: self.short_name = short_name # Use the parents name or the base class name # if not hasattr(self, 'short_name'): if hasattr(self.parent, 'short_name'): self.short_name = self.parent.short_name else: self.short_name = camel_to_snake(self.__class__.__name__) @property_cached def path(self): return Path(self.base_dir + self.short_name + '.tex') @property def csv_path(self): return self.path.replace_extension('csv') #-------------------------------- Other ----------------------------------# def split_thousands(self, number): """This method will determine how numbers are displayed in the table.""" # Case is NaN # if numpy.isnan(number): return self.na_rep # Round # number = int(round(number)) # Format # from plumbing.common import split_thousands number = split_thousands(number) # Return # return number def make_percent(self, row): # Remember where the NaNs are located # nans = row.isna() # Multiply for percentage # row *= 100 # Express difference as a percentage # row = row.apply(lambda f: "%.1f%%" % f) # Restore NaNs # row[nans] = self.na_rep # Return # return row #--------------------------------- Save ----------------------------------# def save(self, **kw): # Load # df = self.df.copy() # Modify the index name# if self.capital_index and df.index.name is not None: df.index.name = df.index.name.capitalize() # Modify column names # if self.upper_columns: df.columns = df.columns.str.upper() # Possibility to overwrite path # if 'path' in kw: path = FilePath(kw['path']) else: path = self.path # Special cases for float formatting # if self.float_format_tex == 'split_thousands': self.float_format_tex = self.split_thousands # Make sure the directory exists # self.base_dir.create_if_not_exists() # Latex version # if 'tex' in self.formats: df.to_latex(str(path), float_format = self.float_format_tex, na_rep = self.na_rep, index = self.index, bold_rows = self.bold_rows, column_format = self.column_format, escape = self.escape_tex) # CSV version (plain text) # if 'csv' in self.formats: path = path.replace_extension('csv') df.to_csv(str(path), float_format = self.float_format_csv, index = self.index) # Return the path # return path
Written by Lucas Sinclair. MIT Licenced. """ # Built-in modules # # Internal modules # import inspect, os # First party modules # from autopaths import Path # Third party modules # # Constants # file_name = inspect.getframeinfo(inspect.currentframe()).filename this_dir = os.path.dirname(os.path.abspath(file_name)) + '/' destin = Path(this_dir + 'user_agent_strings.txt') ################################################################################ def get_popular_user_agents(): """ Retrieve most popular user agent strings. Can look at https://techblog.willshouse.com/2012/01/03/most-common-user-agents/ """ return '' ################################################################################ if __name__ == '__main__': content = get_popular_user_agents() destin.write(content)
__version__ = '0.2.2' # Built-in modules # import os, sys # First party modules # from autopaths import Path from autopaths.dir_path import DirectoryPath from plumbing.git import GitRepo # Constants # project_name = 'libcbm_runner' project_url = 'https://github.com/xapple/libcbm_runner' # Get paths to module # self = sys.modules[__name__] module_dir = Path(os.path.dirname(self.__file__)) # The repository directory # repos_dir = module_dir.directory # The module is maybe in a git repository # git_repo = GitRepo(repos_dir, empty=True) # Where is the data, default case # libcbm_data_dir = DirectoryPath("~/repos/libcbm_data/") # But you can override that with an environment variable # if os.environ.get("LIBCBM_DATA"): libcbm_data_dir = DirectoryPath(os.environ['LIBCBM_DATA'])
def __init__(self, sheet_to_dfs, path): self.sheet_to_dfs = sheet_to_dfs self.path = Path(path)
class Document(object): """The main object is the document to be generated from markdown text.""" def __repr__(self): return '<%s object on %s>' % (self.__class__.__name__, self.parent) def __init__(self, input_path, output_path=None, builtin_template=None): # Input # self.input_path = Path(input_path) # Output # if output_path is None: self.output_path = self.default_output_name else: self.output_path = output_path # Template # self.builtin_template = builtin_template if builtin_template else 'sinclair_bio' def __call__(self, *args, **kwargs): return self.generate(*args, **kwargs) def generate(self): self.load_markdown() self.make_body() self.make_latex(params=self.params) self.make_pdf() @property def default_options(self): return { 'name': os.environ.get('USER_FULL_NAME'), 'status': os.environ.get('USER_STATUS'), 'company': os.environ.get('USER_COMPANY'), 'subcompany': os.environ.get('USER_SUBCOMPANY'), 'title': "Auto-generated report", 'image_path': logo_dir + 'logo.png', } @property def default_output_name(self): return os.path.splitext(self.input_path)[0] + '.pdf' def load_markdown(self): """Load file in memory and separate the options and body""" # Read the file # self.input_path.must_exist() self.input = self.input_path.contents_utf8 # Separate the top params and the rest of the markdown # find_results = re.findall('\A---(.+?)---(.+)', self.input, re.M|re.DOTALL) # We did not find any parameters # if not find_results: self.params = {} self.markdown = self.input return # We did find a set of parameters # self.params, self.markdown = find_results[0] self.params = [i.partition(':')[::2] for i in self.params.strip().split('\n')] self.params = dict([(k.strip(),v.strip()) for k,v in self.params]) def make_body(self): """Convert the body to LaTeX.""" kwargs = dict(_in=self.markdown, read='markdown', write='latex') self.body = pbs3.Command('pandoc')(**kwargs).stdout def make_latex(self, params=None, header=None, footer=None): """Add the header and footer.""" options = self.default_options.copy() if params: options.update(params) # Load the right templates # subpackage = importlib.import_module('pymarktex.templates.' + self.builtin_template) # Header and Footer # self.header = subpackage.HeaderTemplate(options) if header is None else header self.footer = subpackage.FooterTemplate() if footer is None else footer self.latex = str(self.header) + self.body + str(self.footer) def make_pdf(self, safe=False, include_src=False): """Call XeLaTeX (twice for cross-referencing)""" # Paths # self.tmp_dir = new_temp_dir() self.tmp_path = Path(self.tmp_dir + 'main.tex') self.tmp_stdout = Path(self.tmp_dir + 'stdout.txt') self.tmp_stderr = Path(self.tmp_dir + 'stderr.txt') self.tmp_log = Path(self.tmp_dir + 'main.log') # Prepare # with codecs.open(self.tmp_path, 'w', encoding='utf8') as handle: handle.write(self.latex) self.cmd_params = ["--interaction=nonstopmode", '-output-directory'] self.cmd_params += [self.tmp_dir, self.tmp_path] # Call twice for references # self.call_xelatex(safe) self.call_xelatex(safe) # Move into place # shutil.move(self.tmp_dir + 'main.pdf', self.output_path) # Show the latex source # if include_src: self.output_path.replace_extension('tex').write(self.latex, encoding='utf-8') def call_xelatex(self, safe=False): """Here we use the `pbs3` library under Windows and the sh` library under Unix. There is a cross-compatible library called `plumbum` but has an awkward syntax: cmd = plumbum.local['xelatex'] ((cmd > self.tmp_stderr) >= self.tmp_stdout)() See https://github.com/tomerfiliba/plumbum/issues/441 """ if os.name == "posix": cmd = pbs3.Command('xelatex') if os.name == "nt": cmd = pbs3.Command('xelatex.exe') try: cmd(*self.cmd_params, _ok_code=[0] if not safe else [0,1], _err=str(self.tmp_stderr), _out=str(self.tmp_stdout)) except pbs3.ErrorReturnCode_1: print('-'*60) print("Xelatex exited with return code 1.") if self.tmp_stdout.exists: print("Here is the tail of the stdout at '%s':" % self.tmp_stdout.unix_style) print(self.tmp_stdout.pretty_tail) elif self.tmp_log.exists: print("Here is the tail of the log at '%s':" % self.tmp_log.unix_style) print(self.tmp_log.pretty_tail) print('-'*60) raise def copy_to_outbox(self): """Copy the report to the outbox directory where it can be viewed by anyone.""" self.outbox.directory.create(safe=True) shutil.copy(self.output_path, self.outbox) def purge_cache(self): """Some reports used pickled properties to avoid recalculations.""" if not hasattr(self, 'cache_dir'): raise Exception("No cache directory to purge.") self.cache_dir.remove() self.cache_dir.create()
def __call__(self): for item in self.csv_list: csv_path = Path(self.country.data_dir + 'orig/csv/' + item) self.rename(csv_path)
def path(self): return Path(self.base_dir + self.short_name + '.tex')
JRC Biomass Project. Unit D1 Bioeconomy. """ # Built-in modules # import os, inspect # Internal modules # from pymarktex.templates import Template # First party modules # from autopaths import Path # Get current directory # file_name = os.path.abspath((inspect.stack()[0])[1]) this_dir = Path(os.path.dirname(os.path.abspath(file_name)) + '/') ############################################################################### class Header(Template): """All the parameters to be rendered in the LaTeX header template.""" def image_path(self): return (this_dir + 'logo.png').unix_style ############################################################################### class Footer(Template): """All the parameters to be rendered in the LaTeX footer template.""" pass
def __init__(self, zip_cache_dir): # Record where the cache will be located on disk # self.cache_dir = zip_cache_dir # Where the file should be downloaded to # self.zip_path = Path(self.cache_dir + self.zip_name)
def __init__(self, output_path=None): # Paths # if output_path is None: self.output_path = Path(cache_dir + 'reports/comparison.pdf') else: self.output_path = Path(output_path)
class Graph(object): """ A nice class to make graphs with matplotlib. Example usage: from plumbing.graphs import Graph class RegressionGraph(Graph): def plot(self, **kwargs): fig = pyplot.figure() seaborn.regplot(self.x_data, self.y_data, fit_reg=True); self.save_plot(fig, **kwargs) for x_name in x_names: graph = PearsonGraph(short_name = x_name) graph.title = "Regression between y and '%s'" % (x_name) graph.x_data = x_data[x_name] graph.y_data = y_data graph.plot() """ default_params = OrderedDict(( ('width' , None), ('height' , None), ('bottom' , None), ('top' , None), ('left' , None), ('right' , None), ('x_grid' , None), # Vertical lines ('y_grid' , None), # Horizontal lines ('x_scale', None), ('y_scale', None), ('x_label', None), ('y_label', None), ('title' , None), ('y_lim_min', None), # Minium (ymax - ymin) after autoscale ('x_lim_min', None), # Minium (xmax - xmin) after autoscale ('sep' , ()), ('formats', ('pdf',)), )) def __bool__(self): return bool(self.path) __nonzero__ = __bool__ def __init__(self, parent=None, base_dir=None, short_name=None): # Save parent # self.parent = parent # If we got a file # if isinstance(base_dir, FilePath): self.base_dir = base_dir.directory short_name = base_dir.short_prefix # If no parent and no directory # if base_dir is None and parent is None: file_name = os.path.abspath((inspect.stack()[1])[1]) self.base_dir = os.path.dirname(os.path.abspath(file_name)) + '/' self.base_dir = Path(self.base_dir) # If no directory but a parent is present # if base_dir is None: if hasattr(self.parent, 'p'): self.base_dir = self.parent.p.graphs_dir if hasattr(self.parent, 'paths'): self.base_dir = self.parent.paths.graphs_dir else: self.base_dir = Path(self.base_dir) self.base_dir.create_if_not_exists() # Short name # if short_name: self.short_name = short_name # Use the base class name # if not hasattr(self, 'short_name'): self.short_name = camel_to_snake(self.__class__.__name__) @property_cached def path(self): return Path(self.base_dir + self.short_name + '.pdf') def __call__(self, *args, **kwargs): """Plot the graph if it doesn't exist. Then return the path to it. Force the reruning with rerun=True""" if not self or kwargs.get('rerun'): self.plot(*args, **kwargs) return self.path def save_plot(self, fig=None, axes=None, **kwargs): # Missing figure # if fig is None: fig = pyplot.gcf() # Missing axes # if axes is None: axes = pyplot.gca() # Parameters # self.params = {} for key in self.default_params: if key in kwargs: self.params[key] = kwargs[key] elif hasattr(self, key): self.params[key] = getattr(self, key) elif self.default_params[key] is not None: self.params[key] = self.default_params[key] # Backwards compatibility # if kwargs.get('x_log', False): self.params['x_scale'] = 'symlog' if kwargs.get('y_log', False): self.params['y_scale'] = 'symlog' # Log # if 'x_scale' in self.params: axes.set_xscale(self.params['x_scale']) if 'y_scale' in self.params: axes.set_yscale(self.params['y_scale']) # Axis limits # if 'x_min' in self.params: axes.set_xlim(self.params['x_min'], axes.get_xlim()[1]) if 'x_max' in self.params: axes.set_xlim(axes.get_xlim()[0], self.params['x_max']) if 'y_min' in self.params: axes.set_ylim(self.params['y_min'], axes.get_ylim()[1]) if 'y_max' in self.params: axes.set_ylim(axes.get_ylim()[0], self.params['y_max']) # Minimum delta on axis limits # if 'y_lim_min' in self.params: top, bottom = axes.get_ylim() minimum = self.params['y_lim_min'] delta = top - bottom if delta < minimum: center = bottom + delta/2 axes.set_ylim(center - minimum/2, center + minimum/2) # Title # title = self.params.get('title', False) if title: axes.set_title(title) # Axes labels # if self.params.get('x_label'): axes.set_xlabel(self.params['x_label']) if self.params.get('y_label'): axes.set_ylabel(self.params['y_label']) # Set height and width # if self.params.get('width'): fig.set_figwidth(self.params['width']) if self.params.get('height'): fig.set_figheight(self.params['height']) # Adjust # if self.params.get('bottom'): fig.subplots_adjust(hspace=0.0, bottom = self.params['bottom'], top = self.params['top'], left = self.params['left'], right = self.params['right']) # Grid # if 'x_grid' in self.params: axes.xaxis.grid(self.params['x_grid']) if 'y_grid' in self.params: axes.yaxis.grid(self.params['y_grid']) # Data and source extra text # if hasattr(self, 'dev_mode') and self.dev_mode is True: fig.text(0.99, 0.98, time.asctime(), horizontalalignment='right') job_name = os.environ.get('SLURM_JOB_NAME', 'Unnamed') user_msg = 'user: %s, job: %s' % (getpass.getuser(), job_name) fig.text(0.01, 0.98, user_msg, horizontalalignment='left') # Nice digit grouping # if 'x' in self.params['sep']: separate = lambda x,pos: split_thousands(x) axes.xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(separate)) if 'y' in self.params['sep']: separate = lambda y,pos: split_thousands(y) axes.yaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(separate)) # Add custom labels # if 'x_labels' in self.params: axes.set_xticklabels(self.params['x_labels']) if 'x_labels_rot' in self.params: pyplot.setp(axes.xaxis.get_majorticklabels(), rotation=self.params['x_labels_rot']) # Possibility to overwrite path # if 'path' in self.params: path = FilePath(self.params['path']) elif hasattr(self, 'path'): path = FilePath(self.path) else: path = FilePath(self.short_name + '.pdf') # Save it as different formats # for ext in self.params['formats']: fig.savefig(path.replace_extension(ext)) # Close it # pyplot.close(fig) def plot_and_save(self, **kwargs): """Used when the plot method defined does not create a figure nor calls save_plot Then the plot method has to use self.fig""" self.fig = pyplot.figure() self.plot() self.axes = pyplot.gca() self.save_plot(self.fig, self.axes, **kwargs) pyplot.close(self.fig) def plot(self, bins=250, **kwargs): """An example plot function. You have to subclass this method.""" # Data # counts = [sum(map(len, b.contigs)) for b in self.parent.bins] # Linear bins in logarithmic space # if 'log' in kwargs.get('x_scale', ''): start, stop = numpy.log10(1), numpy.log10(max(counts)) bins = list(numpy.logspace(start=start, stop=stop, num=bins)) bins.insert(0, 0) # Plot # fig = pyplot.figure() pyplot.hist(counts, bins=bins, color='gray') axes = pyplot.gca() # Information # title = 'Distribution of the total nucleotide count in the bins' axes.set_title(title) axes.set_xlabel('Number of nucleotides in a bin') axes.set_ylabel('Number of bins with that many nucleotides in them') # Save it # self.save_plot(fig, axes, **kwargs) pyplot.close(fig) # For convenience # return self def save_anim(self, fig, animate, init, bitrate=10000, fps=30): """Not functional -- TODO""" from matplotlib import animation anim = animation.FuncAnimation(fig, animate, init_func=init, frames=360, interval=20) FFMpegWriter = animation.writers['ffmpeg'] writer = FFMpegWriter(bitrate= bitrate, fps=fps) # Save # self.avi_path = self.base_dir + self.short_name + '.avi' anim.save(self.avi_path, writer=writer, codec='x264')