docs: def plsr(df, v, n_components=2, mean_center=False, scale=True, fcol=None, ecol=None, marker='o', markersize=40, threshold=None, label_threshold=None, label_weights=None, label_scores=None, return_df=False, show_covariance_ellipse=False, *args, **kwargs):
      """
      Partial Least Squares Regression Analysis, based on `sklearn.cross_decomposition.PLSRegression`
  
      Performs a partial least squares regression (PLS-R) on the supplied dataframe ``df``
      against the provided continuous variable ``v``, selecting the first ``n_components``.
  
      For more information on PLS regression and the algorithm used, see the `scikit-learn documentation <http://scikit-learn.org/stable/modules/generated/sklearn.cross_decomposition.PLSRegression.html>`_.
  
      Resulting scores, weights and regression plots are generated showing the distribution of samples within the resulting
      PCA space. Sample color and marker size can be controlled by label, lookup and calculation (lambda) to
      generate complex plots highlighting sample separation.
  
      For further information see the examples included in the documentation.
  
      :param df: Pandas `DataFrame`
      :param v: Continuous variable to perform regression against
      :param n_components: `int` number of Principal components to return
      :param mean_center: `bool` mean center the data before performing PCA
      :param fcol: `dict` of indexers:colors, where colors are hex colors or matplotlib color names
      :param ecol: `dict` of indexers:colors, where colors are hex colors or matplotlib color names
      :param marker: `str` matplotlib marker name (default "o")
      :param markersize: `int` or `callable` which returns an `int` for a given indexer
      :param threshold: `float` weight threshold for plot (horizontal line)
      :param label_threshold: `float` weight threshold over which to draw labels
      :param label_weights: `list` of `str`
      :param label_scores: `list` of `str`
      :param return_df: `bool` return the resulting scores, weights as pandas DataFrames
      :param show_covariance_ellipse: `bool` show the covariance ellipse around each group
      :param args: additional arguments passed to analysis.pca
      :param kwargs: additional arguments passed to analysis.pca
      :return:
      """
  
      scores, weights, loadings, predicted = analysis.plsr(df, v, n_components=n_components, scale=scale, *args, **kwargs)
  
      scores_ax = _pca_scores(scores, fcol=fcol, ecol=ecol, marker=marker, markersize=markersize, label_scores=label_scores, show_covariance_ellipse=show_covariance_ellipse)
      weights_ax = []
  
      for pc in range(0, weights.shape[1]):
          weights_ax.append( _pca_weights(weights, pc, threshold=threshold, label_threshold=label_threshold, label_weights=label_weights) )
  
      fig = plt.figure(figsize=(8, 8))
      ax = fig.add_subplot(1,1,1)
  
      slope, intercept, r, p, se = sp.stats.linregress(v, predicted.flatten())
  
      # Add regression line
      xmin, xmax = np.min(v), np.max(v)
      ax.plot([xmin, xmax],[xmin*slope+intercept, xmax*slope+intercept], lw=1, c='k')
  
      ax.scatter(v, predicted, s=50, alpha=0.5)
      ax.set_xlabel("Actual values")
      ax.set_ylabel("Predicted values")
  
      ax.set_aspect(1./ax.get_data_ratio())
  
      ax.text(0.05, 0.95, '$y = %.2f+%.2fx$' % (intercept, slope), horizontalalignment='left', transform=ax.transAxes, color='black', fontsize=14)
  
      ax.text(0.95, 0.15, '$r^2$ = %.2f' % (r**2), horizontalalignment='right', transform=ax.transAxes, color='black', fontsize=14)
      ax.text(0.95, 0.10, '$p$ = %.2f' % p, horizontalalignment='right', transform=ax.transAxes, color='black', fontsize=14)
      ax.text(0.95, 0.05, '$SE$ = %.2f' % se, horizontalalignment='right', transform=ax.transAxes, color='black', fontsize=14)
  
  
      if return_df:
          return scores, weights, loadings, predicted
      else:
          return scores_ax, weights_ax, ax