docs: def plot_ic_ts(ic, ax=None):
      """
      Plots Spearman Rank Information Coefficient and IC moving
      average for a given factor.
  
      Parameters
      ----------
      ic : pd.DataFrame
          DataFrame indexed by date, with IC for each forward return.
      ax : matplotlib.Axes, optional
          Axes upon which to plot.
  
      Returns
      -------
      ax : matplotlib.Axes
          The axes that were plotted on.
      """
      ic = ic.copy()
  
      num_plots = len(ic.columns)
      if ax is None:
          f, ax = plt.subplots(num_plots, 1, figsize=(18, num_plots * 7))
          ax = np.asarray([ax]).flatten()
  
      ymin, ymax = (None, None)
      for a, (period_num, ic) in zip(ax, ic.iteritems()):
          ic.plot(alpha=0.7, ax=a, lw=0.7, color='steelblue')
          ic.rolling(window=22).mean().plot(
              ax=a,
              color='forestgreen',
              lw=2,
              alpha=0.8
          )
  
          a.set(ylabel='IC', xlabel="")
          a.set_title(
              "{} Period Forward Return Information Coefficient (IC)"
              .format(period_num))
          a.axhline(0.0, linestyle='-', color='black', lw=1, alpha=0.8)
          a.legend(['IC', '1 month moving avg'], loc='upper right')
          a.text(.05, .95, "Mean %.3f \n Std. %.3f" % (ic.mean(), ic.std()),
                 fontsize=16,
                 bbox={'facecolor': 'white', 'alpha': 1, 'pad': 5},
                 transform=a.transAxes,
                 verticalalignment='top')
  
          curr_ymin, curr_ymax = a.get_ylim()
          ymin = curr_ymin if ymin is None else min(ymin, curr_ymin)
          ymax = curr_ymax if ymax is None else max(ymax, curr_ymax)
  
      for a in ax:
          a.set_ylim([ymin, ymax])
  
      return ax