Repository: statsmodels/statsmodels

Issue:
TST: closing plots, pytest teardown
we have a large number of plots that are not properly closed
see https://github.com/statsmodels/statsmodels/pull/4226#issuecomment-360821013

in gofplots:

Mixin class has a `teardown` method, however that is not a recognized pytest name. pytest uses either a class method `teardown_class` or a regular method `teardown_method` which is called after every test method. test_gofplots doesn't have any `close` in the test methods directly.

The only other teardown in graphics.tests is in regression_plots which uses `teardown_module` in addition to the close in individual test methods. So that looks good.

statespace:
AFAICS from a file search, all plots have a plt.close(fig) after the call to the plot method.
 



Discussion:
I don't find a test log with the too many open plots warnings anymore.  It is possible that it is a consequence of failing/erroring unit tests in #4226

Resolving patch:
diff --git a/conftest.py b/conftest.py
deleted file mode 100644
--- a/conftest.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import pytest
-
-
-def pytest_addoption(parser):
-    parser.addoption("--skip-slow", action="store_true",
-                     help="skip slow tests")
-    parser.addoption("--only-slow", action="store_true",
-                     help="run only slow tests")
-    parser.addoption("--skip-examples", action="store_true",
-                     help="skip tests of examples")
-
-
-def pytest_runtest_setup(item):
-    if 'slow' in item.keywords and item.config.getoption("--skip-slow"):
-        pytest.skip("skipping due to --skip-slow")
-
-    if 'slow' not in item.keywords and item.config.getoption("--only-slow"):
-        pytest.skip("skipping due to --only-slow")
-
-    if 'example' in item.keywords and item.config.getoption("--skip-examples"):
-        pytest.skip("skipping due to --skip-examples")
diff --git a/statsmodels/conftest.py b/statsmodels/conftest.py
new file mode 100644
--- /dev/null
+++ b/statsmodels/conftest.py
@@ -0,0 +1,70 @@
+import pytest
+
+
+def pytest_addoption(parser):
+    parser.addoption("--skip-slow", action="store_true",
+                     help="skip slow tests")
+    parser.addoption("--only-slow", action="store_true",
+                     help="run only slow tests")
+    parser.addoption("--skip-examples", action="store_true",
+                     help="skip tests of examples")
+
+
+def pytest_runtest_setup(item):
+    if 'slow' in item.keywords and item.config.getoption("--skip-slow"):
+        pytest.skip("skipping due to --skip-slow")
+
+    if 'slow' not in item.keywords and item.config.getoption("--only-slow"):
+        pytest.skip("skipping due to --only-slow")
+
+    if 'example' in item.keywords and item.config.getoption("--skip-examples"):
+        pytest.skip("skipping due to --skip-examples")
+
+
+def pytest_configure(config):
+    try:
+        import matplotlib
+        matplotlib.use('agg')
+    except ImportError:
+        pass
+
+
+@pytest.fixture()
+def close_figures():
+    """
+    Fixture that closes all figures after a test function has completed
+
+    Returns
+    -------
+    closer : callable
+        Function that will close all figures when called.
+
+    Notes
+    -----
+    Used by passing as an argument to the function that produces a plot,
+    for example
+
+    def test_some_plot(close_figures):
+        <test code>
+
+    If a function creates many figures, then these can be destroyed within a
+    test function by calling close_figures to ensure that the number of
+    figures does not become too large.
+
+    def test_many_plots(close_figures):
+        for i in range(100000):
+            plt.plot(x,y)
+            close_figures()
+    """
+    try:
+        import matplotlib.pyplot
+
+        def close():
+            matplotlib.pyplot.close('all')
+
+    except ImportError:
+        def close():
+            pass
+
+    yield close
+    close()


Test patch:
diff --git a/statsmodels/discrete/tests/test_diagnostic.py b/statsmodels/discrete/tests/test_diagnostic.py
--- a/statsmodels/discrete/tests/test_diagnostic.py
+++ b/statsmodels/discrete/tests/test_diagnostic.py
@@ -57,7 +57,7 @@ def test_count(self):
         tzi3_1 = (0.79863597832443878, 0.67077736750318928, 2, 2)
         assert_allclose(tzi3, tzi3_1, rtol=5e-4)
 
-    def test_probs(self):
+    def test_probs(self, close_figures):
         nobs = self.nobs
         probs = self.res.predict_prob()
         freq = np.bincount(self.endog) / nobs
@@ -74,4 +74,3 @@ def test_probs(self):
         except ImportError:
             return
         fig = dia.plot_probs(freq, probs.mean(0))
-        plt.close(fig)
diff --git a/statsmodels/duration/tests/test_survfunc.py b/statsmodels/duration/tests/test_survfunc.py
--- a/statsmodels/duration/tests/test_survfunc.py
+++ b/statsmodels/duration/tests/test_survfunc.py
@@ -21,8 +21,6 @@
 def close_or_save(pdf, fig):
     if pdf_output:
         pdf.savefig(fig)
-    else:
-        plt.close(fig)
 
 
 """
@@ -192,7 +190,7 @@ def test_survdiff():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='requires matplotlib')
-def test_plot_km():
+def test_plot_km(close_figures):
 
     if pdf_output:
         from matplotlib.backends.backend_pdf import PdfPages
diff --git a/statsmodels/genmod/tests/test_gee.py b/statsmodels/genmod/tests/test_gee.py
--- a/statsmodels/genmod/tests/test_gee.py
+++ b/statsmodels/genmod/tests/test_gee.py
@@ -49,14 +49,6 @@
 def close_or_save(pdf, fig):
     if pdf_output:
         pdf.savefig(fig)
-    plt.close(fig)
-
-
-def teardown_module():
-    if have_matplotlib:
-        plt.close('all')
-        if pdf_output:
-            pdf.close()
 
 
 def load_data(fname, icept=True):
@@ -168,7 +160,7 @@ def test_margins_multinomial(self):
         assert_allclose(marg.margeff_se, np.r_[0.1379962], rtol=1e-6)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_nominal_plot(self):
+    def test_nominal_plot(self, close_figures):
         np.random.seed(34234)
         endog = np.r_[0, 0, 0, 0, 1, 1, 1, 1]
         exog = np.ones((8, 2))
@@ -183,7 +175,6 @@ def test_nominal_plot(self):
         # Smoke test for figure
         fig = result.plot_distribution()
         assert_equal(isinstance(fig, plt.Figure), True)
-        plt.close(fig)
 
     def test_margins_poisson(self):
         # Check marginal effects for a Poisson GEE fit.
@@ -815,7 +806,7 @@ def test_nominal_independence(self):
             model1.fit()
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ordinal_plot(self):
+    def test_ordinal_plot(self, close_figures):
         family = Binomial()
 
         endog, exog, groups = load_data("gee_ordinal_1.csv",
@@ -829,7 +820,6 @@ def test_ordinal_plot(self):
         # Smoke test for figure
         fig = rslt.plot_distribution()
         assert_equal(isinstance(fig, plt.Figure), True)
-        plt.close(fig)
 
     def test_nominal(self):
 
@@ -1569,7 +1559,7 @@ def test_wrapper(self):
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plots():
+def test_plots(close_figures):
 
     np.random.seed(378)
     exog = np.random.normal(size=100)
@@ -1582,17 +1572,12 @@ def test_plots():
     # Smoke tests
     fig = result.plot_added_variable(1)
     assert_equal(isinstance(fig, plt.Figure), True)
-    plt.close(fig)
     fig = result.plot_partial_residuals(1)
     assert_equal(isinstance(fig, plt.Figure), True)
-    plt.close(fig)
     fig = result.plot_ceres_residuals(1)
     assert_equal(isinstance(fig, plt.Figure), True)
-    plt.close(fig)
     fig = result.plot_isotropic_dependence()
     assert_equal(isinstance(fig, plt.Figure), True)
-    plt.close(fig)
-
 
 
 def test_missing():
diff --git a/statsmodels/genmod/tests/test_glm.py b/statsmodels/genmod/tests/test_glm.py
--- a/statsmodels/genmod/tests/test_glm.py
+++ b/statsmodels/genmod/tests/test_glm.py
@@ -45,11 +45,9 @@
 def close_or_save(pdf, fig):
     if pdf_output:
         pdf.savefig(fig)
-    plt.close(fig)
 
 def teardown_module():
     if have_matplotlib:
-        plt.close('all')
         if pdf_output:
             pdf.close()
 
@@ -903,7 +901,7 @@ def test_formula_missing_exposure():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plots():
+def test_plots(close_figures):
 
     np.random.seed(378)
     n = 200
diff --git a/statsmodels/graphics/tests/test_agreement.py b/statsmodels/graphics/tests/test_agreement.py
--- a/statsmodels/graphics/tests/test_agreement.py
+++ b/statsmodels/graphics/tests/test_agreement.py
@@ -13,7 +13,7 @@
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_mean_diff_plot():
+def test_mean_diff_plot(close_figures):
 
     # Seed the random number generator.
     # This ensures that the results below are reproducible.
@@ -25,32 +25,25 @@ def test_mean_diff_plot():
     ax = fig.add_subplot(111)
 
     # basic test.
-    fig = mean_diff_plot(m1, m2, ax=ax)
-    plt.close(fig)
+    mean_diff_plot(m1, m2, ax=ax)
 
     # Test with pandas Series.
     p1 = pd.Series(m1)
     p2 = pd.Series(m2)
-    fig = mean_diff_plot(p1, p2)
-    plt.close(fig)
+    mean_diff_plot(p1, p2)
 
     # Test plotting on assigned axis.
     fig, ax = plt.subplots(2)
-    mean_diff_plot(m1, m2, ax = ax[0])
-    plt.close(fig)
+    mean_diff_plot(m1, m2, ax=ax[0])
 
     # Test the setting of confidence intervals.
-    fig = mean_diff_plot(m1, m2, sd_limit = 0)
-    plt.close(fig)
+    mean_diff_plot(m1, m2, sd_limit=0)
 
     # Test asethetic controls.
-    fig = mean_diff_plot(m1, m2, scatter_kwds={'color':'green', 's':10})
-    plt.close(fig)
+    mean_diff_plot(m1, m2, scatter_kwds={'color':'green', 's':10})
 
-    fig = mean_diff_plot(m1, m2, mean_line_kwds={'color':'green', 'lw':5})
-    plt.close(fig)
+    mean_diff_plot(m1, m2, mean_line_kwds={'color':'green', 'lw':5})
 
-    fig = mean_diff_plot(m1, m2, limit_lines_kwds={'color':'green',
-                                                'lw':5,
-                                                'ls':'dotted'})
-    plt.close(fig)
+    mean_diff_plot(m1, m2, limit_lines_kwds={'color':'green',
+                                             'lw':5,
+                                             'ls':'dotted'})
diff --git a/statsmodels/graphics/tests/test_boxplots.py b/statsmodels/graphics/tests/test_boxplots.py
--- a/statsmodels/graphics/tests/test_boxplots.py
+++ b/statsmodels/graphics/tests/test_boxplots.py
@@ -13,7 +13,7 @@
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_violinplot_beanplot():
+def test_violinplot_beanplot(close_figures):
     # Test violinplot and beanplot with the same dataset.
     data = anes96.load_pandas()
     party_ID = np.arange(7)
@@ -30,8 +30,6 @@ def test_violinplot_beanplot():
                           'label_fontsize':'small',
                           'label_rotation':30})
 
-    plt.close(fig)
-
     fig = plt.figure()
     ax = fig.add_subplot(111)
     violinplot(age, ax=ax, labels=labels,
@@ -40,9 +38,6 @@ def test_violinplot_beanplot():
                           'label_rotation':30,
                           'bw_factor':.2})
 
-    plt.close(fig)
-
-
     fig = plt.figure()
     ax = fig.add_subplot(111)
     beanplot(age, ax=ax, labels=labels,
@@ -50,8 +45,6 @@ def test_violinplot_beanplot():
                         'label_fontsize':'small',
                         'label_rotation':30})
 
-    plt.close(fig)
-
     fig = plt.figure()
     ax = fig.add_subplot(111)
     beanplot(age, ax=ax, labels=labels, jitter=True,
@@ -59,8 +52,6 @@ def test_violinplot_beanplot():
                         'label_fontsize': 'small',
                         'label_rotation': 30})
 
-    plt.close(fig)
-
     fig = plt.figure()
     ax = fig.add_subplot(111)
     beanplot(age, ax=ax, labels=labels, jitter=True, side='right',
@@ -68,8 +59,6 @@ def test_violinplot_beanplot():
                         'label_fontsize': 'small',
                         'label_rotation': 30})
 
-    plt.close(fig)
-
     fig = plt.figure()
     ax = fig.add_subplot(111)
     beanplot(age, ax=ax, labels=labels, jitter=True, side='left',
@@ -77,11 +66,7 @@ def test_violinplot_beanplot():
                         'label_fontsize': 'small',
                         'label_rotation': 30})
 
-    plt.close(fig)
-
     fig = plt.figure()
     ax = fig.add_subplot(111)
     beanplot(age, ax=ax, labels=labels,
              plot_opts={'bean_legend_text': 'text'})
-
-    plt.close(fig)
diff --git a/statsmodels/graphics/tests/test_correlation.py b/statsmodels/graphics/tests/test_correlation.py
--- a/statsmodels/graphics/tests/test_correlation.py
+++ b/statsmodels/graphics/tests/test_correlation.py
@@ -13,30 +13,24 @@
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_corr():
+def test_plot_corr(close_figures):
     hie_data = randhie.load_pandas()
     corr_matrix = np.corrcoef(hie_data.data.values.T)
 
-    fig = plot_corr(corr_matrix, xnames=hie_data.names)
-    plt.close(fig)
+    plot_corr(corr_matrix, xnames=hie_data.names)
 
-    fig = plot_corr(corr_matrix, xnames=[], ynames=hie_data.names)
-    plt.close(fig)
+    plot_corr(corr_matrix, xnames=[], ynames=hie_data.names)
 
-    fig = plot_corr(corr_matrix, normcolor=True, title='', cmap='jet')
-    plt.close(fig)
+    plot_corr(corr_matrix, normcolor=True, title='', cmap='jet')
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_corr_grid():
+def test_plot_corr_grid(close_figures):
     hie_data = randhie.load_pandas()
     corr_matrix = np.corrcoef(hie_data.data.values.T)
 
-    fig = plot_corr_grid([corr_matrix] * 2, xnames=hie_data.names)
-    plt.close(fig)
+    plot_corr_grid([corr_matrix] * 2, xnames=hie_data.names)
 
-    fig = plot_corr_grid([corr_matrix] * 5, xnames=[], ynames=hie_data.names)
-    plt.close(fig)
+    plot_corr_grid([corr_matrix] * 5, xnames=[], ynames=hie_data.names)
 
-    fig = plot_corr_grid([corr_matrix] * 3, normcolor=True, titles='', cmap='jet')
-    plt.close(fig)
+    plot_corr_grid([corr_matrix] * 3, normcolor=True, titles='', cmap='jet')
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
@@ -18,11 +18,9 @@
 def close_or_save(pdf, fig):
     if pdf_output:
         pdf.savefig(fig)
-    else:
-        plt.close(fig)
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_all():
+def test_all(close_figures):
 
     if pdf_output:
         from matplotlib.backends.backend_pdf import PdfPages
@@ -416,4 +414,3 @@ 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
@@ -26,17 +26,15 @@ def setup_class(cls):
         cls.days = np.log(np.random.randint(1,30, size=60))
 
 
-    def test_plot_both(self):
+    def test_plot_both(self, close_figures):
         fig = interaction_plot(self.weight, self.duration, self.days,
                  colors=['red','blue'], markers=['D','^'], ms=10)
-        plt.close(fig)
 
-    def test_plot_rainbow(self):
+    def test_plot_rainbow(self, close_figures):
         fig = interaction_plot(self.weight, self.duration, self.days,
                  markers=['D','^'], ms=10)
-        plt.close(fig)
 
-    def test_plot_pandas(self):
+    def test_plot_pandas(self, close_figures):
         weight = Series(self.weight, name='Weight')
         duration = Series(self.duration, name='Duration')
         days = Series(self.days, name='Days')
@@ -47,10 +45,8 @@ def test_plot_pandas(self):
         assert_equal(trace, 'Duration')
         assert_equal(ax.get_ylabel(), 'mean of Days')
         assert_equal(ax.get_xlabel(), 'Weight')
-        plt.close(fig)
 
-
-    def test_plot_string_data(self):
+    def test_plot_string_data(self, close_figures):
         weight = Series(self.weight, name='Weight').astype('str')
         duration = Series(self.duration, name='Duration')
         days = Series(self.days, name='Days')
@@ -61,29 +57,19 @@ def test_plot_string_data(self):
         assert_equal(trace, 'Duration')
         assert_equal(ax.get_ylabel(), 'mean of Days')
         assert_equal(ax.get_xlabel(), 'Weight')
-        plt.close(fig)
 
-    def test_formatting(self):
+    def test_formatting(self, close_figures):
         fig = interaction_plot(self.weight, self.duration, self.days, colors=['r','g'], linestyles=['--','-.'])
         assert_equal(isinstance(fig, plt.Figure), True)
-        plt.close(fig)
 
-    def test_formatting_errors(self):
-        #plt.close('all')
+    def test_formatting_errors(self, close_figures):
         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):
+    def test_plottype(self, close_figures):
         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_functional.py b/statsmodels/graphics/tests/test_functional.py
--- a/statsmodels/graphics/tests/test_functional.py
+++ b/statsmodels/graphics/tests/test_functional.py
@@ -23,7 +23,7 @@
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_basic():
+def test_hdr_basic(close_figures):
     fig, hdr = hdrboxplot(data, labels=labels)
     print(hdr)
 
@@ -58,11 +58,10 @@ def test_hdr_basic():
     outliers = labels[labels_pos]
     assert_equal([1982, 1983, 1997, 1998], outliers)
     assert_equal(labels[hdr.outliers_idx], outliers)
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_plot():
+def test_hdr_plot(close_figures):
     fig = plt.figure()
     ax = fig.add_subplot(111)
 
@@ -73,22 +72,20 @@ def test_hdr_plot():
     ax.set_xticks(np.arange(13, step=3) - 1)
     ax.set_xticklabels(["", "Mar", "Jun", "Sep", "Dec"])
     ax.set_xlim([-0.2, 11.2])
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_alpha():
+def test_hdr_alpha(close_figures):
     fig, hdr = hdrboxplot(data, alpha=[0.7])
     extra_quant_t = np.vstack([[25.1, 26.5, 27.0, 26.4, 25.4, 24.1,
                                 23.0, 22.0, 21.7, 22.1, 22.7, 23.8],
                                [23.4, 24.8, 25.0, 23.9, 22.4, 21.1,
                                 20.0, 19.3, 19.2, 19.4, 20.1, 21.3]])
     assert_almost_equal(hdr.extra_quantiles, extra_quant_t, decimal=0)
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_multiple_alpha():
+def test_hdr_multiple_alpha(close_figures):
     fig, hdr = hdrboxplot(data, alpha=[0.4, 0.92])
     extra_quant_t = [[25.712, 27.052, 27.711, 27.200,
                       26.162, 24.833, 23.639, 22.378,
@@ -103,34 +100,30 @@ def test_hdr_multiple_alpha():
                       23.177, 21.923, 20.791, 20.015,
                       19.697, 19.951, 20.622, 21.858]]
     assert_almost_equal(hdr.extra_quantiles, np.vstack(extra_quant_t), decimal=0)
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_threshold():
+def test_hdr_threshold(close_figures):
     fig, hdr = hdrboxplot(data, alpha=[0.8], threshold=0.93)
     labels_pos = np.all(np.in1d(data, hdr.outliers).reshape(data.shape), axis=1)
     outliers = labels[labels_pos]
     assert_equal([1968, 1982, 1983, 1997, 1998], outliers)
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_bw():
+def test_hdr_bw(close_figures):
     fig, hdr = hdrboxplot(data, bw='cv_ml')
     median_t = [24.25, 25.64, 25.99, 25.04, 23.71, 22.38,
                 21.31, 20.44, 20.24, 20.51, 21.19, 22.38]
     assert_almost_equal(hdr.median, median_t, decimal=2)
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_hdr_ncomp():
+def test_hdr_ncomp(close_figures):
     fig, hdr = hdrboxplot(data, ncomp=3)
     median_t = [24.33, 25.71, 26.04, 25.08, 23.74, 22.40,
                 21.32, 20.45, 20.25, 20.53, 21.2 , 22.39]
     assert_almost_equal(hdr.median, median_t, decimal=2)
-    plt.close(fig)
 
 
 def test_banddepth_BD2():
@@ -169,7 +162,7 @@ def test_banddepth_MBD():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_fboxplot_rainbowplot():
+def test_fboxplot_rainbowplot(close_figures):
     # Test fboxplot and rainbowplot together, is much faster.
     def harmfunc(t):
         """Test function, combination of a few harmonic terms."""
@@ -203,9 +196,6 @@ def harmfunc(t):
     ix_expected2 = np.array([2, 11, 17, 18])
     assert_equal(ix_outliers, ix_expected2)
 
-    plt.close(fig)
-
     # rainbowplot test (re-uses depth variable)
     xdata = np.arange(data[0].size)
     fig = rainbowplot(data, xdata=xdata, depth=depth, cmap=plt.cm.rainbow)
-    plt.close(fig)
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
@@ -1,10 +1,8 @@
 import numpy as np
 import pytest
-
-import statsmodels.api as sm
-from statsmodels.graphics.gofplots import qqplot, qqline, ProbPlot
 from scipy import stats
 
+import statsmodels.api as sm
 
 try:
     import matplotlib.pyplot as plt
@@ -21,90 +19,89 @@ def base_setup(self):
         self.other_array = np.random.normal(size=self.prbplt.data.shape)
         self.other_prbplot = sm.ProbPlot(self.other_array)
 
-    def teardown(self):
-        if have_matplotlib:
-            plt.close('all')
-
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot(self):
-        self.fig = self.prbplt.qqplot(ax=self.ax, line=self.line)
+    def test_qqplot(self, close_figures):
+        self.prbplt.qqplot(ax=self.ax, line=self.line)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ppplot(self):
-        plt.close('all')
-        self.fig = self.prbplt.ppplot(ax=self.ax, line=self.line)
+    def test_ppplot(self, close_figures):
+        self.prbplt.ppplot(ax=self.ax, line=self.line)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_probplot(self):
-        self.fig = self.prbplt.probplot(ax=self.ax, line=self.line)
+    def test_probplot(self, close_figures):
+        self.prbplt.probplot(ax=self.ax, line=self.line)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_other_array(self):
-        self.fig = self.prbplt.qqplot(ax=self.ax, line=self.line,
-                                        other=self.other_array)
+    def test_qqplot_other_array(self, close_figures):
+        self.prbplt.qqplot(ax=self.ax, line=self.line,
+                           other=self.other_array)
+
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ppplot_other_array(self):
-        self.fig = self.prbplt.ppplot(ax=self.ax, line=self.line,
-                                        other=self.other_array)
+    def test_ppplot_other_array(self, close_figures):
+        self.prbplt.ppplot(ax=self.ax, line=self.line,
+                           other=self.other_array)
+
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def t_est_probplot_other_array(self):
-        self.fig = self.prbplt.probplot(ax=self.ax, line=self.line,
-                                        other=self.other_array)
+    def t_est_probplot_other_array(self, close_figures):
+        self.prbplt.probplot(ax=self.ax, line=self.line,
+                             other=self.other_array)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_other_prbplt(self):
-        self.fig = self.prbplt.qqplot(ax=self.ax, line=self.line,
-                                        other=self.other_prbplot)
+    def test_qqplot_other_prbplt(self, close_figures):
+        self.prbplt.qqplot(ax=self.ax, line=self.line,
+                           other=self.other_prbplot)
+
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ppplot_other_prbplt(self):
-        self.fig = self.prbplt.ppplot(ax=self.ax, line=self.line,
-                                        other=self.other_prbplot)
+    def test_ppplot_other_prbplt(self, close_figures):
+        self.prbplt.ppplot(ax=self.ax, line=self.line,
+                           other=self.other_prbplot)
+
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def t_est_probplot_other_prbplt(self):
-        self.fig = self.prbplt.probplot(ax=self.ax, line=self.line,
-                                        other=self.other_prbplot)
+    def t_est_probplot_other_prbplt(self, close_figures):
+        self.prbplt.probplot(ax=self.ax, line=self.line,
+                             other=self.other_prbplot)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_custom_labels(self):
-        self.fig = self.prbplt.qqplot(ax=self.ax, line=self.line,
-                                      xlabel='Custom X-Label',
-                                      ylabel='Custom Y-Label')
+    def test_qqplot_custom_labels(self, close_figures):
+        self.prbplt.qqplot(ax=self.ax, line=self.line,
+                           xlabel='Custom X-Label',
+                           ylabel='Custom Y-Label')
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ppplot_custom_labels(self):
-        self.fig = self.prbplt.ppplot(ax=self.ax, line=self.line,
-                                      xlabel='Custom X-Label',
-                                      ylabel='Custom Y-Label')
+    def test_ppplot_custom_labels(self, close_figures):
+        self.prbplt.ppplot(ax=self.ax, line=self.line,
+                           xlabel='Custom X-Label',
+                           ylabel='Custom Y-Label')
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_probplot_custom_labels(self):
-        self.fig = self.prbplt.probplot(ax=self.ax, line=self.line,
-                                        xlabel='Custom X-Label',
-                                        ylabel='Custom Y-Label')
+    def test_probplot_custom_labels(self, close_figures):
+        self.prbplt.probplot(ax=self.ax, line=self.line,
+                             xlabel='Custom X-Label',
+                             ylabel='Custom Y-Label')
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_pltkwargs(self):
-        self.fig = self.prbplt.qqplot(ax=self.ax, line=self.line,
-                                      marker='d',
-                                      markerfacecolor='cornflowerblue',
-                                      markeredgecolor='white',
-                                      alpha=0.5)
+    def test_qqplot_pltkwargs(self, close_figures):
+        self.prbplt.qqplot(ax=self.ax, line=self.line,
+                           marker='d',
+                           markerfacecolor='cornflowerblue',
+                           markeredgecolor='white',
+                           alpha=0.5)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ppplot_pltkwargs(self):
-        self.fig = self.prbplt.ppplot(ax=self.ax, line=self.line,
-                                      marker='d',
-                                      markerfacecolor='cornflowerblue',
-                                      markeredgecolor='white',
-                                      alpha=0.5)
+    def test_ppplot_pltkwargs(self, close_figures):
+        self.prbplt.ppplot(ax=self.ax, line=self.line,
+                           marker='d',
+                           markerfacecolor='cornflowerblue',
+                           markeredgecolor='white',
+                           alpha=0.5)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_probplot_pltkwargs(self):
-        self.fig = self.prbplt.probplot(ax=self.ax, line=self.line,
-                                        marker='d',
-                                        markerfacecolor='cornflowerblue',
-                                        markeredgecolor='white',
-                                        alpha=0.5)
+    def test_probplot_pltkwargs(self, close_figures):
+        self.prbplt.probplot(ax=self.ax, line=self.line,
+                             marker='d',
+                             markerfacecolor='cornflowerblue',
+                             markeredgecolor='white',
+                             alpha=0.5)
 
 
 class TestProbPlotLongely(BaseProbplotMixin):
@@ -155,34 +152,29 @@ def setup(self):
         self.other_array = np.random.normal(size=self.prbplt.data.shape)
         self.other_prbplot = sm.ProbPlot(self.other_array)
 
-    def teardown(self):
-        if have_matplotlib:
-            plt.close('all')
-
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot(self):
-        fig = sm.qqplot(self.res, line='r')
+    def test_qqplot(self, close_figures):
+        sm.qqplot(self.res, line='r')
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_pltkwargs(self):
-        fig = sm.qqplot(self.res, line='r', marker='d',
-                                      markerfacecolor='cornflowerblue',
-                                      markeredgecolor='white',
-                                      alpha=0.5)
+    def test_qqplot_pltkwargs(self, close_figures):
+        sm.qqplot(self.res, line='r', marker='d',
+                  markerfacecolor='cornflowerblue',
+                  markeredgecolor='white',
+                  alpha=0.5)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_2samples_ProbPlotObjects(self):
+    def test_qqplot_2samples_ProbPlotObjects(self, close_figures):
         # also tests all values for line
         for line in ['r', 'q', '45', 's']:
             # test with `ProbPlot` instances
-            fig = sm.qqplot_2samples(self.prbplt, self.other_prbplot,
-                                     line=line)
-            plt.close('all')
+            sm.qqplot_2samples(self.prbplt, self.other_prbplot,
+                               line=line)
+
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_qqplot_2samples_arrays(self):
+    def test_qqplot_2samples_arrays(self, close_figures):
         # 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')
+            sm.qqplot_2samples(self.res, self.other_array, line=line)
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
@@ -34,7 +34,7 @@
 
 @pytest.mark.skipif(not have_matplotlib or pandas_old,
         reason='matplotlib not available or pandas too old')
-def test_data_conversion():
+def test_data_conversion(close_figures):
     # It will not reorder the elements
     # so the dictionary will look odd
     # as it key order has the c and b
@@ -76,7 +76,7 @@ def test_data_conversion():
     pylab.close('all')
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_mosaic_simple():
+def test_mosaic_simple(close_figures):
     # display a simple plot of 4 categories of data, splitted in four
     # levels with increasing size for each group
     # creation of the levels
@@ -108,7 +108,7 @@ def test_mosaic_simple():
 
 @pytest.mark.skipif(not have_matplotlib or pandas_old,
         reason='matplotlib not available or pandas too old')
-def test_mosaic():
+def test_mosaic(close_figures):
     # make the same analysis on a known dataset
 
     # load the data and clean it a bit
@@ -146,7 +146,7 @@ def test_mosaic():
     pylab.close('all')
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_mosaic_very_complex():
+def test_mosaic_very_complex(close_figures):
     # make a scattermatrix of mosaic plots to show the correlations between
     # each pair of variable in a dataset. Could be easily converted into a
     # new function that does this automatically based on the type of data
@@ -188,7 +188,7 @@ def test_mosaic_very_complex():
     pylab.close('all')
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_axes_labeling():
+def test_axes_labeling(close_figures):
     from numpy.random import rand
     key_set = (['male', 'female'], ['old', 'adult', 'young'],
                ['worker', 'unemployed'], ['yes', 'no'])
@@ -208,7 +208,7 @@ def test_axes_labeling():
 
 @pytest.mark.skipif(not have_matplotlib or pandas_old,
         reason='matplotlib not available or pandas too old')
-def test_mosaic_empty_cells():
+def test_mosaic_empty_cells(close_figures):
     # SMOKE test  see #2286
     import pandas as pd
     mydata = pd.DataFrame({'id2': {64: 'Angelica',
@@ -436,7 +436,7 @@ def test_gap_split():
 
 @pytest.mark.skipif(not have_matplotlib or pandas_old,
         reason='matplotlib not available or pandas too old')
-def test_default_arg_index():
+def test_default_arg_index(close_figures):
     # 2116
     import pandas as pd
     df = pd.DataFrame({'size' : ['small', 'large', 'large', 'small', 'large',
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
@@ -13,7 +13,7 @@
 try:
     import matplotlib.pyplot as plt  #makes plt available for test functions
     have_matplotlib = True
-except:
+except ImportError:
     have_matplotlib = False
 
 pdf_output = False
@@ -24,16 +24,10 @@
 else:
     pdf = None
 
+
 def close_or_save(pdf, fig):
     if pdf_output:
         pdf.savefig(fig)
-    plt.close(fig)
-
-@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def teardown_module():
-    plt.close('all')
-    if pdf_output:
-        pdf.close()
 
 class TestPlot(object):
 
@@ -52,7 +46,7 @@ def setup(self):
         self.res = res
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_fit(self):
+    def test_plot_fit(self, close_figures):
         res = self.res
 
         fig = plot_fit(res, 0, y_true=None)
@@ -72,29 +66,22 @@ def test_plot_fit(self):
         close_or_save(pdf, fig)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_oth(self):
+    def test_plot_oth(self, close_figures):
         #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')
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_influence(self):
+    def test_plot_influence(self, close_figures):
         infl = self.res.get_influence()
         fig = influence_plot(self.res)
         assert_equal(isinstance(fig, plt.Figure), True)
@@ -107,7 +94,6 @@ def test_plot_influence(self):
         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)
@@ -118,15 +104,13 @@ def test_plot_influence(self):
             assert_array_less(ssr, 1e-12)
         except AttributeError:
             pass
-        plt.close(fig)
 
         assert_raises(ValueError, influence_plot, self.res, criterion='unknown')
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_leverage_resid2(self):
+    def test_plot_leverage_resid2(self, close_figures):
         fig = plot_leverage_resid2(self.res)
         assert_equal(isinstance(fig, plt.Figure), True)
-        plt.close(fig)
 
 
 class TestPlotPandas(TestPlot):
@@ -149,15 +133,14 @@ def setup(self):
         self.data = data
 
 class TestPlotFormula(TestPlotPandas):
+
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_one_column_exog(self):
+    def test_one_column_exog(self, close_figures):
         from statsmodels.formula.api import ols
         res = ols("y~var1-1", data=self.data).fit()
         fig = plot_regress_exog(res, "var1")
-        plt.close(fig)
         res = ols("y~var1", data=self.data).fit()
         fig = plot_regress_exog(res, "var1")
-        plt.close(fig)
 
 
 class TestABLine(object):
@@ -173,14 +156,14 @@ def setup_class(cls):
         cls.mod = mod
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_abline_model(self):
+    def test_abline_model(self, close_figures):
         fig = abline_plot(model_results=self.mod)
         ax = fig.axes[0]
         ax.scatter(self.X[:,1], self.y)
         close_or_save(pdf, fig)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_abline_model_ax(self):
+    def test_abline_model_ax(self, close_figures):
         fig = plt.figure()
         ax = fig.add_subplot(111)
         ax.scatter(self.X[:,1], self.y)
@@ -188,14 +171,14 @@ def test_abline_model_ax(self):
         close_or_save(pdf, fig)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_abline_ab(self):
+    def test_abline_ab(self, close_figures):
         mod = self.mod
         intercept, slope = mod.params
         fig = abline_plot(intercept=intercept, slope=slope)
         close_or_save(pdf, fig)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_abline_ab_ax(self):
+    def test_abline_ab_ax(self, close_figures):
         mod = self.mod
         intercept, slope = mod.params
         fig = plt.figure()
@@ -205,7 +188,7 @@ def test_abline_ab_ax(self):
         close_or_save(pdf, fig)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_abline_remove(self):
+    def test_abline_remove(self, close_figures):
         mod = self.mod
         intercept, slope = mod.params
         fig = plt.figure()
@@ -231,17 +214,18 @@ def setup_class(cls):
         mod = sm.OLS(y,X).fit()
         cls.mod = mod
 
+
 class TestAddedVariablePlot(object):
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_added_variable_poisson(self):
+    def test_added_variable_poisson(self, close_figures):
 
         np.random.seed(3446)
 
         n = 100
         p = 3
         exog = np.random.normal(size=(n, p))
-        lin_pred = 4 + exog[:, 0] + 0.2*exog[:, 1]**2
+        lin_pred = 4 + exog[:, 0] + 0.2 * exog[:, 1]**2
         expval = np.exp(lin_pred)
         endog = np.random.poisson(expval)
 
@@ -254,7 +238,7 @@ def test_added_variable_poisson(self):
                     weight_str = ["Unweighted", "Weighted"][use_glm_weights]
 
                     # Run directly and called as a results method.
-                    for j in 0,1:
+                    for j in 0, 1:
 
                         if j == 0:
                             fig = plot_added_variable(results, focus_col,
@@ -263,8 +247,8 @@ def test_added_variable_poisson(self):
                             ti = "Added variable plot"
                         else:
                             fig = results.plot_added_variable(focus_col,
-                                                 use_glm_weights=use_glm_weights,
-                                                 resid_type=resid_type)
+                                                              use_glm_weights=use_glm_weights,
+                                                              resid_type=resid_type)
                             ti = "Added variable plot (called as method)"
                         ax = fig.get_axes()[0]
 
@@ -278,12 +262,13 @@ def test_added_variable_poisson(self):
                         ti += "Using '%s' residuals" % resid_type
                         ax.set_title(ti)
                         close_or_save(pdf, fig)
+                        close_figures()
 
 
 class TestPartialResidualPlot(object):
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_partial_residual_poisson(self):
+    def test_partial_residual_poisson(self, close_figures):
 
         np.random.seed(3446)
 
@@ -319,7 +304,7 @@ def test_partial_residual_poisson(self):
 class TestCERESPlot(object):
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_ceres_poisson(self):
+    def test_ceres_poisson(self, close_figures):
 
         np.random.seed(3446)
 
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
@@ -22,8 +22,9 @@
 pandas_lt_0_19_2 = LooseVersion(pd.__version__) < '0.19.1'
 
 
+
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_acf():
+def test_plot_acf(close_figures):
     # Just test that it runs.
     fig = plt.figure()
     ax = fig.add_subplot(111)
@@ -37,11 +38,9 @@ def test_plot_acf():
     plot_acf(acf, ax=ax)
     plot_acf(acf, ax=ax, alpha=None)
 
-    plt.close(fig)
-
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_acf_irregular():
+def test_plot_acf_irregular(close_figures):
     # Just test that it runs.
     fig = plt.figure()
     ax = fig.add_subplot(111)
@@ -55,11 +54,9 @@ def test_plot_acf_irregular():
     plot_acf(acf, ax=ax, lags=10, zero=False)
     plot_acf(acf, ax=ax, alpha=None, zero=False)
 
-    plt.close(fig)
-
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_pacf():
+def test_plot_pacf(close_figures):
     # Just test that it runs.
     fig = plt.figure()
     ax = fig.add_subplot(111)
@@ -72,11 +69,9 @@ def test_plot_pacf():
     plot_pacf(pacf, ax=ax)
     plot_pacf(pacf, ax=ax, alpha=None)
 
-    plt.close(fig)
-
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_pacf_kwargs():
+def test_plot_pacf_kwargs(close_figures):
     # Just test that it runs.
     fig = plt.figure()
     ax = fig.add_subplot(111)
@@ -90,14 +85,12 @@ def test_plot_pacf_kwargs():
     buff = BytesIO()
     plot_pacf(pacf, ax=ax)
     fig.savefig(buff, format='rgba')
-    plt.close(fig)
 
     buff_linestyle = BytesIO()
     fig_linestyle = plt.figure()
     ax = fig_linestyle.add_subplot(111)
     plot_pacf(pacf, ax=ax, ls='-')
     fig_linestyle.savefig(buff_linestyle, format='rgba')
-    plt.close(fig_linestyle)
 
     buff_with_vlines = BytesIO()
     fig_with_vlines = plt.figure()
@@ -105,7 +98,6 @@ def test_plot_pacf_kwargs():
     vlines_kwargs = {'linestyles': 'dashdot'}
     plot_pacf(pacf, ax=ax, vlines_kwargs=vlines_kwargs)
     fig_with_vlines.savefig(buff_with_vlines, format='rgba')
-    plt.close(fig_with_vlines)
 
     buff.seek(0)
     buff_linestyle.seek(0)
@@ -120,7 +112,7 @@ def test_plot_pacf_kwargs():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_acf_kwargs():
+def test_plot_acf_kwargs(close_figures):
     # Just test that it runs.
     fig = plt.figure()
     ax = fig.add_subplot(111)
@@ -134,7 +126,6 @@ def test_plot_acf_kwargs():
     buff = BytesIO()
     plot_acf(acf, ax=ax)
     fig.savefig(buff, format='rgba')
-    plt.close(fig)
 
     buff_with_vlines = BytesIO()
     fig_with_vlines = plt.figure()
@@ -142,7 +133,6 @@ def test_plot_acf_kwargs():
     vlines_kwargs = {'linestyles': 'dashdot'}
     plot_acf(acf, ax=ax, vlines_kwargs=vlines_kwargs)
     fig_with_vlines.savefig(buff_with_vlines, format='rgba')
-    plt.close(fig_with_vlines)
 
     buff.seek(0)
     buff_with_vlines.seek(0)
@@ -153,7 +143,7 @@ def test_plot_acf_kwargs():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_pacf_irregular():
+def test_plot_pacf_irregular(close_figures):
     # Just test that it runs.
     fig = plt.figure()
     ax = fig.add_subplot(111)
@@ -167,12 +157,10 @@ def test_plot_pacf_irregular():
     plot_pacf(pacf, ax=ax, lags=10, zero=False)
     plot_pacf(pacf, ax=ax, alpha=None, zero=False)
 
-    plt.close(fig)
-
 
 @pytest.mark.skipif(not have_matplotlib or pandas_lt_0_19_2,
         reason='matplotlib not available or pandas too old')
-def test_plot_month():
+def test_plot_month(close_figures):
     dta = sm.datasets.elnino.load_pandas().data
     dta['YEAR'] = dta.YEAR.astype(int).apply(str)
     dta = dta.set_index('YEAR').T.unstack()
@@ -180,52 +168,45 @@ def test_plot_month():
 
     # test dates argument
     fig = month_plot(dta.values, dates=dates, ylabel='el nino')
-    plt.close(fig)
 
     # test with a TimeSeries DatetimeIndex with no freq
     dta.index = pd.DatetimeIndex(dates)
     fig = month_plot(dta)
-    plt.close(fig)
 
     # w freq
     dta.index = pd.DatetimeIndex(dates, freq='MS')
     fig = month_plot(dta)
-    plt.close(fig)
 
     # test with a TimeSeries PeriodIndex
     dta.index = pd.PeriodIndex(dates, freq='M')
     fig = month_plot(dta)
-    plt.close(fig)
 
 
 @pytest.mark.skipif(not have_matplotlib or pandas_lt_0_19_2,
         reason='matplotlib not available or pandas too old')
-def test_plot_quarter():
+def test_plot_quarter(close_figures):
     dta = sm.datasets.macrodata.load_pandas().data
     dates = lmap('Q'.join, zip(dta.year.astype(int).apply(str),
                                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
     dta.set_index(pd.to_datetime(dates), inplace=True)
     quarter_plot(dta.unemp)
-    plt.close('all')
 
     # w freq
     # see pandas #6631
     dta.index = pd.DatetimeIndex(pd.to_datetime(dates), freq='QS-Oct')
     quarter_plot(dta.unemp)
-    plt.close('all')
 
     # w PeriodIndex
     dta.index = pd.PeriodIndex(pd.to_datetime(dates), freq='Q')
     quarter_plot(dta.unemp)
-    plt.close('all')
+
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_seasonal_plot():
+def test_seasonal_plot(close_figures):
     rs = np.random.RandomState(1234)
     data = rs.randn(20,12)
     data += 6*np.sin(np.arange(12.0)/11*np.pi)[None,:]
@@ -239,4 +220,3 @@ 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/imputation/tests/test_mice.py b/statsmodels/imputation/tests/test_mice.py
--- a/statsmodels/imputation/tests/test_mice.py
+++ b/statsmodels/imputation/tests/test_mice.py
@@ -30,9 +30,6 @@ def close_or_save(pdf, fig):
 
 
 def teardown_module():
-    if not have_matplotlib:
-        return
-    plt.close('all')
     if pdf_output:
         pdf.close()
 
@@ -223,7 +220,7 @@ def test_set_imputer(self):
 
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_missing_pattern(self):
+    def test_plot_missing_pattern(self, close_figures):
 
         df = gendat()
         imp_data = mice.MICEData(df)
@@ -239,7 +236,7 @@ def test_plot_missing_pattern(self):
 
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_bivariate(self):
+    def test_plot_bivariate(self, close_figures):
 
         df = gendat()
         imp_data = mice.MICEData(df)
@@ -253,7 +250,7 @@ def test_plot_bivariate(self):
 
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_fit_obs(self):
+    def test_fit_obs(self, close_figures):
 
         df = gendat()
         imp_data = mice.MICEData(df)
@@ -267,7 +264,7 @@ def test_fit_obs(self):
 
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_imputed_hist(self):
+    def test_plot_imputed_hist(self, close_figures):
 
         df = gendat()
         imp_data = mice.MICEData(df)
diff --git a/statsmodels/multivariate/tests/test_factor.py b/statsmodels/multivariate/tests/test_factor.py
--- a/statsmodels/multivariate/tests/test_factor.py
+++ b/statsmodels/multivariate/tests/test_factor.py
@@ -191,18 +191,14 @@ def test_example_compare_to_R_output():
 
 
 @pytest.mark.skipif(missing_matplotlib, reason='matplotlib not available')
-def test_plots():
+def test_plots(close_figures):
     mod = Factor(X.iloc[:, 1:], 3)
     results = mod.fit()
     results.rotate('oblimin')
     fig = results.plot_scree()
-    plt.close(fig)
 
     fig_loadings = results.plot_loadings()
     assert_equal(3, len(fig_loadings))
-    for fig in fig_loadings[:-1]:
-        plt.close(fig)
-    plt.close('all')
 
 
 def test_getframe_smoke():
diff --git a/statsmodels/multivariate/tests/test_pca.py b/statsmodels/multivariate/tests/test_pca.py
--- a/statsmodels/multivariate/tests/test_pca.py
+++ b/statsmodels/multivariate/tests/test_pca.py
@@ -52,7 +52,7 @@ def setup_class(cls):
         cls.x_wide = f.dot(b) + e
 
     @pytest.mark.skipif(missing_matplotlib, reason='matplotlib not available')
-    def test_smoke_plot_and_repr(self):
+    def test_smoke_plot_and_repr(self, close_figures):
         pc = PCA(self.x)
         fig = pc.plot_scree()
         fig = pc.plot_scree(ncomp=10)
@@ -188,7 +188,7 @@ def test_warnings_and_errors(self):
         assert_raises(ValueError, PCA, np.nan * np.ones((200,100)), tol=2.0)
 
     @pytest.mark.skipif(missing_matplotlib, reason='matplotlib not available')
-    def test_pandas(self):
+    def test_pandas(self, close_figures):
         pc = PCA(pd.DataFrame(self.x))
         pc1 = PCA(self.x)
         assert_allclose(pc.factors.values, pc1.factors)
diff --git a/statsmodels/regression/tests/test_recursive_ls.py b/statsmodels/regression/tests/test_recursive_ls.py
--- a/statsmodels/regression/tests/test_recursive_ls.py
+++ b/statsmodels/regression/tests/test_recursive_ls.py
@@ -266,38 +266,32 @@ def test_estimates():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plots():
+def test_plots(close_figures):
     exog = add_constant(dta[['m1', 'pop']])
     mod = RecursiveLS(endog, exog)
     res = mod.fit()
 
     # Basic plot
     fig = res.plot_recursive_coefficient()
-    plt.close(fig)
 
     # Specific variable
     fig = res.plot_recursive_coefficient(variables=['m1'])
-    plt.close(fig)
 
     # All variables
     fig = res.plot_recursive_coefficient(variables=[0, 'm1', 'pop'])
-    plt.close(fig)
 
     # Basic plot
     fig = res.plot_cusum()
-    plt.close(fig)
 
     # Other alphas
     for alpha in [0.01, 0.10]:
         fig = res.plot_cusum(alpha=alpha)
-        plt.close(fig)
 
     # Invalid alpha
     assert_raises(ValueError, res.plot_cusum, alpha=0.123)
 
     # Basic plot
     fig = res.plot_cusum_squares()
-    plt.close(fig)
 
     # Numpy input (no dates)
     mod = RecursiveLS(endog.values, exog.values)
@@ -305,15 +299,12 @@ def test_plots():
 
     # Basic plot
     fig = res.plot_recursive_coefficient()
-    plt.close(fig)
 
     # Basic plot
     fig = res.plot_cusum()
-    plt.close(fig)
 
     # Basic plot
     fig = res.plot_cusum_squares()
-    plt.close(fig)
 
 
 def test_from_formula():
diff --git a/statsmodels/sandbox/tests/test_predict_functional.py b/statsmodels/sandbox/tests/test_predict_functional.py
--- a/statsmodels/sandbox/tests/test_predict_functional.py
+++ b/statsmodels/sandbox/tests/test_predict_functional.py
@@ -35,12 +35,9 @@ def teardown_class(cls):
     def close_or_save(self, fig):
         if pdf_output:
             self.pdf.savefig(fig)
-        else:
-            plt.close(fig)
-
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_formula(self):
+    def test_formula(self, close_figures):
 
         np.random.seed(542)
         n = 500
@@ -92,9 +89,8 @@ def test_formula(self):
         plt.title("Linear model prediction")
         self.close_or_save(fig)
 
-
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_lm_contrast(self):
+    def test_lm_contrast(self, close_figures):
 
         np.random.seed(542)
         n = 200
@@ -128,9 +124,8 @@ def test_lm_contrast(self):
         plt.title("Linear model contrast")
         self.close_or_save(fig)
 
-
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_glm_formula_contrast(self):
+    def test_glm_formula_contrast(self, close_figures):
 
         np.random.seed(542)
         n = 50
@@ -165,9 +160,8 @@ def test_glm_formula_contrast(self):
         plt.title("Poisson regression contrast")
         self.close_or_save(fig)
 
-
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_scb(self):
+    def test_scb(self, close_figures):
 
         np.random.seed(473)
         n = 100
@@ -232,7 +226,7 @@ def test_scb(self):
 
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_glm_formula(self):
+    def test_glm_formula(self, close_figures):
 
         np.random.seed(542)
         n = 500
@@ -300,9 +294,8 @@ def test_glm_formula(self):
             plt.title("Binomial GLM prediction")
             self.close_or_save(fig)
 
-
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_noformula_prediction(self):
+    def test_noformula_prediction(self, close_figures):
 
         np.random.seed(6434)
         n = 200
diff --git a/statsmodels/stats/tests/test_influence.py b/statsmodels/stats/tests/test_influence.py
--- a/statsmodels/stats/tests/test_influence.py
+++ b/statsmodels/stats/tests/test_influence.py
@@ -87,36 +87,26 @@ def test_basics(self):
                         infl1.d_fittedvalues_scaled, rtol=5e-9)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plots(self):
+    def test_plots(self, close_figures):
         # SMOKE tests for plots
         infl1 = self.infl1
         infl0 = self.infl0
 
         fig = infl0.plot_influence(external=False)
-        plt.close(fig)
         fig = infl1.plot_influence(external=False)
-        plt.close(fig)
 
         fig = infl0.plot_index('resid', threshold=0.2, title='')
-        plt.close(fig)
         fig = infl1.plot_index('resid', threshold=0.2, title='')
-        plt.close(fig)
 
         fig = infl0.plot_index('dfbeta', idx=1, threshold=0.2, title='')
-        plt.close(fig)
         fig = infl1.plot_index('dfbeta', idx=1, threshold=0.2, title='')
-        plt.close(fig)
 
         fig = infl0.plot_index('cook', idx=1, threshold=0.2, title='')
-        plt.close(fig)
         fig = infl1.plot_index('cook', idx=1, threshold=0.2, title='')
-        plt.close(fig)
 
         fig = infl0.plot_index('hat', idx=1, threshold=0.2, title='')
-        plt.close(fig)
         fig = infl1.plot_index('hat', idx=1, threshold=0.2, title='')
-        plt.close(fig)
-        plt.close('all')
+
 
     def test_summary(self):
         infl1 = self.infl1
diff --git a/statsmodels/stats/tests/test_pairwise.py b/statsmodels/stats/tests/test_pairwise.py
--- a/statsmodels/stats/tests/test_pairwise.py
+++ b/statsmodels/stats/tests/test_pairwise.py
@@ -192,13 +192,12 @@ def test_shortcut_function(self):
         res = pairwise_tukeyhsd(self.endog, self.groups, alpha=self.alpha)
         assert_almost_equal(res.confint, self.res.confint, decimal=14)
 
-    def test_plot_simultaneous_ci(self):
+    def test_plot_simultaneous_ci(self, close_figures):
         # smoke tests
         self.res._simultaneous_ci()
         if has_maplotlib:
             reference = self.res.groupsunique[1]
             fig = self.res.plot_simultaneous(comparison_name=reference)
-            plt.close('all')
 
 
 class TestTuckeyHSD2(CheckTuckeyHSDMixin):
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
@@ -91,7 +91,7 @@ def test_roots(self):
             kwds[key] = value  # reset dict
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_power_plot(self):
+    def test_power_plot(self, close_figures):
         if self.cls == smp.FTestPower:
             pytest.skip('skip FTestPower plot_power')
         plt.close()
@@ -110,7 +110,6 @@ def test_power_plot(self):
                                   #alternative='larger',
                                   ax=ax, title='',
                                   **self.kwds_extra)
-        plt.close(fig)
 
 #''' test cases
 #one sample
diff --git a/statsmodels/tsa/statespace/tests/test_dynamic_factor.py b/statsmodels/tsa/statespace/tests/test_dynamic_factor.py
--- a/statsmodels/tsa/statespace/tests/test_dynamic_factor.py
+++ b/statsmodels/tsa/statespace/tests/test_dynamic_factor.py
@@ -72,7 +72,7 @@ def test_params(self):
         self.model.enforce_stationarity = True
         assert_allclose(actual, self.model.start_params)
 
-    def test_results(self):
+    def test_results(self, close_figures):
         # Smoke test for creating the summary
         with warnings.catch_warnings():
             warnings.simplefilter("ignore")
@@ -92,7 +92,6 @@ def test_results(self):
         # Smoke test for plot_coefficients_of_determination
         if have_matplotlib:
             fig = self.results.plot_coefficients_of_determination();
-            plt.close(fig)
 
     def test_no_enforce(self):
         return
diff --git a/statsmodels/tsa/statespace/tests/test_sarimax.py b/statsmodels/tsa/statespace/tests/test_sarimax.py
--- a/statsmodels/tsa/statespace/tests/test_sarimax.py
+++ b/statsmodels/tsa/statespace/tests/test_sarimax.py
@@ -990,7 +990,7 @@ def test_transform_untransform(self):
         assert_almost_equal(constrained, true_constrained, 4)
         self.model.enforce_stationarity, self.model.enforce_invertibility = stat, inv
 
-    def test_results(self):
+    def test_results(self, close_figures):
         self.result = self.model.filter(self.true_params)
 
         # Just make sure that no exceptions are thrown during summary
@@ -999,7 +999,6 @@ def test_results(self):
         # Make sure that no exceptions are thrown during plot_diagnostics
         if have_matplotlib:
             fig = self.result.plot_diagnostics()
-            plt.close(fig)
 
         # And make sure no expections are thrown calculating any of the
         # covariance matrix types
@@ -1718,7 +1717,7 @@ def setup_class(cls, *args, **kwargs):
         # Modify true params to convert from mean to intercept form
         cls.true_params[:2] = (1 - cls.true_params[2:5].sum()) * cls.true_params[:2]
 
-    def test_results(self):
+    def test_results(self, close_figures):
         self.result = self.model.filter(self.true_params)
 
         # Just make sure that no exceptions are thrown during summary
@@ -1727,7 +1726,6 @@ def test_results(self):
         # Make sure that no exceptions are thrown during plot_diagnostics
         if have_matplotlib:
             fig = self.result.plot_diagnostics()
-            plt.close(fig)
 
         # And make sure no expections are thrown calculating any of the
         # covariance matrix types
@@ -1771,7 +1769,7 @@ def setup_class(cls, *args, **kwargs):
         kwargs['seasonal_order'] = (3,2,2,4)
         super(Test_seasonal_arma_diff_seasonal_diff, cls).setup_class(47, *args, **kwargs)
 
-    def test_results(self):
+    def test_results(self, close_figures):
         self.result = self.model.filter(self.true_params)
 
         # Just make sure that no exceptions are thrown during summary
@@ -1780,7 +1778,6 @@ def test_results(self):
         # Make sure that no exceptions are thrown during plot_diagnostics
         if have_matplotlib:
             fig = self.result.plot_diagnostics()
-            plt.close(fig)
 
         # And make sure no expections are thrown calculating any of the
         # covariance matrix types
diff --git a/statsmodels/tsa/statespace/tests/test_structural.py b/statsmodels/tsa/statespace/tests/test_structural.py
--- a/statsmodels/tsa/statespace/tests/test_structural.py
+++ b/statsmodels/tsa/statespace/tests/test_structural.py
@@ -96,7 +96,6 @@ def run_ucm(name):
         # Smoke test for plot_components
         if have_matplotlib:
             fig = res_true.plot_components()
-            plt.close(fig)
 
         # Now fit the model via MLE
         with warnings.catch_warnings(record=True) as w:
@@ -110,11 +109,11 @@ def run_ucm(name):
             res.summary()
 
 
-def test_irregular():
+def test_irregular(close_figures):
     run_ucm('irregular')
 
 
-def test_fixed_intercept():
+def test_fixed_intercept(close_figures):
     # Clear warnings
     structural.__warningregistry__ = {}
 
@@ -125,23 +124,23 @@ def test_fixed_intercept():
         assert_equal(str(w[0].message), message)
 
 
-def test_deterministic_constant():
+def test_deterministic_constant(close_figures):
     run_ucm('deterministic_constant')
 
 
-def test_random_walk():
+def test_random_walk(close_figures):
     run_ucm('random_walk')
 
 
-def test_local_level():
+def test_local_level(close_figures):
     run_ucm('local_level')
 
 
-def test_fixed_slope():
+def test_fixed_slope(close_figures):
     run_ucm('fixed_slope')
 
 
-def test_fixed_slope_warn():
+def test_fixed_slope_warn(close_figures):
     # Clear warnings
     structural.__warningregistry__ = {}
 
@@ -152,51 +151,51 @@ def test_fixed_slope_warn():
         assert_equal(str(w[0].message), message)
 
 
-def test_deterministic_trend():
+def test_deterministic_trend(close_figures):
     run_ucm('deterministic_trend')
 
 
-def test_random_walk_with_drift():
+def test_random_walk_with_drift(close_figures):
     run_ucm('random_walk_with_drift')
 
 
-def test_local_linear_deterministic_trend():
+def test_local_linear_deterministic_trend(close_figures):
     run_ucm('local_linear_deterministic_trend')
 
 
-def test_local_linear_trend():
+def test_local_linear_trend(close_figures):
     run_ucm('local_linear_trend')
 
 
-def test_smooth_trend():
+def test_smooth_trend(close_figures):
     run_ucm('smooth_trend')
 
 
-def test_random_trend():
+def test_random_trend(close_figures):
     run_ucm('random_trend')
 
 
-def test_cycle():
+def test_cycle(close_figures):
     run_ucm('cycle')
 
 
-def test_seasonal():
+def test_seasonal(close_figures):
     run_ucm('seasonal')
 
 
-def test_freq_seasonal():
+def test_freq_seasonal(close_figures):
     run_ucm('freq_seasonal')
 
 
-def test_reg():
+def test_reg(close_figures):
     run_ucm('reg')
 
 
-def test_rtrend_ar1():
+def test_rtrend_ar1(close_figures):
     run_ucm('rtrend_ar1')
 
 
-def test_lltrend_cycle_seasonal_reg_ar1():
+def test_lltrend_cycle_seasonal_reg_ar1(close_figures):
     run_ucm('lltrend_cycle_seasonal_reg_ar1')
 
 
diff --git a/statsmodels/tsa/tests/test_arima.py b/statsmodels/tsa/tests/test_arima.py
--- a/statsmodels/tsa/tests/test_arima.py
+++ b/statsmodels/tsa/tests/test_arima.py
@@ -2057,18 +2057,16 @@ def test_arma_missing():
 
 
 @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-def test_plot_predict():
+def test_plot_predict(close_figures):
     from statsmodels.datasets.sunspots import load_pandas
 
     dta = load_pandas().data[['SUNACTIVITY']]
     dta.index = DatetimeIndex(start='1700', end='2009', freq='A')[:309]
     res = ARMA(dta, (3, 0)).fit(disp=-1)
     fig = res.plot_predict('1990', '2012', dynamic=True, plot_insample=False)
-    plt.close(fig)
 
     res = ARIMA(dta, (3, 1, 0)).fit(disp=-1)
     fig = res.plot_predict('1990', '2012', dynamic=True, plot_insample=False)
-    plt.close(fig)
 
 
 def test_arima_diff2():
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
@@ -155,14 +155,6 @@ def __init__(self):
         self.causality = data['causality']
 
 
-def close_plots():
-    try:
-        import matplotlib.pyplot as plt
-        plt.close('all')
-    except ImportError:
-        pass
-
-
 _orig_stdout = None
 
 
@@ -172,11 +164,6 @@ def setup_module():
     sys.stdout = StringIO()
 
 
-def teardown_module():
-    sys.stdout = _orig_stdout
-    close_plots()
-
-
 class CheckIRF(object):
 
     ref = None; res = None; irf = None
@@ -196,41 +183,28 @@ def _check_irfs(self, py_irfs, r_irfs):
             assert_almost_equal(ref_irfs, res_irfs)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_irf(self):
+    def test_plot_irf(self, close_figures):
         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()
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_cum_effects(self):
+    def test_plot_cum_effects(self, close_figures):
         # 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):
@@ -241,9 +215,8 @@ class CheckFEVD(object):
     # FEVD tests
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_fevd_plot(self):
+    def test_fevd_plot(self, close_figures):
         self.fevd.plot()
-        close_plots()
 
     def test_fevd_repr(self):
         self.fevd
@@ -420,27 +393,23 @@ def test_forecast_interval(self):
         point, lower, upper = self.res.forecast_interval(y, 5)
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_sim(self):
+    def test_plot_sim(self, close_figures):
         self.res.plotsim(steps=100)
-        close_plots()
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot(self):
+    def test_plot(self, close_figures):
         self.res.plot()
-        close_plots()
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_acorr(self):
+    def test_plot_acorr(self, close_figures):
         self.res.plot_acorr()
-        close_plots()
 
     @pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
-    def test_plot_forecast(self):
+    def test_plot_forecast(self, close_figures):
         self.res.plot_forecast(5)
-        close_plots()
 
     def test_reorder(self):
-        #manually reorder
+        # manually reorder
         data = self.data.view((float,3), type=np.ndarray)
         names = self.names
         data2 = np.append(np.append(data[:,2,None], data[:,0,None], axis=1), data[:,1,None], axis=1)
@@ -664,7 +633,7 @@ def setup_class(cls):
         data = np.diff(np.log(data), axis=0) * 400
         cls.res0 = sm.tsa.VAR(data).fit(maxlags=2)
 
-    def test_process(self):
+    def test_process(self, close_figures):
         res0 = self.res0
         k_ar = res0.k_ar
         fc20 = res0.forecast(res0.endog[-k_ar:], 20)
@@ -696,10 +665,8 @@ def test_process(self):
 
         # partially SMOKE test
         if have_matplotlib and MATPLOTLIB_GT_15:
-            fig = res0.plotsim()
-            plt.close(fig)
-            fig = res0.plot_acorr()
-            plt.close(fig)
+            res0.plotsim()
+            res0.plot_acorr()
 
             fig = res0.plot_forecast(20)
             fcp = fig.axes[0].get_children()[1].get_ydata()[-20:]
@@ -709,8 +676,6 @@ def test_process(self):
             assert_allclose(fc20[:, 1], fcp, rtol=1e-13)
             fcp = fig.axes[2].get_children()[1].get_ydata()[-20:]
             assert_allclose(fc20[:, 2], fcp, rtol=1e-13)
-            plt.close(fig)
-            plt.close('all')
 
             fig_asym = irf.plot()
             fig_mc = irf.plot(stderr_type='mc', repl=1000, seed=987128)
@@ -721,9 +686,6 @@ def test_process(self):
                 # use m as desired because it is larger
                 # a is for some irf much smaller than m
                 assert_allclose(a, m, atol=0.1, rtol=0.9)
-            plt.close(fig_asym)
-            plt.close(fig_mc)
-            plt.close('all')
 
     def test_forecast_cov(self):
         # forecast_cov can include parameter uncertainty if contant-only