We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
JointPlotVisualizer insists on Matplotlib "2.0.0" exactly.
Warns if on mpl.__version__ == "2.0.2". That's overly picky, yes?

Line 133 in features/jointplot.py.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `yellowbrick/features/jointplot.py`
Content:
```
1 
2 # yellowbrick.features.jointplot
3 # Implementations of joint plots for univariate and bivariate analysis.
4 #
5 # Author:   Prema Damodaran Roman
6 # Created:  Mon Apr 10 21:00:54 2017 -0400
7 #
8 # Copyright (C) 2017 District Data Labs
9 # For license information, see LICENSE.txt
10 #
11 # ID: jointplot.py [7f47800] pdamodaran@users.noreply.github.com $
12 
13 ##########################################################################
14 ## Imports
15 ##########################################################################
16 
17 import warnings
18 import numpy as np
19 import matplotlib as mpl
20 import matplotlib.pyplot as plt
21 
22 from yellowbrick.features.base import FeatureVisualizer
23 from yellowbrick.exceptions import YellowbrickValueError
24 from yellowbrick.bestfit import draw_best_fit
25 from yellowbrick.utils import is_dataframe
26 
27 ##########################################################################
28 ## Joint Plot Visualizer
29 ##########################################################################
30 
31 
32 class JointPlotVisualizer(FeatureVisualizer):
33     """
34     JointPlotVisualizer allows for a simultaneous visualization of the relationship
35     between two variables and the distrbution of each individual variable.  The
36     relationship is plotted along the joint axis and univariate distributions
37     are plotted on top of the x axis and to the right of the y axis.
38 
39     Parameters
40     ----------
41     ax: matplotlib Axes, default: None
42         This is inherited from FeatureVisualizer but is defined within
43         JointPlotVisualizer since there are three axes objects.
44 
45     feature: string, default: None
46         The name of the X variable
47         If a DataFrame is passed to fit and feature is None, feature
48         is selected as the column of the DataFrame.  There must be only
49         one column in the DataFrame.
50 
51     target: string, default: None
52         The name of the Y variable
53         If target is None and a y value is passed to fit then the target
54         is selected from the target vector.
55 
56     joint_plot: one of {'scatter', 'hex'}, default: 'scatter'
57         The type of plot to render in the joint axis
58         Currently, the choices are scatter and hex.
59         Use scatter for small datasets and hex for large datasets
60 
61     joint_args: dict, default: None
62         Keyword arguments used for customizing the joint plot:
63 
64         =============   ==================================================================
65         Property        Description
66         -------------   ------------------------------------------------------------------
67         alpha           transparency
68         facecolor       background color of the joint axis
69         aspect          aspect ratio
70         fit             used if scatter is selected for joint_plot to draw a
71                         best fit line - values can be True or False.
72                         Uses ``Yellowbrick.bestfit``
73         estimator       used if scatter is selected for joint_plot to determine
74                         the type of best fit line to use.  Refer to
75                         Yellowbrick.bestfit for types of estimators that can be used.
76         x_bins          used if hex is selected to set the number of bins for the x value
77         y_bins          used if hex is selected to set the number of bins for the y value
78         cmap            string or matplotlib cmap to colorize lines
79                         Use either color to colorize the lines on a per class basis or
80                         colormap to color them on a continuous scale.
81         =============   ==================================================================
82 
83     xy_plot: one of {'hist'}, default: 'hist'
84         The type of plot to render along the x and y axes
85         Currently, the choice is hist
86 
87     xy_args: dict, default: None
88         Keyword arguments used for customizing the x and y plots:
89 
90         ==============  =====================================================
91         Property        Description
92         --------------  -----------------------------------------------------
93         alpha           transparency
94         facecolor_x     background color of the x axis
95         facecolor_y     background color of the y axis
96         bins            used to set up the number of bins for the hist plot
97         histcolor_x     used to set the color for the histogram on the x axis
98         histcolor_y     used to set the color for the histogram on the y axis
99         ==============  =====================================================
100 
101     size: float, default: 6
102         Size of each side of the figure in inches
103 
104     ratio: float, default: 5
105         Ratio of joint axis size to the x and y axes height
106 
107     space: float, default: 0.2
108         Space between the joint axis and the x and y axes
109 
110     kwargs : dict
111         Keyword arguments that are passed to the base class and may influence
112         the visualization as defined in other Visualizers.
113 
114     Examples
115     --------
116 
117     >>> visualizer = JointPlotVisualizer()
118     >>> visualizer.fit(X,y)
119     >>> visualizer.poof()
120 
121     Notes
122     -----
123     These parameters can be influenced later on in the visualization
124     process, but can and should be set as early as possible.
125     """
126 
127     def __init__(self, ax=None, feature=None, target=None,
128                  joint_plot='scatter', joint_args=None,
129                  xy_plot='hist', xy_args=None,
130                  size=6, ratio=5, space=.2, **kwargs):
131 
132         #check matplotlib version - needs to be version 2.0.0
133         if mpl.__version__ == "2.0.0":
134             pass
135         else:
136             warnings.warn((
137                 "{} requires Matplotlib version 2.0.0."
138                 "Please upgrade to continue."
139             ).format(self.__class__.__name__))
140 
141         super(JointPlotVisualizer, self).__init__(ax, **kwargs)
142 
143         self.feature = feature
144         self.target = target
145         self.joint_plot = joint_plot
146         self.joint_args = joint_args
147         self.xy_plot = xy_plot
148         self.xy_args = xy_args
149         self.size = size
150         self.ratio = ratio
151         self.space = space
152 
153     def fit(self, X, y, **kwargs):
154         """
155         Sets up the X and y variables for the jointplot
156         and checks to ensure that X and y are of the
157         correct data type
158 
159         Fit calls draw
160 
161         Parameters
162         ----------
163 
164         X : ndarray or DataFrame of shape n x 1
165             A matrix of n instances with 1 feature
166 
167         y : ndarray or Series of length n
168             An array or series of the target value
169 
170         kwargs: dict
171             keyword arguments passed to Scikit-Learn API.
172         """
173 
174         #throw an error if X has more than 1 column
175         if is_dataframe(X):
176             nrows, ncols = X.shape
177 
178             if ncols > 1:
179                 raise YellowbrickValueError((
180                     "X needs to be an ndarray or DataFrame with one feature, "
181                     "please select one feature from the DataFrame"
182                 ))
183 
184         #throw an error is y is None
185         if y is None:
186             raise YellowbrickValueError((
187                 "Joint plots are useful for classification and regression "
188                 "problems, which require a target variable"
189             ))
190 
191 
192         # Handle the feature name if it is None.
193         if self.feature is None:
194 
195             # If X is a data frame, get the columns off it.
196             if is_dataframe(X):
197                 self.feature = X.columns
198 
199             else:
200                 self.feature = ['x']
201 
202         # Handle the target name if it is None.
203         if self.target is None:
204             self.target = ['y']
205 
206         self.draw(X, y, **kwargs)
207         return self
208 
209     def draw(self, X, y, **kwargs):
210         """
211         Sets up the layout for the joint plot draw calls ``draw_joint`` and
212         ``draw_xy`` to render the visualizations.
213         """
214 
215         fig = plt.figure(figsize=(self.size, self.size))
216         gs = plt.GridSpec(self.ratio + 1, self.ratio + 1)
217 
218         #Set up the 3 axes objects
219         joint_ax = fig.add_subplot(gs[1:, :-1])
220         x_ax = fig.add_subplot(gs[0, :-1], sharex=joint_ax)
221         y_ax = fig.add_subplot(gs[1:, -1], sharey=joint_ax)
222 
223         fig.tight_layout()
224         fig.subplots_adjust(hspace=self.space, wspace=self.space)
225 
226         self.fig = fig
227         self.joint_ax = joint_ax
228         self.x_ax = x_ax
229         self.y_ax = y_ax
230 
231         self.draw_joint(X, y, **kwargs)
232         self.draw_xy(X, y, **kwargs)
233 
234     def draw_joint(self, X, y, **kwargs):
235         """
236         Draws the visualization for the joint axis.
237         """
238 
239         if self.joint_args is None:
240             self.joint_args = {}
241 
242         self.joint_args.setdefault("alpha", 0.4)
243         facecolor = self.joint_args.pop("facecolor", "#dddddd")
244         self.joint_ax.set_facecolor(facecolor)
245 
246         if self.joint_plot == "scatter":
247             aspect = self.joint_args.pop("aspect", "auto")
248             self.joint_ax.set_aspect(aspect)
249             self.joint_ax.scatter(X, y, **self.joint_args)
250 
251             fit = self.joint_args.pop("fit", True)
252             if fit:
253                 estimator = self.joint_args.pop("estimator", "linear")
254                 draw_best_fit(X, y, self.joint_ax, estimator)
255 
256         elif self.joint_plot == "hex":
257             x_bins = self.joint_args.pop("x_bins", 50)
258             y_bins = self.joint_args.pop("y_bins", 50)
259             colormap = self.joint_args.pop("cmap", 'Blues')
260             gridsize = int(np.mean([x_bins, y_bins]))
261 
262             xmin = X.min()
263             xmax = X.max()
264             ymin = y.min()
265             ymax = y.max()
266 
267             self.joint_ax.hexbin(X, y,
268                 gridsize=gridsize, cmap=colormap, mincnt=1, **self.joint_args
269             )
270             self.joint_ax.axis([xmin, xmax, ymin, ymax])
271 
272     def draw_xy(self, X, y, **kwargs):
273         """
274         Draws the visualization for the x and y axes
275         """
276 
277         if self.xy_args is None:
278             self.xy_args = {}
279 
280         facecolor_x = self.xy_args.pop("facecolor_x", "#dddddd")
281         self.x_ax.set_facecolor(facecolor_x)
282         facecolor_y = self.xy_args.pop("facecolor_y", "#dddddd")
283         self.y_ax.set_facecolor(facecolor_y)
284 
285 
286         if self.xy_plot == "hist":
287             hist_bins = self.xy_args.pop("bins", 50)
288             self.xy_args.setdefault("alpha", 0.4)
289             histcolor_x = self.xy_args.pop("histcolor_x", "#6897bb")
290             self.x_ax.set_facecolor(facecolor_x)
291             histcolor_y = self.xy_args.pop("histcolor_y", "#6897bb")
292             self.y_ax.set_facecolor(facecolor_y)
293             self.x_ax.hist(X, bins=hist_bins, color=histcolor_x, **self.xy_args)
294             self.y_ax.hist(y, bins=hist_bins, color=histcolor_y,
295                               orientation='horizontal', **self.xy_args)
296 
297     def poof(self, **kwargs):
298         """
299         Creates the labels for the feature and target variables
300         """
301 
302         self.joint_ax.set_xlabel(self.feature)
303         self.joint_ax.set_ylabel(self.target)
304         self.finalize(**kwargs)
305 
306     def finalize(self, **kwargs):
307         """
308         Finalize executes any subclass-specific axes finalization steps.
309         The user calls poof and poof calls finalize.
310 
311         Parameters
312         ----------
313         kwargs: generic keyword arguments.
314         """
315 
316         plt.setp(self.x_ax.get_xticklabels(), visible=False)
317         plt.setp(self.y_ax.get_yticklabels(), visible=False)
318 
319         plt.setp(self.x_ax.yaxis.get_majorticklines(), visible=False)
320         plt.setp(self.x_ax.yaxis.get_minorticklines(), visible=False)
321         plt.setp(self.y_ax.xaxis.get_majorticklines(), visible=False)
322         plt.setp(self.y_ax.xaxis.get_minorticklines(), visible=False)
323         plt.setp(self.x_ax.get_yticklabels(), visible=False)
324         plt.setp(self.y_ax.get_xticklabels(), visible=False)
325         self.x_ax.yaxis.grid(False)
326         self.y_ax.xaxis.grid(False)
327         self.fig.suptitle("Joint Plot of {} vs {}"
328                         .format(self.feature, self.target), y=1.05)
329
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/yellowbrick/features/jointplot.py b/yellowbrick/features/jointplot.py
--- a/yellowbrick/features/jointplot.py
+++ b/yellowbrick/features/jointplot.py
@@ -129,13 +129,14 @@
                  xy_plot='hist', xy_args=None,
                  size=6, ratio=5, space=.2, **kwargs):
 
-        #check matplotlib version - needs to be version 2.0.0
-        if mpl.__version__ == "2.0.0":
+        # Check matplotlib version - needs to be version 2.0.0 or greater.
+        mpl_vers_maj = int(mpl.__version__.split(".")[0])
+        if mpl_vers_maj >= 2:
             pass
         else:
             warnings.warn((
-                "{} requires Matplotlib version 2.0.0."
-                "Please upgrade to continue."
+                "{} requires matplotlib major version 2 or greater. "
+                "Please upgrade."
             ).format(self.__class__.__name__))
 
         super(JointPlotVisualizer, self).__init__(ax, **kwargs)

{"golden_diff": "diff --git a/yellowbrick/features/jointplot.py b/yellowbrick/features/jointplot.py\n--- a/yellowbrick/features/jointplot.py\n+++ b/yellowbrick/features/jointplot.py\n@@ -129,13 +129,14 @@\n                  xy_plot='hist', xy_args=None,\n                  size=6, ratio=5, space=.2, **kwargs):\n \n-        #check matplotlib version - needs to be version 2.0.0\n-        if mpl.__version__ == \"2.0.0\":\n+        # Check matplotlib version - needs to be version 2.0.0 or greater.\n+        mpl_vers_maj = int(mpl.__version__.split(\".\")[0])\n+        if mpl_vers_maj >= 2:\n             pass\n         else:\n             warnings.warn((\n-                \"{} requires Matplotlib version 2.0.0.\"\n-                \"Please upgrade to continue.\"\n+                \"{} requires matplotlib major version 2 or greater. \"\n+                \"Please upgrade.\"\n             ).format(self.__class__.__name__))\n \n         super(JointPlotVisualizer, self).__init__(ax, **kwargs)\n", "issue": "JointPlotVisualizer insists on Matplotlib \"2.0.0\" exactly.\nWarns if on mpl.__version__ == \"2.0.2\". That's overly picky, yes?\r\n\r\nLine 133 in features/jointplot.py.\n", "before_files": [{"content": "\n# yellowbrick.features.jointplot\n# Implementations of joint plots for univariate and bivariate analysis.\n#\n# Author:   Prema Damodaran Roman\n# Created:  Mon Apr 10 21:00:54 2017 -0400\n#\n# Copyright (C) 2017 District Data Labs\n# For license information, see LICENSE.txt\n#\n# ID: jointplot.py [7f47800] pdamodaran@users.noreply.github.com $\n\n##########################################################################\n## Imports\n##########################################################################\n\nimport warnings\nimport numpy as np\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\n\nfrom yellowbrick.features.base import FeatureVisualizer\nfrom yellowbrick.exceptions import YellowbrickValueError\nfrom yellowbrick.bestfit import draw_best_fit\nfrom yellowbrick.utils import is_dataframe\n\n##########################################################################\n## Joint Plot Visualizer\n##########################################################################\n\n\nclass JointPlotVisualizer(FeatureVisualizer):\n    \"\"\"\n    JointPlotVisualizer allows for a simultaneous visualization of the relationship\n    between two variables and the distrbution of each individual variable.  The\n    relationship is plotted along the joint axis and univariate distributions\n    are plotted on top of the x axis and to the right of the y axis.\n\n    Parameters\n    ----------\n    ax: matplotlib Axes, default: None\n        This is inherited from FeatureVisualizer but is defined within\n        JointPlotVisualizer since there are three axes objects.\n\n    feature: string, default: None\n        The name of the X variable\n        If a DataFrame is passed to fit and feature is None, feature\n        is selected as the column of the DataFrame.  There must be only\n        one column in the DataFrame.\n\n    target: string, default: None\n        The name of the Y variable\n        If target is None and a y value is passed to fit then the target\n        is selected from the target vector.\n\n    joint_plot: one of {'scatter', 'hex'}, default: 'scatter'\n        The type of plot to render in the joint axis\n        Currently, the choices are scatter and hex.\n        Use scatter for small datasets and hex for large datasets\n\n    joint_args: dict, default: None\n        Keyword arguments used for customizing the joint plot:\n\n        =============   ==================================================================\n        Property        Description\n        -------------   ------------------------------------------------------------------\n        alpha           transparency\n        facecolor       background color of the joint axis\n        aspect          aspect ratio\n        fit             used if scatter is selected for joint_plot to draw a\n                        best fit line - values can be True or False.\n                        Uses ``Yellowbrick.bestfit``\n        estimator       used if scatter is selected for joint_plot to determine\n                        the type of best fit line to use.  Refer to\n                        Yellowbrick.bestfit for types of estimators that can be used.\n        x_bins          used if hex is selected to set the number of bins for the x value\n        y_bins          used if hex is selected to set the number of bins for the y value\n        cmap            string or matplotlib cmap to colorize lines\n                        Use either color to colorize the lines on a per class basis or\n                        colormap to color them on a continuous scale.\n        =============   ==================================================================\n\n    xy_plot: one of {'hist'}, default: 'hist'\n        The type of plot to render along the x and y axes\n        Currently, the choice is hist\n\n    xy_args: dict, default: None\n        Keyword arguments used for customizing the x and y plots:\n\n        ==============  =====================================================\n        Property        Description\n        --------------  -----------------------------------------------------\n        alpha           transparency\n        facecolor_x     background color of the x axis\n        facecolor_y     background color of the y axis\n        bins            used to set up the number of bins for the hist plot\n        histcolor_x     used to set the color for the histogram on the x axis\n        histcolor_y     used to set the color for the histogram on the y axis\n        ==============  =====================================================\n\n    size: float, default: 6\n        Size of each side of the figure in inches\n\n    ratio: float, default: 5\n        Ratio of joint axis size to the x and y axes height\n\n    space: float, default: 0.2\n        Space between the joint axis and the x and y axes\n\n    kwargs : dict\n        Keyword arguments that are passed to the base class and may influence\n        the visualization as defined in other Visualizers.\n\n    Examples\n    --------\n\n    >>> visualizer = JointPlotVisualizer()\n    >>> visualizer.fit(X,y)\n    >>> visualizer.poof()\n\n    Notes\n    -----\n    These parameters can be influenced later on in the visualization\n    process, but can and should be set as early as possible.\n    \"\"\"\n\n    def __init__(self, ax=None, feature=None, target=None,\n                 joint_plot='scatter', joint_args=None,\n                 xy_plot='hist', xy_args=None,\n                 size=6, ratio=5, space=.2, **kwargs):\n\n        #check matplotlib version - needs to be version 2.0.0\n        if mpl.__version__ == \"2.0.0\":\n            pass\n        else:\n            warnings.warn((\n                \"{} requires Matplotlib version 2.0.0.\"\n                \"Please upgrade to continue.\"\n            ).format(self.__class__.__name__))\n\n        super(JointPlotVisualizer, self).__init__(ax, **kwargs)\n\n        self.feature = feature\n        self.target = target\n        self.joint_plot = joint_plot\n        self.joint_args = joint_args\n        self.xy_plot = xy_plot\n        self.xy_args = xy_args\n        self.size = size\n        self.ratio = ratio\n        self.space = space\n\n    def fit(self, X, y, **kwargs):\n        \"\"\"\n        Sets up the X and y variables for the jointplot\n        and checks to ensure that X and y are of the\n        correct data type\n\n        Fit calls draw\n\n        Parameters\n        ----------\n\n        X : ndarray or DataFrame of shape n x 1\n            A matrix of n instances with 1 feature\n\n        y : ndarray or Series of length n\n            An array or series of the target value\n\n        kwargs: dict\n            keyword arguments passed to Scikit-Learn API.\n        \"\"\"\n\n        #throw an error if X has more than 1 column\n        if is_dataframe(X):\n            nrows, ncols = X.shape\n\n            if ncols > 1:\n                raise YellowbrickValueError((\n                    \"X needs to be an ndarray or DataFrame with one feature, \"\n                    \"please select one feature from the DataFrame\"\n                ))\n\n        #throw an error is y is None\n        if y is None:\n            raise YellowbrickValueError((\n                \"Joint plots are useful for classification and regression \"\n                \"problems, which require a target variable\"\n            ))\n\n\n        # Handle the feature name if it is None.\n        if self.feature is None:\n\n            # If X is a data frame, get the columns off it.\n            if is_dataframe(X):\n                self.feature = X.columns\n\n            else:\n                self.feature = ['x']\n\n        # Handle the target name if it is None.\n        if self.target is None:\n            self.target = ['y']\n\n        self.draw(X, y, **kwargs)\n        return self\n\n    def draw(self, X, y, **kwargs):\n        \"\"\"\n        Sets up the layout for the joint plot draw calls ``draw_joint`` and\n        ``draw_xy`` to render the visualizations.\n        \"\"\"\n\n        fig = plt.figure(figsize=(self.size, self.size))\n        gs = plt.GridSpec(self.ratio + 1, self.ratio + 1)\n\n        #Set up the 3 axes objects\n        joint_ax = fig.add_subplot(gs[1:, :-1])\n        x_ax = fig.add_subplot(gs[0, :-1], sharex=joint_ax)\n        y_ax = fig.add_subplot(gs[1:, -1], sharey=joint_ax)\n\n        fig.tight_layout()\n        fig.subplots_adjust(hspace=self.space, wspace=self.space)\n\n        self.fig = fig\n        self.joint_ax = joint_ax\n        self.x_ax = x_ax\n        self.y_ax = y_ax\n\n        self.draw_joint(X, y, **kwargs)\n        self.draw_xy(X, y, **kwargs)\n\n    def draw_joint(self, X, y, **kwargs):\n        \"\"\"\n        Draws the visualization for the joint axis.\n        \"\"\"\n\n        if self.joint_args is None:\n            self.joint_args = {}\n\n        self.joint_args.setdefault(\"alpha\", 0.4)\n        facecolor = self.joint_args.pop(\"facecolor\", \"#dddddd\")\n        self.joint_ax.set_facecolor(facecolor)\n\n        if self.joint_plot == \"scatter\":\n            aspect = self.joint_args.pop(\"aspect\", \"auto\")\n            self.joint_ax.set_aspect(aspect)\n            self.joint_ax.scatter(X, y, **self.joint_args)\n\n            fit = self.joint_args.pop(\"fit\", True)\n            if fit:\n                estimator = self.joint_args.pop(\"estimator\", \"linear\")\n                draw_best_fit(X, y, self.joint_ax, estimator)\n\n        elif self.joint_plot == \"hex\":\n            x_bins = self.joint_args.pop(\"x_bins\", 50)\n            y_bins = self.joint_args.pop(\"y_bins\", 50)\n            colormap = self.joint_args.pop(\"cmap\", 'Blues')\n            gridsize = int(np.mean([x_bins, y_bins]))\n\n            xmin = X.min()\n            xmax = X.max()\n            ymin = y.min()\n            ymax = y.max()\n\n            self.joint_ax.hexbin(X, y,\n                gridsize=gridsize, cmap=colormap, mincnt=1, **self.joint_args\n            )\n            self.joint_ax.axis([xmin, xmax, ymin, ymax])\n\n    def draw_xy(self, X, y, **kwargs):\n        \"\"\"\n        Draws the visualization for the x and y axes\n        \"\"\"\n\n        if self.xy_args is None:\n            self.xy_args = {}\n\n        facecolor_x = self.xy_args.pop(\"facecolor_x\", \"#dddddd\")\n        self.x_ax.set_facecolor(facecolor_x)\n        facecolor_y = self.xy_args.pop(\"facecolor_y\", \"#dddddd\")\n        self.y_ax.set_facecolor(facecolor_y)\n\n\n        if self.xy_plot == \"hist\":\n            hist_bins = self.xy_args.pop(\"bins\", 50)\n            self.xy_args.setdefault(\"alpha\", 0.4)\n            histcolor_x = self.xy_args.pop(\"histcolor_x\", \"#6897bb\")\n            self.x_ax.set_facecolor(facecolor_x)\n            histcolor_y = self.xy_args.pop(\"histcolor_y\", \"#6897bb\")\n            self.y_ax.set_facecolor(facecolor_y)\n            self.x_ax.hist(X, bins=hist_bins, color=histcolor_x, **self.xy_args)\n            self.y_ax.hist(y, bins=hist_bins, color=histcolor_y,\n                              orientation='horizontal', **self.xy_args)\n\n    def poof(self, **kwargs):\n        \"\"\"\n        Creates the labels for the feature and target variables\n        \"\"\"\n\n        self.joint_ax.set_xlabel(self.feature)\n        self.joint_ax.set_ylabel(self.target)\n        self.finalize(**kwargs)\n\n    def finalize(self, **kwargs):\n        \"\"\"\n        Finalize executes any subclass-specific axes finalization steps.\n        The user calls poof and poof calls finalize.\n\n        Parameters\n        ----------\n        kwargs: generic keyword arguments.\n        \"\"\"\n\n        plt.setp(self.x_ax.get_xticklabels(), visible=False)\n        plt.setp(self.y_ax.get_yticklabels(), visible=False)\n\n        plt.setp(self.x_ax.yaxis.get_majorticklines(), visible=False)\n        plt.setp(self.x_ax.yaxis.get_minorticklines(), visible=False)\n        plt.setp(self.y_ax.xaxis.get_majorticklines(), visible=False)\n        plt.setp(self.y_ax.xaxis.get_minorticklines(), visible=False)\n        plt.setp(self.x_ax.get_yticklabels(), visible=False)\n        plt.setp(self.y_ax.get_xticklabels(), visible=False)\n        self.x_ax.yaxis.grid(False)\n        self.y_ax.xaxis.grid(False)\n        self.fig.suptitle(\"Joint Plot of {} vs {}\"\n                        .format(self.feature, self.target), y=1.05)\n", "path": "yellowbrick/features/jointplot.py"}], "after_files": [{"content": "\n# yellowbrick.features.jointplot\n# Implementations of joint plots for univariate and bivariate analysis.\n#\n# Author:   Prema Damodaran Roman\n# Created:  Mon Apr 10 21:00:54 2017 -0400\n#\n# Copyright (C) 2017 District Data Labs\n# For license information, see LICENSE.txt\n#\n# ID: jointplot.py [7f47800] pdamodaran@users.noreply.github.com $\n\n##########################################################################\n## Imports\n##########################################################################\n\nimport warnings\nimport numpy as np\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\n\nfrom yellowbrick.features.base import FeatureVisualizer\nfrom yellowbrick.exceptions import YellowbrickValueError\nfrom yellowbrick.bestfit import draw_best_fit\nfrom yellowbrick.utils import is_dataframe\n\n##########################################################################\n## Joint Plot Visualizer\n##########################################################################\n\n\nclass JointPlotVisualizer(FeatureVisualizer):\n    \"\"\"\n    JointPlotVisualizer allows for a simultaneous visualization of the relationship\n    between two variables and the distrbution of each individual variable.  The\n    relationship is plotted along the joint axis and univariate distributions\n    are plotted on top of the x axis and to the right of the y axis.\n\n    Parameters\n    ----------\n    ax: matplotlib Axes, default: None\n        This is inherited from FeatureVisualizer but is defined within\n        JointPlotVisualizer since there are three axes objects.\n\n    feature: string, default: None\n        The name of the X variable\n        If a DataFrame is passed to fit and feature is None, feature\n        is selected as the column of the DataFrame.  There must be only\n        one column in the DataFrame.\n\n    target: string, default: None\n        The name of the Y variable\n        If target is None and a y value is passed to fit then the target\n        is selected from the target vector.\n\n    joint_plot: one of {'scatter', 'hex'}, default: 'scatter'\n        The type of plot to render in the joint axis\n        Currently, the choices are scatter and hex.\n        Use scatter for small datasets and hex for large datasets\n\n    joint_args: dict, default: None\n        Keyword arguments used for customizing the joint plot:\n\n        =============   ==================================================================\n        Property        Description\n        -------------   ------------------------------------------------------------------\n        alpha           transparency\n        facecolor       background color of the joint axis\n        aspect          aspect ratio\n        fit             used if scatter is selected for joint_plot to draw a\n                        best fit line - values can be True or False.\n                        Uses ``Yellowbrick.bestfit``\n        estimator       used if scatter is selected for joint_plot to determine\n                        the type of best fit line to use.  Refer to\n                        Yellowbrick.bestfit for types of estimators that can be used.\n        x_bins          used if hex is selected to set the number of bins for the x value\n        y_bins          used if hex is selected to set the number of bins for the y value\n        cmap            string or matplotlib cmap to colorize lines\n                        Use either color to colorize the lines on a per class basis or\n                        colormap to color them on a continuous scale.\n        =============   ==================================================================\n\n    xy_plot: one of {'hist'}, default: 'hist'\n        The type of plot to render along the x and y axes\n        Currently, the choice is hist\n\n    xy_args: dict, default: None\n        Keyword arguments used for customizing the x and y plots:\n\n        ==============  =====================================================\n        Property        Description\n        --------------  -----------------------------------------------------\n        alpha           transparency\n        facecolor_x     background color of the x axis\n        facecolor_y     background color of the y axis\n        bins            used to set up the number of bins for the hist plot\n        histcolor_x     used to set the color for the histogram on the x axis\n        histcolor_y     used to set the color for the histogram on the y axis\n        ==============  =====================================================\n\n    size: float, default: 6\n        Size of each side of the figure in inches\n\n    ratio: float, default: 5\n        Ratio of joint axis size to the x and y axes height\n\n    space: float, default: 0.2\n        Space between the joint axis and the x and y axes\n\n    kwargs : dict\n        Keyword arguments that are passed to the base class and may influence\n        the visualization as defined in other Visualizers.\n\n    Examples\n    --------\n\n    >>> visualizer = JointPlotVisualizer()\n    >>> visualizer.fit(X,y)\n    >>> visualizer.poof()\n\n    Notes\n    -----\n    These parameters can be influenced later on in the visualization\n    process, but can and should be set as early as possible.\n    \"\"\"\n\n    def __init__(self, ax=None, feature=None, target=None,\n                 joint_plot='scatter', joint_args=None,\n                 xy_plot='hist', xy_args=None,\n                 size=6, ratio=5, space=.2, **kwargs):\n\n        # Check matplotlib version - needs to be version 2.0.0 or greater.\n        mpl_vers_maj = int(mpl.__version__.split(\".\")[0])\n        if mpl_vers_maj >= 2:\n            pass\n        else:\n            warnings.warn((\n                \"{} requires matplotlib major version 2 or greater. \"\n                \"Please upgrade.\"\n            ).format(self.__class__.__name__))\n\n        super(JointPlotVisualizer, self).__init__(ax, **kwargs)\n\n        self.feature = feature\n        self.target = target\n        self.joint_plot = joint_plot\n        self.joint_args = joint_args\n        self.xy_plot = xy_plot\n        self.xy_args = xy_args\n        self.size = size\n        self.ratio = ratio\n        self.space = space\n\n    def fit(self, X, y, **kwargs):\n        \"\"\"\n        Sets up the X and y variables for the jointplot\n        and checks to ensure that X and y are of the\n        correct data type\n\n        Fit calls draw\n\n        Parameters\n        ----------\n\n        X : ndarray or DataFrame of shape n x 1\n            A matrix of n instances with 1 feature\n\n        y : ndarray or Series of length n\n            An array or series of the target value\n\n        kwargs: dict\n            keyword arguments passed to Scikit-Learn API.\n        \"\"\"\n\n        #throw an error if X has more than 1 column\n        if is_dataframe(X):\n            nrows, ncols = X.shape\n\n            if ncols > 1:\n                raise YellowbrickValueError((\n                    \"X needs to be an ndarray or DataFrame with one feature, \"\n                    \"please select one feature from the DataFrame\"\n                ))\n\n        #throw an error is y is None\n        if y is None:\n            raise YellowbrickValueError((\n                \"Joint plots are useful for classification and regression \"\n                \"problems, which require a target variable\"\n            ))\n\n\n        # Handle the feature name if it is None.\n        if self.feature is None:\n\n            # If X is a data frame, get the columns off it.\n            if is_dataframe(X):\n                self.feature = X.columns\n\n            else:\n                self.feature = ['x']\n\n        # Handle the target name if it is None.\n        if self.target is None:\n            self.target = ['y']\n\n        self.draw(X, y, **kwargs)\n        return self\n\n    def draw(self, X, y, **kwargs):\n        \"\"\"\n        Sets up the layout for the joint plot draw calls ``draw_joint`` and\n        ``draw_xy`` to render the visualizations.\n        \"\"\"\n\n        fig = plt.figure(figsize=(self.size, self.size))\n        gs = plt.GridSpec(self.ratio + 1, self.ratio + 1)\n\n        #Set up the 3 axes objects\n        joint_ax = fig.add_subplot(gs[1:, :-1])\n        x_ax = fig.add_subplot(gs[0, :-1], sharex=joint_ax)\n        y_ax = fig.add_subplot(gs[1:, -1], sharey=joint_ax)\n\n        fig.tight_layout()\n        fig.subplots_adjust(hspace=self.space, wspace=self.space)\n\n        self.fig = fig\n        self.joint_ax = joint_ax\n        self.x_ax = x_ax\n        self.y_ax = y_ax\n\n        self.draw_joint(X, y, **kwargs)\n        self.draw_xy(X, y, **kwargs)\n\n    def draw_joint(self, X, y, **kwargs):\n        \"\"\"\n        Draws the visualization for the joint axis.\n        \"\"\"\n\n        if self.joint_args is None:\n            self.joint_args = {}\n\n        self.joint_args.setdefault(\"alpha\", 0.4)\n        facecolor = self.joint_args.pop(\"facecolor\", \"#dddddd\")\n        self.joint_ax.set_facecolor(facecolor)\n\n        if self.joint_plot == \"scatter\":\n            aspect = self.joint_args.pop(\"aspect\", \"auto\")\n            self.joint_ax.set_aspect(aspect)\n            self.joint_ax.scatter(X, y, **self.joint_args)\n\n            fit = self.joint_args.pop(\"fit\", True)\n            if fit:\n                estimator = self.joint_args.pop(\"estimator\", \"linear\")\n                draw_best_fit(X, y, self.joint_ax, estimator)\n\n        elif self.joint_plot == \"hex\":\n            x_bins = self.joint_args.pop(\"x_bins\", 50)\n            y_bins = self.joint_args.pop(\"y_bins\", 50)\n            colormap = self.joint_args.pop(\"cmap\", 'Blues')\n            gridsize = int(np.mean([x_bins, y_bins]))\n\n            xmin = X.min()\n            xmax = X.max()\n            ymin = y.min()\n            ymax = y.max()\n\n            self.joint_ax.hexbin(X, y,\n                gridsize=gridsize, cmap=colormap, mincnt=1, **self.joint_args\n            )\n            self.joint_ax.axis([xmin, xmax, ymin, ymax])\n\n    def draw_xy(self, X, y, **kwargs):\n        \"\"\"\n        Draws the visualization for the x and y axes\n        \"\"\"\n\n        if self.xy_args is None:\n            self.xy_args = {}\n\n        facecolor_x = self.xy_args.pop(\"facecolor_x\", \"#dddddd\")\n        self.x_ax.set_facecolor(facecolor_x)\n        facecolor_y = self.xy_args.pop(\"facecolor_y\", \"#dddddd\")\n        self.y_ax.set_facecolor(facecolor_y)\n\n\n        if self.xy_plot == \"hist\":\n            hist_bins = self.xy_args.pop(\"bins\", 50)\n            self.xy_args.setdefault(\"alpha\", 0.4)\n            histcolor_x = self.xy_args.pop(\"histcolor_x\", \"#6897bb\")\n            self.x_ax.set_facecolor(facecolor_x)\n            histcolor_y = self.xy_args.pop(\"histcolor_y\", \"#6897bb\")\n            self.y_ax.set_facecolor(facecolor_y)\n            self.x_ax.hist(X, bins=hist_bins, color=histcolor_x, **self.xy_args)\n            self.y_ax.hist(y, bins=hist_bins, color=histcolor_y,\n                              orientation='horizontal', **self.xy_args)\n\n    def poof(self, **kwargs):\n        \"\"\"\n        Creates the labels for the feature and target variables\n        \"\"\"\n\n        self.joint_ax.set_xlabel(self.feature)\n        self.joint_ax.set_ylabel(self.target)\n        self.finalize(**kwargs)\n\n    def finalize(self, **kwargs):\n        \"\"\"\n        Finalize executes any subclass-specific axes finalization steps.\n        The user calls poof and poof calls finalize.\n\n        Parameters\n        ----------\n        kwargs: generic keyword arguments.\n        \"\"\"\n\n        plt.setp(self.x_ax.get_xticklabels(), visible=False)\n        plt.setp(self.y_ax.get_yticklabels(), visible=False)\n\n        plt.setp(self.x_ax.yaxis.get_majorticklines(), visible=False)\n        plt.setp(self.x_ax.yaxis.get_minorticklines(), visible=False)\n        plt.setp(self.y_ax.xaxis.get_majorticklines(), visible=False)\n        plt.setp(self.y_ax.xaxis.get_minorticklines(), visible=False)\n        plt.setp(self.x_ax.get_yticklabels(), visible=False)\n        plt.setp(self.y_ax.get_xticklabels(), visible=False)\n        self.x_ax.yaxis.grid(False)\n        self.y_ax.xaxis.grid(False)\n        self.fig.suptitle(\"Joint Plot of {} vs {}\"\n                        .format(self.feature, self.target), y=1.05)\n", "path": "yellowbrick/features/jointplot.py"}]}