parameters: (data, labels, color=None, title='', xlimit=4.0, mae=None, mape=None,
      mousetext=None, mouselink=None, mouseimag=None, mousetitle=None, mousediv=None,
      labeled=True, view=True,
      saveas=None, relpath=False, graphicsformat=['pdf'])
docstring: Generates a tiered slat diagram between model chemistries with
      errors (or simply values) in list *data*, which is supplied as part of the
      dictionary for each participating reaction, along with *dbse* and *rxn* keys
      in argument *data*. The plot is labeled with *title* and each tier with
      an element of *labels* and plotted at *xlimit* from the zero-line. If
      *color* is None, slats are black, if 'sapt', colors are taken from *color*
      key in *data* [0, 1]. Summary statistics *mae* are plotted on the
      overbound side and relative statistics *mape* on the underbound side.
      HTML code for mouseover if mousetext or mouselink or mouseimag specified
      based on recipe of Andrew Dalke from
      http://www.dalkescientific.com/writings/diary/archive/2005/04/24/interactive_html.html
docstring_summary: Generates a tiered slat diagram between model chemistries with
      errors (or simply values) in list *data*, which is supplied as part of the
      dictionary for each participating reaction, along with *dbse* and *rxn* keys
      in argument *data*. The plot is labeled with *title* and each tier with
      an element of *labels* and plotted at *xlimit* from the zero-line. If
      *color* is None, slats are black, if 'sapt', colors are taken from *color*
      key in *data* [0, 1]. Summary statistics *mae* are plotted on the
      overbound side and relative statistics *mape* on the underbound side.
      HTML code for mouseover if mousetext or mouselink or mouseimag specified
      based on recipe of Andrew Dalke from
      http://www.dalkescientific.com/writings/diary/archive/2005/04/24/interactive_html.html
docstring_tokens: Generates a tiered slat diagram between model chemistries with errors ( or simply values ) in list * data * which is supplied as part of the dictionary for each participating reaction along with * dbse * and * rxn * keys in argument * data * . The plot is labeled with * title * and each tier with an element of * labels * and plotted at * xlimit * from the zero - line . If * color * is None slats are black if sapt colors are taken from * color * key in * data * [ 0 1 ] . Summary statistics * mae * are plotted on the overbound side and relative statistics * mape * on the underbound side . HTML code for mouseover if mousetext or mouselink or mouseimag specified based on recipe of Andrew Dalke from http : // www . dalkescientific . com / writings / diary / archive / 2005 / 04 / 24 / interactive_html . html
function: def threads(data, labels, color=None, title='', xlimit=4.0, mae=None, mape=None,
      mousetext=None, mouselink=None, mouseimag=None, mousetitle=None, mousediv=None,
      labeled=True, view=True,
      saveas=None, relpath=False, graphicsformat=['pdf']):
      """Generates a tiered slat diagram between model chemistries with
      errors (or simply values) in list *data*, which is supplied as part of the
      dictionary for each participating reaction, along with *dbse* and *rxn* keys
      in argument *data*. The plot is labeled with *title* and each tier with
      an element of *labels* and plotted at *xlimit* from the zero-line. If
      *color* is None, slats are black, if 'sapt', colors are taken from *color*
      key in *data* [0, 1]. Summary statistics *mae* are plotted on the
      overbound side and relative statistics *mape* on the underbound side.
      HTML code for mouseover if mousetext or mouselink or mouseimag specified
      based on recipe of Andrew Dalke from
      http://www.dalkescientific.com/writings/diary/archive/2005/04/24/interactive_html.html
  
      """
      import random
      import hashlib
      import matplotlib.pyplot as plt
      import numpy as np  # only needed for missing data with mouseiness
  
      # initialize tiers/wefts
      Nweft = len(labels)
      lenS = 0.2
      gapT = 0.04
      positions = range(-1, -1 * Nweft - 1, -1)
      posnS = []
      for weft in range(Nweft):
          posnS.extend([positions[weft] + lenS, positions[weft] - lenS, None])
      posnT = []
      for weft in range(Nweft - 1):
          posnT.extend([positions[weft] - lenS - gapT, positions[weft + 1] + lenS + gapT, None])
      posnM = []
  
      # initialize plot
      fht = Nweft * 0.8
      #fig, ax = plt.subplots(figsize=(12, fht))
      fig, ax = plt.subplots(figsize=(11, fht))
      plt.subplots_adjust(left=0.01, right=0.99, hspace=0.3)
      plt.xlim([-xlimit, xlimit])
      plt.ylim([-1 * Nweft - 1, 0])
      plt.yticks([])
      ax.set_frame_on(False)
      if labeled:
          ax.set_xticks([-0.5 * xlimit, -0.25 * xlimit, 0.0, 0.25 * xlimit, 0.5 * xlimit])
      else:
          ax.set_xticks([])
      for tick in ax.xaxis.get_major_ticks():
          tick.tick1line.set_markersize(0)
          tick.tick2line.set_markersize(0)
  
      # label plot and tiers
      if labeled:
          ax.text(-0.9 * xlimit, -0.25, title,
              verticalalignment='bottom', horizontalalignment='left',
              family='Times New Roman', weight='bold', fontsize=12)
          for weft in labels:
              ax.text(-0.9 * xlimit, -(1.2 + labels.index(weft)), weft,
                  verticalalignment='bottom', horizontalalignment='left',
                  family='Times New Roman', weight='bold', fontsize=18)
  
      # plot reaction errors and threads
      for rxn in data:
  
          # preparation
          xvals = rxn['data']
          clr = segment_color(color, rxn['color'] if 'color' in rxn else None)
          slat = []
          for weft in range(Nweft):
              slat.extend([xvals[weft], xvals[weft], None])
          thread = []
          for weft in range(Nweft - 1):
              thread.extend([xvals[weft], xvals[weft + 1], None])
  
          # plotting
          if Nweft == 1:
              ax.plot(slat, posnS, '|', color=clr, markersize=20.0, mew=1.5, solid_capstyle='round')
          else:
              ax.plot(slat, posnS, color=clr, linewidth=1.0, solid_capstyle='round')
          ax.plot(thread, posnT, color=clr, linewidth=0.5, solid_capstyle='round', alpha=0.3)
  
          # converting into screen coordinates for image map
          # block not working for py3 or up-to-date mpl. better ways for html image map nowadays
          #npxvals = [np.nan if val is None else val for val in xvals]
          #xyscreen = ax.transData.transform(zip(npxvals, positions))
          #xscreen, yscreen = zip(*xyscreen)
          #posnM.extend(zip([rxn['db']] * Nweft, [rxn['sys']] * Nweft,
          #    npxvals, [rxn['show']] * Nweft, xscreen, yscreen))
  
          # labeling
          if not(mousetext or mouselink or mouseimag):
              if labeled and len(data) < 200:
                  try:
                      toplblposn = next(item for item in xvals if item is not None)
                      botlblposn = next(item for item in reversed(xvals) if item is not None)
                  except StopIteration:
                      pass
                  else:
                      ax.text(toplblposn, -0.75 + 0.6 * random.random(), rxn['sys'],
                          verticalalignment='bottom', horizontalalignment='center',
                          family='Times New Roman', fontsize=8)
                      ax.text(botlblposn, -1 * Nweft - 0.75 + 0.6 * random.random(), rxn['sys'],
                          verticalalignment='bottom', horizontalalignment='center',
                          family='Times New Roman', fontsize=8)
  
      # plot trimmings
      if mae is not None:
          ax.plot([-x for x in mae], positions, 's', color='black')
      if labeled:
          if mape is not None:  # equivalent to MAE for a 10 kcal/mol IE
              ax.plot([0.025 * x for x in mape], positions, 'o', color='black')
          plt.axvline(0, color='#cccc00')
  
      # save and show
      pltuid = title + '_' + ('lbld' if labeled else 'bare') + '_' + hashlib.sha1((title + repr(labels) + repr(xlimit)).encode()).hexdigest()
      pltfile = expand_saveas(saveas, pltuid, def_prefix='thread_', relpath=relpath)
      files_saved = {}
      for ext in graphicsformat:
          savefile = pltfile + '.' + ext.lower()
          plt.savefig(savefile, transparent=True, format=ext, bbox_inches='tight')
          files_saved[ext.lower()] = savefile
      if view:
          plt.show()
  
      if not (mousetext or mouselink or mouseimag):
          plt.close()
          return files_saved, None
      else:
          dpi = 80
          img_width = fig.get_figwidth() * dpi
          img_height = fig.get_figheight() * dpi
  
          htmlcode = """<SCRIPT>\n"""
          htmlcode += """function mouseshow(db, rxn, val, show) {\n"""
          if mousetext or mouselink:
              htmlcode += """   var cid = document.getElementById("cid");\n"""
              if mousetext:
                  htmlcode += """   cid.innerHTML = %s;\n""" % (mousetext)
              if mouselink:
                  htmlcode += """   cid.href = %s;\n""" % (mouselink)
          if mouseimag:
              htmlcode += """   var cmpd_img = document.getElementById("cmpd_img");\n"""
              htmlcode += """   cmpd_img.src = %s;\n""" % (mouseimag)
          htmlcode += """}\n"""
          htmlcode += """</SCRIPT>\n"""
  
          if mousediv:
              htmlcode += """%s\n""" % (mousediv[0])
          if mousetitle:
              htmlcode += """%s <BR>""" % (mousetitle)
          htmlcode += """<h4>Mouseover</h4><a id="cid"></a><br>\n"""
          if mouseimag:
              htmlcode += """<div class="text-center">"""
              htmlcode += """<IMG ID="cmpd_img" WIDTH="%d" HEIGHT="%d">\n""" % (200, 160)
              htmlcode += """</div>"""
          if mousediv:
              htmlcode += """%s\n""" % (mousediv[1])
          #htmlcode += """<IMG SRC="%s" ismap usemap="#points" WIDTH="%d" HEIGHT="%d">\n""" % \
          #    (pltfile + '.png', img_width, img_height)
          htmlcode += """<IMG SRC="%s" ismap usemap="#points" WIDTH="%d">\n""" % \
              (pltfile + '.png', img_width)
          htmlcode += """<MAP name="points">\n"""
  
          # generating html image map code
          #   points sorted to avoid overlapping map areas that can overwhelm html for SSI
          #   y=0 on top for html and on bottom for mpl, so flip the numbers
          posnM.sort(key=lambda tup: tup[2])
          posnM.sort(key=lambda tup: tup[3])
          last = (0, 0)
          for dbse, rxn, val, show, x, y in posnM:
              if val is None or val is np.nan:
                  continue
  
              now = (int(x), int(y))
              if now == last:
                  htmlcode += """<!-- map overlap! %s-%s %+.2f skipped -->\n""" % (dbse, rxn, val)
              else:
                  htmlcode += """<AREA shape="rect" coords="%d,%d,%d,%d" onmouseover="javascript:mouseshow('%s', '%s', '%+.2f', '%s');">\n""" % \
                      (x - 2, img_height - y - 20,
                      x + 2, img_height - y + 20,
                      dbse, rxn, val, show)
                  last = now
  
          htmlcode += """</MAP>\n"""
  
          plt.close()
          return files_saved, htmlcode
function_tokens: def threads ( data , labels , color = None , title = '' , xlimit = 4.0 , mae = None , mape = None , mousetext = None , mouselink = None , mouseimag = None , mousetitle = None , mousediv = None , labeled = True , view = True , saveas = None , relpath = False , graphicsformat = [ 'pdf' ] ) : import random import hashlib import matplotlib . pyplot as plt import numpy as np # only needed for missing data with mouseiness # initialize tiers/wefts Nweft = len ( labels ) lenS = 0.2 gapT = 0.04 positions = range ( - 1 , - 1 * Nweft - 1 , - 1 ) posnS = [ ] for weft in range ( Nweft ) : posnS . extend ( [ positions [ weft ] + lenS , positions [ weft ] - lenS , None ] ) posnT = [ ] for weft in range ( Nweft - 1 ) : posnT . extend ( [ positions [ weft ] - lenS - gapT , positions [ weft + 1 ] + lenS + gapT , None ] ) posnM = [ ] # initialize plot fht = Nweft * 0.8 #fig, ax = plt.subplots(figsize=(12, fht)) fig , ax = plt . subplots ( figsize = ( 11 , fht ) ) plt . subplots_adjust ( left = 0.01 , right = 0.99 , hspace = 0.3 ) plt . xlim ( [ - xlimit , xlimit ] ) plt . ylim ( [ - 1 * Nweft - 1 , 0 ] ) plt . yticks ( [ ] ) ax . set_frame_on ( False ) if labeled : ax . set_xticks ( [ - 0.5 * xlimit , - 0.25 * xlimit , 0.0 , 0.25 * xlimit , 0.5 * xlimit ] ) else : ax . set_xticks ( [ ] ) for tick in ax . xaxis . get_major_ticks ( ) : tick . tick1line . set_markersize ( 0 ) tick . tick2line . set_markersize ( 0 ) # label plot and tiers if labeled : ax . text ( - 0.9 * xlimit , - 0.25 , title , verticalalignment = 'bottom' , horizontalalignment = 'left' , family = 'Times New Roman' , weight = 'bold' , fontsize = 12 ) for weft in labels : ax . text ( - 0.9 * xlimit , - ( 1.2 + labels . index ( weft ) ) , weft , verticalalignment = 'bottom' , horizontalalignment = 'left' , family = 'Times New Roman' , weight = 'bold' , fontsize = 18 ) # plot reaction errors and threads for rxn in data : # preparation xvals = rxn [ 'data' ] clr = segment_color ( color , rxn [ 'color' ] if 'color' in rxn else None ) slat = [ ] for weft in range ( Nweft ) : slat . extend ( [ xvals [ weft ] , xvals [ weft ] , None ] ) thread = [ ] for weft in range ( Nweft - 1 ) : thread . extend ( [ xvals [ weft ] , xvals [ weft + 1 ] , None ] ) # plotting if Nweft == 1 : ax . plot ( slat , posnS , '|' , color = clr , markersize = 20.0 , mew = 1.5 , solid_capstyle = 'round' ) else : ax . plot ( slat , posnS , color = clr , linewidth = 1.0 , solid_capstyle = 'round' ) ax . plot ( thread , posnT , color = clr , linewidth = 0.5 , solid_capstyle = 'round' , alpha = 0.3 ) # converting into screen coordinates for image map # block not working for py3 or up-to-date mpl. better ways for html image map nowadays #npxvals = [np.nan if val is None else val for val in xvals] #xyscreen = ax.transData.transform(zip(npxvals, positions)) #xscreen, yscreen = zip(*xyscreen) #posnM.extend(zip([rxn['db']] * Nweft, [rxn['sys']] * Nweft, #    npxvals, [rxn['show']] * Nweft, xscreen, yscreen)) # labeling if not ( mousetext or mouselink or mouseimag ) : if labeled and len ( data ) < 200 : try : toplblposn = next ( item for item in xvals if item is not None ) botlblposn = next ( item for item in reversed ( xvals ) if item is not None ) except StopIteration : pass else : ax . text ( toplblposn , - 0.75 + 0.6 * random . random ( ) , rxn [ 'sys' ] , verticalalignment = 'bottom' , horizontalalignment = 'center' , family = 'Times New Roman' , fontsize = 8 ) ax . text ( botlblposn , - 1 * Nweft - 0.75 + 0.6 * random . random ( ) , rxn [ 'sys' ] , verticalalignment = 'bottom' , horizontalalignment = 'center' , family = 'Times New Roman' , fontsize = 8 ) # plot trimmings if mae is not None : ax . plot ( [ - x for x in mae ] , positions , 's' , color = 'black' ) if labeled : if mape is not None : # equivalent to MAE for a 10 kcal/mol IE ax . plot ( [ 0.025 * x for x in mape ] , positions , 'o' , color = 'black' ) plt . axvline ( 0 , color = '#cccc00' ) # save and show pltuid = title + '_' + ( 'lbld' if labeled else 'bare' ) + '_' + hashlib . sha1 ( ( title + repr ( labels ) + repr ( xlimit ) ) . encode ( ) ) . hexdigest ( ) pltfile = expand_saveas ( saveas , pltuid , def_prefix = 'thread_' , relpath = relpath ) files_saved = { } for ext in graphicsformat : savefile = pltfile + '.' + ext . lower ( ) plt . savefig ( savefile , transparent = True , format = ext , bbox_inches = 'tight' ) files_saved [ ext . lower ( ) ] = savefile if view : plt . show ( ) if not ( mousetext or mouselink or mouseimag ) : plt . close ( ) return files_saved , None else : dpi = 80 img_width = fig . get_figwidth ( ) * dpi img_height = fig . get_figheight ( ) * dpi htmlcode = """<SCRIPT>\n""" htmlcode += """function mouseshow(db, rxn, val, show) {\n""" if mousetext or mouselink : htmlcode += """   var cid = document.getElementById("cid");\n""" if mousetext : htmlcode += """   cid.innerHTML = %s;\n""" % ( mousetext ) if mouselink : htmlcode += """   cid.href = %s;\n""" % ( mouselink ) if mouseimag : htmlcode += """   var cmpd_img = document.getElementById("cmpd_img");\n""" htmlcode += """   cmpd_img.src = %s;\n""" % ( mouseimag ) htmlcode += """}\n""" htmlcode += """</SCRIPT>\n""" if mousediv : htmlcode += """%s\n""" % ( mousediv [ 0 ] ) if mousetitle : htmlcode += """%s <BR>""" % ( mousetitle ) htmlcode += """<h4>Mouseover</h4><a id="cid"></a><br>\n""" if mouseimag : htmlcode += """<div class="text-center">""" htmlcode += """<IMG ID="cmpd_img" WIDTH="%d" HEIGHT="%d">\n""" % ( 200 , 160 ) htmlcode += """</div>""" if mousediv : htmlcode += """%s\n""" % ( mousediv [ 1 ] ) #htmlcode += """<IMG SRC="%s" ismap usemap="#points" WIDTH="%d" HEIGHT="%d">\n""" % \ #    (pltfile + '.png', img_width, img_height) htmlcode += """<IMG SRC="%s" ismap usemap="#points" WIDTH="%d">\n""" % ( pltfile + '.png' , img_width ) htmlcode += """<MAP name="points">\n""" # generating html image map code #   points sorted to avoid overlapping map areas that can overwhelm html for SSI #   y=0 on top for html and on bottom for mpl, so flip the numbers posnM . sort ( key = lambda tup : tup [ 2 ] ) posnM . sort ( key = lambda tup : tup [ 3 ] ) last = ( 0 , 0 ) for dbse , rxn , val , show , x , y in posnM : if val is None or val is np . nan : continue now = ( int ( x ) , int ( y ) ) if now == last : htmlcode += """<!-- map overlap! %s-%s %+.2f skipped -->\n""" % ( dbse , rxn , val ) else : htmlcode += """<AREA shape="rect" coords="%d,%d,%d,%d" onmouseover="javascript:mouseshow('%s', '%s', '%+.2f', '%s');">\n""" % ( x - 2 , img_height - y - 20 , x + 2 , img_height - y + 20 , dbse , rxn , val , show ) last = now htmlcode += """</MAP>\n""" plt . close ( ) return files_saved , htmlcode