Skip to content

Commit

Permalink
MAINT: Add decorator for tests that use matplotlib
Browse files Browse the repository at this point in the history
Add decorator for tests requirign matplotlib
Automatically skip if mpl is missing
Add option to skip from the command line
  • Loading branch information
bashtage committed Sep 12, 2018
1 parent 7ffda05 commit 492845b
Show file tree
Hide file tree
Showing 25 changed files with 191 additions and 222 deletions.
16 changes: 16 additions & 0 deletions statsmodels/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import pytest

try:
import matplotlib

matplotlib.use('agg')
HAVE_MATPLOTLIB = True
except ImportError:
HAVE_MATPLOTLIB = False


def pytest_addoption(parser):
parser.addoption("--skip-slow", action="store_true",
Expand All @@ -8,6 +16,8 @@ def pytest_addoption(parser):
help="run only slow tests")
parser.addoption("--skip-examples", action="store_true",
help="skip tests of examples")
parser.addoption("--skip-matplotlib", action="store_true",
help="skip tests that depend on matplotlib")


def pytest_runtest_setup(item):
Expand All @@ -20,6 +30,12 @@ def pytest_runtest_setup(item):
if 'example' in item.keywords and item.config.getoption("--skip-examples"):
pytest.skip("skipping due to --skip-examples")

if 'requires_matplotlib' in item.keywords and item.config.getoption("--skip-matplotlib"):
pytest.skip("skipping due to --skip-matplotlib")

if 'requires_matplotlib' in item.keywords and not HAVE_MATPLOTLIB:
pytest.skip("skipping since matplotlib is not intalled")


def pytest_configure(config):
try:
Expand Down
5 changes: 2 additions & 3 deletions statsmodels/duration/tests/test_survfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@

try:
import matplotlib.pyplot as plt
have_matplotlib = True
except ImportError:
have_matplotlib = False
pass


def close_or_save(pdf, fig):
Expand Down Expand Up @@ -189,7 +188,7 @@ def test_survdiff():
assert_allclose(stat, 13.35259, atol=1e-4, rtol=1e-4)


@pytest.mark.skipif(not have_matplotlib, reason='requires matplotlib')
@pytest.mark.requires_matplotlib
def test_plot_km(close_figures):

if pdf_output:
Expand Down
13 changes: 6 additions & 7 deletions statsmodels/genmod/tests/test_gee.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@
import warnings

try:
import matplotlib.pyplot as plt # makes plt available for test functions
have_matplotlib = True
except:
have_matplotlib = False
import matplotlib.pyplot as plt
except ImportError:
pass

pdf_output = False

Expand Down Expand Up @@ -156,7 +155,7 @@ def test_margins_multinomial(self):
assert_allclose(marg.margeff, np.r_[-0.41197961], rtol=1e-5)
assert_allclose(marg.margeff_se, np.r_[0.1379962], rtol=1e-6)

@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_nominal_plot(self, close_figures):
np.random.seed(34234)
endog = np.r_[0, 0, 0, 0, 1, 1, 1, 1]
Expand Down Expand Up @@ -802,7 +801,7 @@ def test_nominal_independence(self):
model1 = NominalGEE(y, x, groups, cov_struct=nmi)
model1.fit()

@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_ordinal_plot(self, close_figures):
family = Binomial()

Expand Down Expand Up @@ -1555,7 +1554,7 @@ def test_wrapper(self):
check_wrapper(rslt2)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_plots(close_figures):

np.random.seed(378)
Expand Down
15 changes: 8 additions & 7 deletions statsmodels/genmod/tests/test_glm.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@
DECIMAL_0 = 0

try:
import matplotlib.pyplot as plt #makes plt available for test functions
have_matplotlib = True
import matplotlib.pyplot as plt
except:
have_matplotlib = False
pass

pdf_output = False

Expand All @@ -42,14 +41,16 @@
else:
pdf = None


def close_or_save(pdf, fig):
if pdf_output:
pdf.savefig(fig)


def teardown_module():
if have_matplotlib:
if pdf_output:
pdf.close()
if pdf_output:
pdf.close()


class CheckModelResultsMixin(object):
'''
Expand Down Expand Up @@ -900,7 +901,7 @@ def test_formula_missing_exposure():
exposure=exposure, family=family)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_plots(close_figures):

np.random.seed(378)
Expand Down
17 changes: 8 additions & 9 deletions statsmodels/graphics/tests/test_agreement.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@

try:
import matplotlib.pyplot as plt
have_matplotlib = True
except:
have_matplotlib = False
except ImportError:
pass


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_mean_diff_plot(close_figures):

# Seed the random number generator.
Expand Down Expand Up @@ -40,10 +39,10 @@ def test_mean_diff_plot(close_figures):
mean_diff_plot(m1, m2, sd_limit=0)

# Test asethetic controls.
mean_diff_plot(m1, m2, scatter_kwds={'color':'green', 's':10})
mean_diff_plot(m1, m2, scatter_kwds={'color': 'green', 's': 10})

mean_diff_plot(m1, m2, mean_line_kwds={'color':'green', 'lw':5})
mean_diff_plot(m1, m2, mean_line_kwds={'color': 'green', 'lw': 5})

mean_diff_plot(m1, m2, limit_lines_kwds={'color':'green',
'lw':5,
'ls':'dotted'})
mean_diff_plot(m1, m2, limit_lines_kwds={'color': 'green',
'lw': 5,
'ls': 'dotted'})
8 changes: 3 additions & 5 deletions statsmodels/graphics/tests/test_boxplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
from statsmodels.graphics.boxplots import violinplot, beanplot
from statsmodels.datasets import anes96


try:
import matplotlib.pyplot as plt
have_matplotlib = True
except:
have_matplotlib = False
except ImportError:
pass


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_violinplot_beanplot(close_figures):
# Test violinplot and beanplot with the same dataset.
data = anes96.load_pandas()
Expand Down
10 changes: 4 additions & 6 deletions statsmodels/graphics/tests/test_correlation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
from statsmodels.graphics.correlation import plot_corr, plot_corr_grid
from statsmodels.datasets import randhie


try:
import matplotlib.pyplot as plt
have_matplotlib = True
except:
have_matplotlib = False
except ImportError:
pass


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_plot_corr(close_figures):
hie_data = randhie.load_pandas()
corr_matrix = np.corrcoef(hie_data.data.values.T)
Expand All @@ -24,7 +22,7 @@ def test_plot_corr(close_figures):
plot_corr(corr_matrix, normcolor=True, title='', cmap='jet')


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_plot_corr_grid(close_figures):
hie_data = randhie.load_pandas()
corr_matrix = np.corrcoef(hie_data.data.values.T)
Expand Down
6 changes: 3 additions & 3 deletions statsmodels/graphics/tests/test_dotplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
try:
import matplotlib.pyplot as plt
import matplotlib
have_matplotlib = True
except ImportError:
have_matplotlib = False
pass


def close_or_save(pdf, fig):
if pdf_output:
pdf.savefig(fig)

@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')

@pytest.mark.requires_matplotlib
def test_all(close_figures):

if pdf_output:
Expand Down
14 changes: 8 additions & 6 deletions statsmodels/graphics/tests/test_factorplots.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,30 @@
try:
import matplotlib.pyplot as plt
import matplotlib
have_matplotlib = True
except ImportError:
have_matplotlib = False
pass


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
class TestInteractionPlot(object):

@classmethod
def setup_class(cls):
if not have_matplotlib:
pytest.skip('matplotlib not available')
np.random.seed(12345)
cls.weight = np.random.randint(1,4,size=60)
cls.duration = np.random.randint(1,3,size=60)
cls.days = np.log(np.random.randint(1,30, size=60))


@pytest.mark.requires_matplotlib
def test_plot_both(self, close_figures):
fig = interaction_plot(self.weight, self.duration, self.days,
colors=['red','blue'], markers=['D','^'], ms=10)

@pytest.mark.requires_matplotlib
def test_plot_rainbow(self, close_figures):
fig = interaction_plot(self.weight, self.duration, self.days,
markers=['D','^'], ms=10)

@pytest.mark.requires_matplotlib
def test_plot_pandas(self, close_figures):
weight = Series(self.weight, name='Weight')
duration = Series(self.duration, name='Duration')
Expand All @@ -46,6 +44,7 @@ def test_plot_pandas(self, close_figures):
assert_equal(ax.get_ylabel(), 'mean of Days')
assert_equal(ax.get_xlabel(), 'Weight')

@pytest.mark.requires_matplotlib
def test_plot_string_data(self, close_figures):
weight = Series(self.weight, name='Weight').astype('str')
duration = Series(self.duration, name='Duration')
Expand All @@ -58,15 +57,18 @@ def test_plot_string_data(self, close_figures):
assert_equal(ax.get_ylabel(), 'mean of Days')
assert_equal(ax.get_xlabel(), 'Weight')

@pytest.mark.requires_matplotlib
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)

@pytest.mark.requires_matplotlib
def test_formatting_errors(self, close_figures):
assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, markers=['D'])
assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, colors=['b','r','g'])
assert_raises(ValueError, interaction_plot, self.weight, self.duration, self.days, linestyles=['--','-.',':'])

@pytest.mark.requires_matplotlib
def test_plottype(self, close_figures):
fig = interaction_plot(self.weight, self.duration, self.days, plottype='line')
assert_equal(isinstance(fig, plt.Figure), True)
Expand Down
22 changes: 10 additions & 12 deletions statsmodels/graphics/tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@
from statsmodels.graphics.functional import \
hdrboxplot, banddepth, fboxplot, rainbowplot


try:
import matplotlib.pyplot as plt
have_matplotlib = True
except ImportError:
have_matplotlib = False
pass


data = elnino.load(as_pandas=False)
labels = data.raw_data[:, 0].astype(int)
data = data.raw_data[:, 1:]


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_basic(close_figures):
_, hdr = hdrboxplot(data, labels=labels, seed=12345)

Expand Down Expand Up @@ -59,7 +57,7 @@ def test_hdr_basic(close_figures):
assert_equal(labels[hdr.outliers_idx], outliers)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_basic_brute(close_figures):
_, hdr = hdrboxplot(data, labels=labels, use_brute=True)

Expand All @@ -71,7 +69,7 @@ def test_hdr_basic_brute(close_figures):
assert_almost_equal(hdr.median, median_t, decimal=2)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_plot(close_figures):
fig = plt.figure()
ax = fig.add_subplot(111)
Expand All @@ -85,7 +83,7 @@ def test_hdr_plot(close_figures):
ax.set_xlim([-0.2, 11.2])


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_alpha(close_figures):
_, hdr = hdrboxplot(data, alpha=[0.7], seed=12345)
extra_quant_t = np.vstack([[25.1, 26.5, 27.0, 26.4, 25.4, 24.1,
Expand All @@ -95,7 +93,7 @@ def test_hdr_alpha(close_figures):
assert_almost_equal(hdr.extra_quantiles, extra_quant_t, decimal=0)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_multiple_alpha(close_figures):
_, hdr = hdrboxplot(data, alpha=[0.4, 0.92], seed=12345)
extra_quant_t = [[25.712, 27.052, 27.711, 27.200,
Expand All @@ -114,7 +112,7 @@ def test_hdr_multiple_alpha(close_figures):
decimal=0)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_threshold(close_figures):
_, hdr = hdrboxplot(data, alpha=[0.8], threshold=0.93, seed=12345)
labels_pos = np.all(np.in1d(data, hdr.outliers).reshape(data.shape),
Expand All @@ -123,15 +121,15 @@ def test_hdr_threshold(close_figures):
assert_equal([1968, 1982, 1983, 1997, 1998], outliers)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_bw(close_figures):
_, hdr = hdrboxplot(data, bw='cv_ml', seed=12345)
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)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_hdr_ncomp(close_figures):
_, hdr = hdrboxplot(data, ncomp=3, seed=12345)
median_t = [24.33, 25.71, 26.04, 25.08, 23.74, 22.40,
Expand Down Expand Up @@ -174,7 +172,7 @@ def test_banddepth_MBD():
assert_almost_equal(depth, expected_depth, decimal=4)


@pytest.mark.skipif(not have_matplotlib, reason='matplotlib not available')
@pytest.mark.requires_matplotlib
def test_fboxplot_rainbowplot(close_figures):
# Test fboxplot and rainbowplot together, is much faster.
def harmfunc(t):
Expand Down
Loading

0 comments on commit 492845b

Please sign in to comment.