def set_first_figure_current(self): # only do this if we have any figures at all # If we don't, we don't want to create one as that sets the size of the # window and then figures sizes are ignored by subsequent runs of the script if len(matplotlib.pyplot.get_fignums()) == 0: return identifier = 1 fig = self._figure(identifier) if fig not in self.figs.values(): self.figs[identifier] = fig elif identifier not in self.__allocated_figures: # handle case where we are swapping from all identified figures # to the first not being explicitly identified through a call to figure() # AND we already had a figure with the identifier of "1" which is what we use # for the default figure if identifier in self.figs and self.figs[identifier] != fig: j = identifier while j in self.figs: j += 1 self.figs[j] = self.figs[identifier] msg = """Warning: detected collision of matplotlib figure identifiers. Plot output may not be as expected. Re-run the analysis script to (hopefully) resolve the collision. To permanently fix this, please ensure you call figure() prior to other matplotlib plotting functions. """ sys.stderr.write(lyse.dedent(msg)) self.figs[identifier] = fig self.__allocated_figures.append(identifier) self._remove_dead_references(identifier, fig)
def new_figure(self, fig, identifier): try: # Get custom class for this plot if it is registered cls = lyse.get_plot_class(identifier) # If no plot was registered, use the base class if cls is None: cls = Plot # if cls is not a subclass of Plot, then raise an Exception if not issubclass(cls, Plot): raise RuntimeError( 'The specified class must be a subclass of lyse.Plot') # Instantiate the plot self.plots[fig] = cls(fig, identifier, self.filepath) except Exception: traceback_lines = traceback.format_exception(*sys.exc_info()) del traceback_lines[1] # Avoiding a list comprehension here so as to avoid this # python bug in earlier versions of 2.7 (fixed in 2.7.9): # https://bugs.python.org/issue21591 message = """Failed to instantiate custom class for plot "{identifier}". Perhaps lyse.register_plot_class() was called incorrectly from your script? The exception raised was: """.format(identifier=identifier) message = lyse.dedent(message) for line in traceback_lines: if PY2: # errors='replace' is for Windows filenames present in the # traceback that are not UTF8. They will not display # correctly, but that's the best we can do - the traceback # may contain code from the file in a different encoding, # so we could have a mixed encoding string. This is only # a problem for Python 2. line = line.decode('utf8', errors='replace') message += line message += '\n' message += 'Due to this error, we used the default lyse.Plot class instead.\n' sys.stderr.write(message) # instantiate plot using original Base class so that we always get a plot self.plots[fig] = Plot(fig, identifier, self.filepath) return self.plots[fig]