docs: def plotRaster (include = ['allCells'], timeRange = None, maxSpikes = 1e8, orderBy = 'gid', orderInverse = False, labels = 'legend', popRates = False,
          spikeHist=None, spikeHistBin=5, syncLines=False, lw=2, marker='|', markerSize=5, popColors=None, figSize=(10, 8), fontSize=12,
          dpi = 100, saveData = None, saveFig = None, showFig = True):
      '''
      Raster plot of network cells
          - include (['all',|'allCells',|'allNetStims',|,120,|,'E1'|,('L2', 56)|,('L5',[4,5,6])]): Cells to include (default: 'allCells')
          - timeRange ([start:stop]): Time range of spikes shown; if None shows all (default: None)
          - maxSpikes (int): maximum number of spikes that will be plotted  (default: 1e8)
          - orderBy ('gid'|'y'|'ynorm'|...): Unique numeric cell property to order y-axis by, e.g. 'gid', 'ynorm', 'y' (default: 'gid')
          - orderInverse (True|False): Invert the y-axis order (default: False)
          - labels = ('legend', 'overlay'): Show population labels in a legend or overlayed on one side of raster (default: 'legend')
          - popRates = (True|False): Include population rates (default: False)
          - spikeHist (None|'overlay'|'subplot'): overlay line over raster showing spike histogram (spikes/bin) (default: False)
          - spikeHistBin (int): Size of bin in ms to use for histogram (default: 5)
          - syncLines (True|False): calculate synchorny measure and plot vertical lines for each spike to evidence synchrony (default: False)
          - lw (integer): Line width for each spike (default: 2)
          - marker (char): Marker for each spike (default: '|')
          - popColors (odict): Dictionary with color (value) used for each population (key) (default: None)
          - figSize ((width, height)): Size of figure (default: (10,8))
          - dpi (int): Dots per inch to save fig (default: 100)
          - saveData (None|True|'fileName'): File name where to save the final data used to generate the figure;
              if set to True uses filename from simConfig (default: None)
          - saveFig (None|True|'fileName'): File name where to save the figure (default: None)
              if set to True uses filename from simConfig (default: None)
          - showFig (True|False): Whether to show the figure or not (default: True)
          - Returns figure handle
      '''
  
      from .. import sim
  
      print('Plotting raster...')
  
      # Select cells to include
      cells, cellGids, netStimLabels = getCellsInclude(include)
  
      df = pd.DataFrame.from_records(cells)
      df = pd.concat([df.drop('tags', axis=1), pd.DataFrame.from_records(df['tags'].tolist())], axis=1)
  
      keep = ['pop', 'gid', 'conns']
  
      if isinstance(orderBy, basestring) and orderBy not in cells[0]['tags']:  # if orderBy property doesn't exist or is not numeric, use gid
          orderBy = 'gid'
      elif orderBy is 'pop':
          df['popInd'] = df['pop'].astype('category')
          df['popInd'].cat.set_categories(sim.net.pops.keys(), inplace=True)
          orderBy='popInd'
      elif isinstance(orderBy, basestring) and not isinstance(cells[0]['tags'][orderBy], Number):
          orderBy = 'gid'
          
      if isinstance(orderBy, list):
          if 'pop' in orderBy:
              df['popInd'] = df['pop'].astype('category')
              df['popInd'].cat.set_categories(sim.net.pops.keys(), inplace=True)
              orderBy[orderBy.index('pop')] = 'popInd'
          keep = keep + list(set(orderBy) - set(keep))
      elif orderBy not in keep:
          keep.append(orderBy)
      df = df[keep]
  
      popLabels = [pop for pop in sim.net.allPops if pop in df['pop'].unique()] #preserves original ordering
      if netStimLabels: popLabels.append('NetStims')
      popColorsTmp = {popLabel: colorList[ipop%len(colorList)] for ipop,popLabel in enumerate(popLabels)} # dict with color for each pop
      if popColors: popColorsTmp.update(popColors)
      popColors = popColorsTmp
      if len(cellGids) > 0:
          gidColors = {cell['gid']: popColors[cell['tags']['pop']] for cell in cells}  # dict with color for each gid
          try:
              sel, spkts,spkgids = getSpktSpkid(cellGids=cellGids, timeRange=timeRange, allCells=(include == ['allCells']))
          except:
              import sys
              print((sys.exc_info()))
              spkgids, spkts = [], []
              sel = pd.DataFrame(columns=['spkt', 'spkid'])
          sel['spkgidColor'] = sel['spkid'].map(gidColors)
          df['gidColor'] = df['pop'].map(popColors)
          df.set_index('gid', inplace=True)
  
  
      # Order by
      if len(df) > 0:
          ylabelText = 'Cells (ordered by %s)'%(orderBy)
          df = df.sort_values(by=orderBy)
          sel['spkind'] = sel['spkid'].apply(df.index.get_loc)
  
      else:
          sel = pd.DataFrame(columns=['spkt', 'spkid', 'spkind'])
          ylabelText = ''
  
      # Add NetStim spikes
      numCellSpks = len(sel)
      numNetStims = 0
      for netStimLabel in netStimLabels:
          netStimSpks = [spk for cell,stims in sim.allSimData['stims'].items() \
              for stimLabel,stimSpks in stims.items() for spk in stimSpks if stimLabel == netStimLabel]
          if len(netStimSpks) > 0:
              # lastInd = max(spkinds) if len(spkinds)>0 else 0
              lastInd = sel['spkind'].max() if len(sel['spkind']) > 0 else 0
              spktsNew = netStimSpks
              spkindsNew = [lastInd+1+i for i in range(len(netStimSpks))]
              ns = pd.DataFrame(list(zip(spktsNew, spkindsNew)), columns=['spkt', 'spkind'])
              ns['spkgidColor'] = popColors['netStims']
              sel = pd.concat([sel, ns])
              numNetStims += 1
          else:
              pass
              #print netStimLabel+' produced no spikes'
      if len(cellGids)>0 and numNetStims:
          ylabelText = ylabelText + ' and NetStims (at the end)'
      elif numNetStims:
          ylabelText = ylabelText + 'NetStims'
  
      if numCellSpks+numNetStims == 0:
          print('No spikes available to plot raster')
          return None
  
      # Time Range
      if timeRange == [0,sim.cfg.duration]:
          pass
      elif timeRange is None:
          timeRange = [0,sim.cfg.duration]
      else:
          sel = sel.query('spkt >= @timeRange[0] and spkt <= @timeRange[1]')
  
  
      # Limit to maxSpikes
      if (len(sel)>maxSpikes):
          print(('  Showing only the first %i out of %i spikes' % (maxSpikes, len(sel)))) # Limit num of spikes
          if numNetStims: # sort first if have netStims
              sel = sel.sort_values(by='spkt')
          sel = sel.iloc[:maxSpikes]
          timeRange[1] =  sel['spkt'].max()
  
      # Calculate spike histogram
      if spikeHist:
          histo = np.histogram(sel['spkt'].tolist(), bins = np.arange(timeRange[0], timeRange[1], spikeHistBin))
          histoT = histo[1][:-1]+spikeHistBin/2
          histoCount = histo[0]
  
      # Plot spikes
      # set font size
      plt.rcParams.update({'font.size': fontSize})
  
      fig,ax1 = plt.subplots(figsize=figSize)
      fontsiz = fontSize
   
      if spikeHist == 'subplot':
          gs = gridspec.GridSpec(2, 1,height_ratios=[2,1])
          ax1=plt.subplot(gs[0])
      sel['spkt'] = sel['spkt'].apply(pd.to_numeric)
      sel.plot.scatter(ax=ax1, x='spkt', y='spkind', lw=lw, s=markerSize, marker=marker, c=sel['spkgidColor'].tolist()) # Create raster
      ax1.set_xlim(timeRange)
  
      # Plot stats
      gidPops = df['pop'].tolist()
      popNumCells = [float(gidPops.count(pop)) for pop in popLabels] if numCellSpks else [0] * len(popLabels)
      totalSpikes = len(sel)
      totalConnections = sum([len(conns) for conns in df['conns']])
      numCells = len(cells)
      firingRate = float(totalSpikes)/(numCells+numNetStims)/(timeRange[1]-timeRange[0])*1e3 if totalSpikes>0 else 0 # Calculate firing rate
      connsPerCell = totalConnections/float(numCells) if numCells>0 else 0 # Calculate the number of connections per cell
      
      if popRates:
          avgRates = {}
          tsecs = (timeRange[1]-timeRange[0])/1e3
          for i,(pop, popNum) in enumerate(zip(popLabels, popNumCells)):
              if numCells > 0 and pop != 'NetStims':
                  if numCellSpks == 0:
                      avgRates[pop] = 0
                  else:
                      avgRates[pop] = len([spkid for spkid in sel['spkind'].iloc[:numCellSpks-1] if df['pop'].iloc[int(spkid)]==pop])/popNum/tsecs
          if numNetStims:
              popNumCells[-1] = numNetStims
              avgRates['NetStims'] = len([spkid for spkid in sel['spkind'].iloc[numCellSpks:]])/numNetStims/tsecs
  
      # Plot synchrony lines
      if syncLines:
          for spkt in sel['spkt'].tolist():
              ax1.plot((spkt, spkt), (0, len(cells)+numNetStims), 'r-', linewidth=0.1)
          plt.title('cells=%i   syns/cell=%0.1f   rate=%0.1f Hz   sync=%0.2f' % (numCells,connsPerCell,firingRate,syncMeasure()), fontsize=fontsiz)
      else:
          plt.title('cells=%i   syns/cell=%0.1f   rate=%0.1f Hz' % (numCells,connsPerCell,firingRate), fontsize=fontsiz)
      # Axis
      ax1.set_xlabel('Time (ms)', fontsize=fontsiz)
      ax1.set_ylabel(ylabelText, fontsize=fontsiz)
      ax1.set_xlim(timeRange)
      ax1.set_ylim(-1, len(cells)+numNetStims+1)
  
      # Add legend
      if popRates:
          popLabelRates = [popLabel + ' (%.3g Hz)'%(avgRates[popLabel]) for popLabel in popLabels if popLabel in avgRates]
  
      if labels == 'legend':
          for ipop,popLabel in enumerate(popLabels):
              label = popLabelRates[ipop] if popRates else popLabel
              plt.plot(0,0,color=popColors[popLabel],label=label)
          plt.legend(fontsize=fontsiz, bbox_to_anchor=(1.04, 1), loc=2, borderaxespad=0.)
          maxLabelLen = max([len(l) for l in popLabels])
          rightOffset = 0.85 if popRates else 0.9
          plt.subplots_adjust(right=(rightOffset-0.012*maxLabelLen))
  
      elif labels == 'overlay':
          ax = plt.gca()
          tx = 1.01
          margin = 1.0/numCells/2
          minSpacing = float(fontsiz) * 1.1 / float((0.8*figSize[1]*dpi))
          tys = [(float(popLen)/numCells)*(1-2*margin) for popLen in popNumCells]
          tysOffset = list(scipy.cumsum(tys))[:-1]
          tysOffset = [tysOffset[0]] +[tysOffset[i] + max(tysOffset[i+1]-tysOffset[i], minSpacing) for i in range(len(tysOffset)-1)]
          tysOffset.insert(0, 0)
          labels = popLabelRates if popRates else popLabels
          for ipop,(ty, tyOffset, popLabel) in enumerate(zip(tys, tysOffset, popLabels)):
              label = popLabelRates[ipop] if popRates else popLabel
              if orderInverse:
                  finalty = 1.0 - (tyOffset + ty/2.0 + 0.01)
              else:
                  finalty = tyOffset + ty/2.0 - 0.01
              plt.text(tx, finalty, label, transform=ax.transAxes, fontsize=fontsiz, color=popColors[popLabel])
          maxLabelLen = min(6, max([len(l) for l in labels]))
          plt.subplots_adjust(right=(0.95-0.011*maxLabelLen))
  
  
      # Plot spike hist
      if spikeHist == 'overlay':
          ax2 = ax1.twinx()
          ax2.plot (histoT, histoCount, linewidth=0.5)
          ax2.set_ylabel('Spike count', fontsize=fontsiz) # add yaxis label in opposite side
          ax2.set_xlim(timeRange)
      elif spikeHist == 'subplot':
          ax2=plt.subplot(gs[1])
          ax2.plot (histoT, histoCount, linewidth=1.0)
          ax2.set_xlabel('Time (ms)', fontsize=fontsiz)
          ax2.set_ylabel('Spike count', fontsize=fontsiz)
          ax2.set_xlim(timeRange)
  
      if orderInverse: plt.gca().invert_yaxis()
  
      # save figure data
      if saveData:
          figData = {'spkTimes': sel['spkt'].tolist(), 'spkInds': sel['spkind'].tolist(), 'spkColors': sel['spkgidColor'].tolist(), 'cellGids': cellGids, 'sortedGids': df.index.tolist(), 'numNetStims': numNetStims,
          'include': include, 'timeRange': timeRange, 'maxSpikes': maxSpikes, 'orderBy': orderBy, 'orderInverse': orderInverse, 'spikeHist': spikeHist,
          'syncLines': syncLines}
          _saveFigData(figData, saveData, 'raster')
  
      # save figure
      if saveFig:
          if isinstance(saveFig, basestring):
              filename = saveFig
          else:
              filename = sim.cfg.filename+'_'+'raster.png'
          plt.savefig(filename, dpi=dpi)
  
      # show fig
      if showFig: _showFigure()
  
      return fig, {'include': include, 'spkts': spkts, 'spkinds': sel['spkind'].tolist(), 'timeRange': timeRange}