docs: def allele_plot(file, normalize=False, alleles=None, generations=None):
      """Plot the alleles from each generation from the individuals file.
      
      This function creates a plot of the individual allele values as they
      change through the generations. It creates three subplots, one for each
      of the best, median, and average individual. The best and median 
      individuals are chosen using the fitness data for each generation. The 
      average individual, on the other hand, is actually an individual created
      by averaging the alleles within a generation. This function requires the 
      matplotlib library.
  
      .. note::
      
         This function only works for single-objective problems.
  
      .. figure:: _static/allele_plot.png
          :alt: Example allele plot
          :align: center
          
          An example image saved from the ``allele_plot`` function.
      
      Arguments:
      
      - *file* -- a file-like object representing the individuals file 
        produced by the file_observer 
      - *normalize* -- Boolean value stating whether allele values should be
        normalized before plotting (default False)
      - *alleles* -- a list of allele index values that should be plotted
        (default None)
      - *generations* -- a list of generation numbers that should be plotted
        (default None)
  
      If *alleles* is ``None``, then all alleles are plotted. Similarly, if 
      *generations* is ``None``, then all generations are plotted.
  
      """    
      import matplotlib.pyplot as plt
      
      generation_data = []
      reader = csv.reader(open(file))
      for row in reader:
          g = int(row[0])
          row[3] = row[3].replace('[', '')
          row[-1] = row[-1].replace(']', '')
          individual = [float(r) for r in row[3:]]
          individual.append(float(row[2]))
          try:
              generation_data[g]
          except IndexError:
              generation_data.append([])
          generation_data[g].append(individual)
      for gen in generation_data:
          gen.sort(key=lambda x: x[-1])
          for j, g in enumerate(gen):
              gen[j] = g[:-1]
          
      best = []
      median = []
      average = []
      for gen in generation_data:
          best.append(gen[0])
          plen = len(gen)
          if plen % 2 == 1:
              med = gen[(plen - 1) // 2]
          else:
              med = []
              for a, b in zip(gen[plen // 2 - 1], gen[plen // 2]):
                  med.append(float(a + b) / 2)
          median.append(med)
          avg = [0] * len(gen[0])
          for individual in gen:
              for i, allele in enumerate(individual):
                  avg[i] += allele
          for i, a in enumerate(avg):
              avg[i] /= float(len(gen))
          average.append(avg)        
      
      for plot_num, (data, title) in enumerate(zip([best, median, average], 
                                                   ["Best", "Median", "Average"])):
          if alleles is None:
              alleles = list(range(len(data[0])))
          if generations is None:
              generations = list(range(len(data)))    
          if normalize:
              columns = list(zip(*data))
              max_col = [max(c) for c in columns]
              min_col = [min(c) for c in columns]
              for dat in data:
                  for i, d in enumerate(dat):
                      dat[i] = (d - min_col[i]) / float(max_col[i] - min_col[i])
          plot_data = []
          for g in generations:
              plot_data.append([data[g][a] for a in alleles])
          sub = plt.subplot(3, 1, plot_num + 1)
          plt.pcolor(plt.array(plot_data))
          plt.colorbar()
          step_size = max(len(generations) // 7, 1)
          ytick_locs = list(range(step_size, len(generations), step_size))
          ytick_labs = generations[step_size::step_size]
          plt.yticks(ytick_locs, ytick_labs)
          plt.ylabel('Generation')
          if plot_num == 2:
              xtick_locs = list(range(len(alleles)))
              xtick_labs = alleles
              plt.xticks(xtick_locs, xtick_labs)
              plt.xlabel('Allele')
          else:
              plt.setp(sub.get_xticklabels(), visible=False)
          plt.title(title)
      plt.show()