Repository: DistrictDataLabs/yellowbrick

Issue:
Complete Tests and Documentation for DispersionPlot Visualizer
To be complete, the new Dispersion Plot Visualizer requires:

- [ ] Tests
- [ ] Documentation

@DistrictDataLabs/team-oz-maintainers



Discussion:

Resolving patch:
diff --git a/docs/api/text/dispersion.py b/docs/api/text/dispersion.py
new file mode 100644
--- /dev/null
+++ b/docs/api/text/dispersion.py
@@ -0,0 +1,48 @@
+# ID: dispersion.py [] lwgray@gmail.com $
+
+"""
+Generate figures for Dispersion Plot documentation.
+"""
+
+##########################################################################
+## Imports
+##########################################################################
+
+import matplotlib.pyplot as plt
+
+from corpus import load_corpus
+from yellowbrick.text.dispersion import DispersionPlot
+
+##########################################################################
+## Generate
+##########################################################################
+
+def dispersion(target_words, text, outpath, **kwargs):
+    # Create a new figure and axes
+    _, ax = plt.subplots()
+
+    # Visualize the Dispersion of target words
+    visualizer = DispersionPlot(target_words, ax=ax, **kwargs)
+    visualizer.fit(text)
+    visualizer.poof(outpath=outpath)
+
+
+##########################################################################
+## Main Method
+##########################################################################
+
+if __name__ == '__main__':
+
+    # Load the corpus
+    corpus = load_corpus("../../../examples/data/hobbies")
+
+    # Convert corpus into a list of all words from beginning to end
+    text = [word for doc in corpus.data for word in doc.split()]
+    
+    # Select target words to visualize 
+    target_words = ['Game', 'player', 'score', 'oil', 'Man']
+
+    # Display dispersion of target words throughout corpus
+    dispersion(target_words, text, "images/dispersion_docs.png")
+
+
diff --git a/yellowbrick/text/dispersion.py b/yellowbrick/text/dispersion.py
--- a/yellowbrick/text/dispersion.py
+++ b/yellowbrick/text/dispersion.py
@@ -84,10 +84,8 @@ def fit(self, text):
             A list of words in the order they appear in the corpus.
         """
             
-        self.words.reverse()
-
         # Create an index (e.g. the y position) for the target words
-        self.target_words_ = np.array(self.words)
+        self.target_words_ = np.flip(self.words, axis=0)
         if self.ignore_case:
             self.target_words_ = np.array([w.lower() for w in self.target_words_])
         
@@ -106,8 +104,8 @@ def draw(self, points, **kwargs):
         """
         
         self.ax.scatter(points[:,0], points[:,1], marker='|', color=self.color)
-        self.ax.set_yticks(list(range(len(self.words))))
-        self.ax.set_yticklabels(self.words)
+        self.ax.set_yticks(list(range(len(self.target_words_))))
+        self.ax.set_yticklabels(self.target_words_)
         
     def finalize(self, **kwargs):
         """
@@ -118,7 +116,7 @@ def finalize(self, **kwargs):
         kwargs: generic keyword arguments.
         """
         
-        self.ax.set_ylim(-1, len(self.words))
+        self.ax.set_ylim(-1, len(self.target_words_))
         self.ax.set_title("Lexical Dispersion Plot")
         self.ax.set_xlabel("Word Offset")
         self.ax.grid(False)


Test patch:
diff --git a/tests/baseline_images/test_text/test_dispersion/test_dispersionplot_generator_input.png b/tests/baseline_images/test_text/test_dispersion/test_dispersionplot_generator_input.png
new file mode 100644
Binary files /dev/null and b/tests/baseline_images/test_text/test_dispersion/test_dispersionplot_generator_input.png differ
diff --git a/tests/baseline_images/test_text/test_dispersion/test_dispersionplot_ignore_case.png b/tests/baseline_images/test_text/test_dispersion/test_dispersionplot_ignore_case.png
new file mode 100644
Binary files /dev/null and b/tests/baseline_images/test_text/test_dispersion/test_dispersionplot_ignore_case.png differ
diff --git a/tests/baseline_images/test_text/test_dispersion/test_integrated_dispersionplot.png b/tests/baseline_images/test_text/test_dispersion/test_integrated_dispersionplot.png
new file mode 100644
Binary files /dev/null and b/tests/baseline_images/test_text/test_dispersion/test_integrated_dispersionplot.png differ
diff --git a/tests/test_text/test_dispersion.py b/tests/test_text/test_dispersion.py
new file mode 100644
--- /dev/null
+++ b/tests/test_text/test_dispersion.py
@@ -0,0 +1,82 @@
+# tests.test_text.test_dispersion
+# Tests for the dispersion plot visualization
+#
+# Author:   Larry Gray
+# Github:   @lwgray
+# Created:  2018-06-22 15:27
+#
+# Copyright (C) 2018
+# For license information, see LICENSE.txt
+#
+# ID: test_dispersion.py [] lwgray@gmail.com $
+
+"""
+Tests for the dispersion plot text visualization
+"""
+
+##########################################################################
+## Imports
+##########################################################################
+
+import sys
+import pytest
+
+from yellowbrick.text.dispersion import *
+from tests.dataset import DatasetMixin
+from tests.base import VisualTestCase
+from itertools import chain
+
+##########################################################################
+## DispersionPlot Tests
+##########################################################################
+
+@pytest.mark.xfail(sys.platform == "win32", reason="Issue #491")
+class DispersionPlotTests(VisualTestCase, DatasetMixin):
+
+    def test_integrated_dispersionplot(self):
+        """
+        Assert no errors occur during DispersionPlot integration
+        """
+        corpus = self.load_data('hobbies')
+	
+        text = [word for doc in corpus.data for word in doc.split()]
+        target_words = ['Game', 'player', 'score', 'oil', 'Man']
+
+        visualizer = DispersionPlot(target_words)
+        visualizer.fit(text)
+        visualizer.ax.grid(False)
+
+        self.assert_images_similar(visualizer, tol=25)
+
+    def test_dispersionplot_ignore_case(self):
+        """
+        Assert no errors occur during DispersionPlot integration
+        with ignore_case parameter turned on
+        """
+        corpus = self.load_data('hobbies')
+	
+        text = [word for doc in corpus.data for word in doc.split()]
+        target_words = ['Game', 'player', 'score', 'oil', 'Man']
+
+        visualizer = DispersionPlot(target_words, ignore_case=True)
+        visualizer.fit(text)
+        visualizer.ax.grid(False)
+
+        self.assert_images_similar(visualizer, tol=25)
+
+    def test_dispersionplot_generator_input(self):
+        """
+        Assert no errors occur during dispersionPlot integration
+        when the corpus' text type is a generator
+        """
+        corpus = self.load_data('hobbies')
+
+        text = chain(*map(str.split, corpus.data))
+        target_words = ['Game', 'player', 'score', 'oil', 'Man']
+
+        visualizer = DispersionPlot(target_words, ignore_case=True)
+        visualizer.fit(text)
+        visualizer.ax.grid(False)
+
+        self.assert_images_similar(visualizer, tol=25)
+