content: """
  plotable rich object display on IPython/Jupyter notebooks 
  """
  
  __author__ = "Philippe Guglielmetti"
  __copyright__ = "Copyright 2015, Philippe Guglielmetti"
  __credits__ = []
  __license__ = "LGPL"
  
  # import matplotlib and set backend once for all
  from . import itertools2
  import os
  import io
  import sys
  import logging
  import base64
  import matplotlib
  
  if os.getenv('TRAVIS'):  # are we running https://travis-ci.org/ automated tests ?
      matplotlib.use('Agg')  # Force matplotlib  not to use any Xwindows backend
  elif sys.gettrace():  # http://stackoverflow.com/questions/333995/how-to-detect-that-python-code-is-being-executed-through-the-debugger
      matplotlib.use('Agg')  # because 'QtAgg' crashes python while debugging
  else:
      pass
      # matplotlib.use('pdf') #for high quality pdf, but doesn't work for png, svg ...
  
  logging.info('matplotlib backend is %s' % matplotlib.get_backend())
  
  
  class Plot(object):
      """base class for plotable rich object display on IPython notebooks
      inspired from http://nbviewer.ipython.org/github/ipython/ipython/blob/3607712653c66d63e0d7f13f073bde8c0f209ba8/docs/examples/notebooks/display_protocol.ipynb
      """
  
      def _plot(self, ax, **kwargs):
          """abstract method, must be overriden
  
          :param ax: `matplotlib.axis` 
          :return ax: `matplotlib.axis` after plot
          """
          raise NotImplementedError(
              'objects derived from plot.PLot must define a _plot method')
          return ax
  
      def render(self, fmt='svg', **kwargs):
          return render([self], fmt, **kwargs)  # call global function
  
      def save(self, filename, **kwargs):
          return save([self], filename, **kwargs)  # call global function
  
      # for IPython notebooks
  
      def _repr_html_(self):
          """default rich format is svg plot"""
          try:
              return self._repr_svg_()
          except NotImplementedError:
              pass
          # this returns  the same as _repr_png_, but is Table compatible
          buffer = self.render('png')
          s = base64.b64encode(buffer).decode('utf-8')
          return '<img src="data:image/png;base64,%s">' % s
  
      def html(self, **kwargs):
          from IPython.display import HTML
          return HTML(self._repr_html_(**kwargs))
  
      def svg(self, **kwargs):
          from IPython.display import SVG
          return SVG(self._repr_svg_(**kwargs))
  
      def _repr_svg_(self, **kwargs):
          return self.render(fmt='svg', **kwargs).decode('utf-8')
  
      def png(self, **kwargs):
          from IPython.display import Image
          return Image(self._repr_png_(**kwargs), embed=True)
  
      def _repr_png_(self, **kwargs):
          return self.render(fmt='png', **kwargs)
  
      def plot(self, **kwargs):
          """ renders on IPython Notebook
          (alias to make usage more straightforward)
          """
          return self.svg(**kwargs)
  
  
  def render(plotables, fmt='svg', **kwargs):
      """renders several Plot objects"""
      import matplotlib.pyplot as plt
  
      # extract optional arguments used for rasterization
      printargs, kwargs = itertools2.dictsplit(
          kwargs,
          ['dpi', 'transparent', 'facecolor', 'background', 'figsize']
      )
  
      ylim = kwargs.pop('ylim', None)
      xlim = kwargs.pop('xlim', None)
      title = kwargs.pop('title', None)
  
      fig, ax = plt.subplots()
  
      labels = kwargs.pop('labels', [None] * len(plotables))
      # slightly shift the points to make superimposed curves more visible
      offset = kwargs.pop('offset', 0)
  
      for i, obj in enumerate(plotables):
          if labels[i] is None:
              labels[i] = str(obj)
          if not title:
              try:
                  title = obj._repr_latex_()
                  # check that title can be used in matplotlib
                  from matplotlib.mathtext import MathTextParser
                  parser = MathTextParser('path').parse(title)
              except Exception as e:
                  title = labels[i]
          ax = obj._plot(ax, label=labels[i], offset=i * offset, **kwargs)
  
      if ylim:
          plt.ylim(ylim)
      if xlim:
          plt.xlim(xlim)
  
      ax.set_title(title)
  
      if len(labels) > 1:
          ax.legend()
  
      output = io.BytesIO()
      fig.savefig(output, format=fmt, **printargs)
      data = output.getvalue()
      plt.close(fig)
      return data
  
  
  def png(plotables, **kwargs):
      from IPython.display import Image
      return Image(render(plotables, 'png', **kwargs), embed=True)
  
  
  def svg(plotables, **kwargs):
      from IPython.display import SVG
      return SVG(render(plotables, 'svg', **kwargs))
  
  
  plot = svg
  
  
  def save(plotables, filename, **kwargs):
      ext = filename.split('.')[-1].lower()
      kwargs.setdefault('dpi', 600)  # force good quality
      return open(filename, 'wb').write(render(plotables, ext, **kwargs))
  