Repository: DistrictDataLabs/yellowbrick

Issue:
Modify ResisdualsPlot histogram to optionally use a PDF
Because the training data set is usually much larger than the test data set, adding an option to normalize the histogram by using a PDF instead of pure frequency may make comparing the train and test set residuals distribution easier. 

Right now the histogram is drawn on the plot if the argument `hist=True`; we can change this argument to accept a string or a boolean, e.g. `hist=True` or `hist='density'` draws the PDF, `hist='frequency'` draws the normal histogram, and `hist=None` or `hist=False` does not draw the histogram at all. Alternatively, we can simply add another boolean argument, `density=True` to the visualizer if that is more understandable. 

The histogram is drawn on [line 508](https://github.com/DistrictDataLabs/yellowbrick/blob/develop/yellowbrick/regressor/residuals.py#L507), to use the PDF, pass `density=True` to the `hist()` function. 


Discussion:

Resolving patch:
diff --git a/yellowbrick/regressor/residuals.py b/yellowbrick/regressor/residuals.py
--- a/yellowbrick/regressor/residuals.py
+++ b/yellowbrick/regressor/residuals.py
@@ -334,9 +334,11 @@ class ResidualsPlot(RegressionScoreVisualizer):
         The axes to plot the figure on. If None is passed in the current axes
         will be used (or generated if required).
 
-    hist : bool, default: True
+    hist : {True, False, None, 'density', 'frequency'}, default: True
         Draw a histogram showing the distribution of the residuals on the
         right side of the figure. Requires Matplotlib >= 2.0.2.
+        If set to 'density', the probability density function will be plotted.
+        If set to True or 'frequency' then the frequency will be plotted.  
 
     train_color : color, default: 'b'
         Residuals for training data are ploted with this color but also
@@ -385,9 +387,15 @@ def __init__(self, model, ax=None, hist=True, train_color='b',
             'test_point': test_color,
             'line': line_color,
         }
-
+        
         self.hist = hist
-        if self.hist:
+        if self.hist not in {True, 'density', 'frequency', None, False}:
+                raise YellowbrickValueError(
+                    "'{}' is an invalid argument for hist, use None, True, " \
+                    "False, 'density', or 'frequency'".format(hist)
+                )
+
+        if self.hist in {True, 'density', 'frequency'}:
             self.hax # If hist is True, test the version availability
 
     @memoized
@@ -503,9 +511,11 @@ def draw(self, y_pred, residuals, train=False, **kwargs):
         # Draw the residuals scatter plot
         self.ax.scatter(y_pred, residuals, c=color, alpha=alpha, label=label)
 
-        # Add residuals histogram histogram
-        if self.hist:
+        # Add residuals histogram
+        if self.hist in {True, 'frequency'}:
             self.hax.hist(residuals, bins=50, orientation="horizontal")
+        elif self.hist == 'density':
+            self.hax.hist(residuals, bins=50, orientation="horizontal", density=True)
 
         # Ensure the current axes is always the main residuals axes
         plt.sca(self.ax)
@@ -575,9 +585,11 @@ def residuals_plot(model,
         The axes to plot the figure on. If None is passed in the current axes
         will be used (or generated if required).
 
-    hist : bool, default: True
+    hist : {True, False, None, 'density', 'frequency'}, default: True
         Draw a histogram showing the distribution of the residuals on the
         right side of the figure. Requires Matplotlib >= 2.0.2.
+        If set to 'density', the probability density function will be plotted.
+        If set to True or 'frequency' then the frequency will be plotted.  
 
     test_size : float, int default: 0.25
         If float, should be between 0.0 and 1.0 and represent the proportion


Test patch: