Repository: statsmodels/statsmodels

Issue:
Logic swapped for cooks distance/dffits in influence_plot?
I was looking at the [code for influence_plot](https://github.com/statsmodels/statsmodels/blob/6903819080ea2ddddcf2cb4aca20ecb1cfbfe35e/statsmodels/graphics/regressionplots.py#L765-768)

and I happened to notice the following block:

``` python
    if criterion.lower().startswith('dff'):
        psize = infl.cooks_distance[0]
    elif criterion.lower().startswith('coo'):
        psize = np.abs(infl.dffits[0])
```

but should that be the other way around? i.e.:

``` python
    if criterion.lower().startswith('dff'):
        psize = np.abs(infl.dffits[0])
    elif criterion.lower().startswith('coo'):
        psize = infl.cooks_distance[0]
```



Discussion:
Thanks for finding and reporting.  (I don't know why I didn't reply during my vacation.)
I'm fixing this this week for 0.8


Resolving patch:
diff --git a/statsmodels/graphics/mosaicplot.py b/statsmodels/graphics/mosaicplot.py
--- a/statsmodels/graphics/mosaicplot.py
+++ b/statsmodels/graphics/mosaicplot.py
@@ -613,7 +613,8 @@ def mosaic(data, index=None, ax=None, horizontal=True, gap=0.005,
         raise ValueError("You must pass an index if data is a DataFrame."
                          " See examples.")
 
-    from pylab import Rectangle
+    from matplotlib.patches import Rectangle
+    #from pylab import Rectangle
     fig, ax = utils.create_mpl_ax(ax)
     # normalize the data to a dict with tuple of strings as keys
     data = _normalize_data(data, index)
diff --git a/statsmodels/graphics/regressionplots.py b/statsmodels/graphics/regressionplots.py
--- a/statsmodels/graphics/regressionplots.py
+++ b/statsmodels/graphics/regressionplots.py
@@ -762,9 +762,9 @@ def influence_plot(results, external=True, alpha=.05, criterion="cooks",
 
     infl = results.get_influence()
 
-    if criterion.lower().startswith('dff'):
+    if criterion.lower().startswith('coo'):
         psize = infl.cooks_distance[0]
-    elif criterion.lower().startswith('coo'):
+    elif criterion.lower().startswith('dff'):
         psize = np.abs(infl.dffits[0])
     else:
         raise ValueError("Criterion %s not understood" % criterion)


Test patch:
diff --git a/statsmodels/graphics/tests/test_dotplot.py b/statsmodels/graphics/tests/test_dotplot.py
--- a/statsmodels/graphics/tests/test_dotplot.py
+++ b/statsmodels/graphics/tests/test_dotplot.py
@@ -418,3 +418,4 @@ def test_all():
 
     if pdf_output:
         pdf.close()
+    plt.close('all')
diff --git a/statsmodels/graphics/tests/test_factorplots.py b/statsmodels/graphics/tests/test_factorplots.py
--- a/statsmodels/graphics/tests/test_factorplots.py
+++ b/statsmodels/graphics/tests/test_factorplots.py
@@ -68,13 +68,21 @@ def test_formatting(self):
         plt.close(fig)
 
     def test_formatting_errors(self):
+        #plt.close('all')
         assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, markers=['D'])
+        plt.close('all')
         assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, colors=['b','r','g'])
+        plt.close('all')
         assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, linestyles=['--','-.',':'])
+        plt.close('all')
+
 
     def test_plottype(self):
         fig = interaction_plot(self.weight, self.duration, self.days, plottype='line')
         assert_equal(isinstance(fig, plt.Figure), True)
+        plt.close(fig)
         fig = interaction_plot(self.weight, self.duration, self.days, plottype='scatter')
         assert_equal(isinstance(fig, plt.Figure), True)
+        plt.close(fig)
         assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, plottype='unknown')
+        plt.close('all')
\ No newline at end of file
diff --git a/statsmodels/graphics/tests/test_gofplots.py b/statsmodels/graphics/tests/test_gofplots.py
--- a/statsmodels/graphics/tests/test_gofplots.py
+++ b/statsmodels/graphics/tests/test_gofplots.py
@@ -31,6 +31,7 @@ def test_qqplot(self):
 
     @dec.skipif(not have_matplotlib)
     def test_ppplot(self):
+        plt.close('all')
         self.fig = self.prbplt.ppplot(ax=self.ax, line=self.line)
 
     @dec.skipif(not have_matplotlib)
@@ -169,9 +170,12 @@ def test_qqplot_2samples_ProbPlotObjects(self):
             # test with `ProbPlot` instances
             fig = sm.qqplot_2samples(self.prbplt, self.other_prbplot,
                                      line=line)
+            plt.close('all')
+
     @dec.skipif(not have_matplotlib)
     def test_qqplot_2samples_arrays(self):
         # also tests all values for line
         for line in ['r', 'q', '45', 's']:
             # test with arrays
             fig = sm.qqplot_2samples(self.res, self.other_array, line=line)
+            plt.close('all')
diff --git a/statsmodels/graphics/tests/test_mosaicplot.py b/statsmodels/graphics/tests/test_mosaicplot.py
--- a/statsmodels/graphics/tests/test_mosaicplot.py
+++ b/statsmodels/graphics/tests/test_mosaicplot.py
@@ -207,7 +207,6 @@ def test_axes_labeling():
 def test_mosaic_empty_cells():
     # SMOKE test  see #2286
     import pandas as pd
-
     mydata = pd.DataFrame({'id2': {64: 'Angelica',
                                    65: 'DXW_UID', 66: 'casuid01',
                                    67: 'casuid01', 68: 'EC93_uid',
@@ -223,6 +222,7 @@ def test_mosaic_empty_cells():
 
     ct = pd.crosstab(mydata.id1, mydata.id2)
     fig, vals = mosaic(ct.T.unstack())
+    pylab.close('all')
     fig, vals = mosaic(mydata, ['id1','id2'])
     pylab.close('all')
 
@@ -430,6 +430,7 @@ def test_gap_split():
     eq(_split_rect(*pure_square, **conf_h), h_2split)
 
 
+@dec.skipif(not have_matplotlib or pandas_old)
 def test_default_arg_index():
     # 2116
     import pandas as pd
@@ -438,6 +439,7 @@ def test_default_arg_index():
                        'length' : ['long', 'short', 'short', 'long', 'long',
                                    'short']})
     assert_raises(ValueError, mosaic, data=df, title='foobar')
+    pylab.close('all')
 
 
 if __name__ == '__main__':
diff --git a/statsmodels/graphics/tests/test_regressionplots.py b/statsmodels/graphics/tests/test_regressionplots.py
--- a/statsmodels/graphics/tests/test_regressionplots.py
+++ b/statsmodels/graphics/tests/test_regressionplots.py
@@ -8,6 +8,7 @@
                   plot_added_variable, plot_partial_residuals,
                   plot_ceres_residuals, influence_plot, plot_leverage_resid2)
 from pandas import Series, DataFrame
+from numpy.testing.utils import assert_array_less
 
 try:
     import matplotlib.pyplot as plt  #makes plt available for test functions
@@ -77,26 +78,49 @@ def test_plot_fit(self):
     def test_plot_oth(self):
         #just test that they run
         res = self.res
-
+        plt.close('all')
         plot_fit(res, 0, y_true=None)
+        plt.close('all')
         plot_partregress_grid(res, exog_idx=[0,1])
+        plt.close('all')
         plot_regress_exog(res, exog_idx=0)
+        plt.close('all')
         plot_ccpr(res, exog_idx=0)
+        plt.close('all')
         plot_ccpr_grid(res, exog_idx=[0])
+        plt.close('all')
         fig = plot_ccpr_grid(res, exog_idx=[0,1])
         for ax in fig.axes:
             add_lowess(ax)
-
+   
         close_or_save(pdf, fig)
+        plt.close('all')
 
     @dec.skipif(not have_matplotlib)
     def test_plot_influence(self):
+        infl = self.res.get_influence()
         fig = influence_plot(self.res)
         assert_equal(isinstance(fig, plt.Figure), True)
+        # test that we have the correct criterion for sizes #3103
+        try:
+            sizes = fig.axes[0].get_children()[0]._sizes
+            ex = sm.add_constant(infl.cooks_distance[0])
+            ssr = sm.OLS(sizes, ex).fit().ssr
+            assert_array_less(ssr, 1e-12)
+        except AttributeError:
+            import warnings
+            warnings.warn('test not compatible with matplotlib version')
         plt.close(fig)
 
         fig = influence_plot(self.res, criterion='DFFITS')
         assert_equal(isinstance(fig, plt.Figure), True)
+        try:
+            sizes = fig.axes[0].get_children()[0]._sizes
+            ex = sm.add_constant(np.abs(infl.dffits[0]))
+            ssr = sm.OLS(sizes, ex).fit().ssr
+            assert_array_less(ssr, 1e-12)
+        except AttributeError:
+            pass
         plt.close(fig)
 
         assert_raises(ValueError, influence_plot, self.res, criterion='unknown')
@@ -133,8 +157,10 @@ def test_one_column_exog(self):
         from statsmodels.formula.api import ols
         res = ols("y~var1-1", data=self.data).fit()
         plot_regress_exog(res, "var1")
+        plt.close('all')
         res = ols("y~var1", data=self.data).fit()
         plot_regress_exog(res, "var1")
+        plt.close('all')
 
 
 class TestABLine(object):
diff --git a/statsmodels/graphics/tests/test_tsaplots.py b/statsmodels/graphics/tests/test_tsaplots.py
--- a/statsmodels/graphics/tests/test_tsaplots.py
+++ b/statsmodels/graphics/tests/test_tsaplots.py
@@ -120,23 +120,27 @@ def test_plot_quarter():
                               dta.quarter.astype(int).apply(str)))
     # test dates argument
     quarter_plot(dta.unemp.values, dates)
+    plt.close('all')
 
     # test with a DatetimeIndex with no freq
     parser = pd.datetools.parse_time_string
     dta.set_index(pd.DatetimeIndex((x[0] for x in map(parser, dates))),
                   inplace=True)
     quarter_plot(dta.unemp)
+    plt.close('all')
 
     # w freq
     # see pandas #6631
     dta.index = pd.DatetimeIndex((x[0] for x in map(parser, dates)),
                                    freq='QS-Oct')
     quarter_plot(dta.unemp)
+    plt.close('all')
 
     # w PeriodIndex
     dta.index = pd.PeriodIndex((x[0] for x in map(parser, dates)),
                                    freq='Q')
     quarter_plot(dta.unemp)
+    plt.close('all')
 
 @dec.skipif(not have_matplotlib)
 def test_seasonal_plot():
@@ -153,3 +157,4 @@ def test_seasonal_plot():
     ax = fig.get_axes()[0]
     output = [tl.get_text() for tl in ax.get_xticklabels()]
     assert_equal(labels, output)
+    plt.close('all')
diff --git a/statsmodels/stats/tests/test_power.py b/statsmodels/stats/tests/test_power.py
--- a/statsmodels/stats/tests/test_power.py
+++ b/statsmodels/stats/tests/test_power.py
@@ -94,6 +94,7 @@ def test_roots(self):
     def test_power_plot(self):
         if self.cls == smp.FTestPower:
             raise nose.SkipTest('skip FTestPower plot_power')
+        plt.close()
         fig = plt.figure()
         ax = fig.add_subplot(2,1,1)
         fig = self.cls().plot_power(dep_var='nobs',
@@ -109,7 +110,7 @@ def test_power_plot(self):
                                   #alternative='larger',
                                   ax=ax, title='',
                                   **self.kwds_extra)
-        plt.close('all')
+        plt.close(fig)
 
 #''' test cases
 #one sample
diff --git a/statsmodels/tsa/vector_ar/tests/test_var.py b/statsmodels/tsa/vector_ar/tests/test_var.py
--- a/statsmodels/tsa/vector_ar/tests/test_var.py
+++ b/statsmodels/tsa/vector_ar/tests/test_var.py
@@ -171,39 +171,56 @@ def test_irf_coefs(self):
         self._check_irfs(self.irf.irfs, self.ref.irf)
         self._check_irfs(self.irf.orth_irfs, self.ref.orth_irf)
 
+
     def _check_irfs(self, py_irfs, r_irfs):
         for i, name in enumerate(self.res.names):
             ref_irfs = r_irfs[name].view((float, self.k), type=np.ndarray)
             res_irfs = py_irfs[:, :, i]
             assert_almost_equal(ref_irfs, res_irfs)
 
+
     def test_plot_irf(self):
         if not have_matplotlib():
             raise nose.SkipTest
 
+        import matplotlib.pyplot as plt
         self.irf.plot()
+        plt.close('all')
         self.irf.plot(plot_stderr=False)
+        plt.close('all')
 
         self.irf.plot(impulse=0, response=1)
+        plt.close('all')
         self.irf.plot(impulse=0)
+        plt.close('all')
         self.irf.plot(response=0)
+        plt.close('all')
 
         self.irf.plot(orth=True)
+        plt.close('all')
         self.irf.plot(impulse=0, response=1, orth=True)
         close_plots()
 
+
     def test_plot_cum_effects(self):
         if not have_matplotlib():
             raise nose.SkipTest
-
+        # I need close after every plot to avoid segfault, see #3158
+        import matplotlib.pyplot as plt
+        plt.close('all')
         self.irf.plot_cum_effects()
+        plt.close('all')
         self.irf.plot_cum_effects(plot_stderr=False)
+        plt.close('all')
         self.irf.plot_cum_effects(impulse=0, response=1)
+        plt.close('all')
 
         self.irf.plot_cum_effects(orth=True)
+        plt.close('all')
         self.irf.plot_cum_effects(impulse=0, response=1, orth=True)
         close_plots()
 
+
 class CheckFEVD(object):
 
     fevd = None