Skip to content

Commit f1b89cb

Browse files
committed
Merge pull request #24 from phobson/better-axes-limits
Better axes limits + New prob plot API
2 parents feac0d4 + 08e0e3b commit f1b89cb

File tree

10 files changed

+140
-116
lines changed

10 files changed

+140
-116
lines changed

.travis.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,22 @@ matrix:
55
- python: 2.7
66
env:
77
- COVERAGE=false
8+
- TESTERS="conda-forge pytest mock pytest-mpl coverage"
89
- ARGS="--verbose"
910
- python: 3.4
1011
env:
1112
- COVERAGE=false
13+
- TESTERS="conda-forge pytest pytest-mpl coverage"
1214
- ARGS="--mpl --verbose"
1315
- python: 3.5
1416
env:
1517
- COVERAGE=false
18+
- TESTERS="conda-forge pytest pytest-mpl coverage"
1619
- ARGS="--mpl --verbose"
1720
- python: 3.5
1821
env:
1922
- COVERAGE=true
23+
- TESTERS="conda-forge pytest pytest-mpl coverage"
2024
- ARGS="--mpl --verbose"
2125

2226
before_install:
@@ -36,8 +40,8 @@ install:
3640

3741
- conda create --yes -n test python=$TRAVIS_PYTHON_VERSION
3842
- source activate test
39-
- conda install --yes --channel=conda-forge numpy matplotlib coverage docopt requests pyyaml
40-
- conda install --yes --channel=conda-forge pytest pytest-cov pytest-mpl
43+
- conda install --yes --channel=conda-forge numpy matplotlib docopt requests pyyaml
44+
- conda install --yes --channel=${TESTERS}
4145
- if [ ${COVERAGE} = true ]; then conda install scipy --yes; fi
4246
- pip install coveralls
4347
- pip install .

conda.recipe/meta.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ test:
3030
- python -c "import sys; import matplotlib as mpl; mpl.use('agg'); import probscale as ps; sys.exit(ps.test('--mpl'))"
3131

3232
requires:
33+
- mock # [py27]
3334
- pytest
3435
- pytest-mpl
3536
- scipy
Loading
Loading
Loading
Loading

probscale/tests/test_validate.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ def test_fit_arguments_invalid(kwarg):
4747
validate.fit_argument('junk', kwarg)
4848

4949

50-
5150
@pytest.mark.parametrize(('value', 'error'), [
5251
('x', None), ('y', None), ('junk', ValueError)
5352
])
@@ -80,3 +79,9 @@ def test_axis_type(value, expected, error):
8079
])
8180
def test_other_options(value, expected):
8281
assert validate.other_options(value) == expected
82+
83+
84+
@pytest.mark.parametrize(('value', 'expected'), [(None, ''), ('test', 'test')])
85+
def test_axis_label(value, expected):
86+
result = validate.axis_label(value)
87+
assert result == expected

probscale/tests/test_viz.py

Lines changed: 62 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
import numpy
1+
import sys
2+
3+
import numpy
24
import matplotlib.pyplot as plt
35

6+
if sys.version_info.major == 2:
7+
import mock
8+
else:
9+
from unittest import mock
410
import pytest
511
import numpy.testing as nptest
612

@@ -13,6 +19,9 @@
1319
from probscale.probscale import _minimal_norm
1420

1521

22+
BASELINE_DIR = 'baseline_images/test_viz'
23+
24+
1625
class Test__fit_line(object):
1726
def setup(self):
1827
self.data = numpy.array([
@@ -367,180 +376,139 @@ def plot_data():
367376
return data
368377

369378

370-
@pytest.mark.mpl_image_compare(
371-
baseline_dir='baseline_images/test_viz',
372-
tolerance=10
373-
)
379+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
374380
def test_probplot_prob(plot_data):
375381
fig, ax = plt.subplots()
376-
fig = viz.probplot(plot_data, ax=ax, xlabel='Test xlabel', datascale='log')
382+
fig = viz.probplot(plot_data, ax=ax, problabel='Test xlabel', datascale='log')
377383
assert isinstance(fig, plt.Figure)
378384
return fig
379385

380386

381-
@pytest.mark.mpl_image_compare(
382-
baseline_dir='baseline_images/test_viz',
383-
tolerance=10
384-
)
387+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
385388
def test_probplot_qq(plot_data):
386389
fig, ax = plt.subplots()
387-
fig = viz.probplot(plot_data, ax=ax, plottype='qq', ylabel='Test label',
390+
fig = viz.probplot(plot_data, ax=ax, plottype='qq', datalabel='Test label',
388391
datascale='log', scatter_kws=dict(color='r'))
389392
return fig
390393

391394

392-
@pytest.mark.mpl_image_compare(
393-
baseline_dir='baseline_images/test_viz',
394-
tolerance=10
395-
)
395+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
396396
def test_probplot_pp(plot_data):
397397
fig, ax = plt.subplots()
398398
scatter_kws = dict(color='b', linestyle='--', markeredgecolor='g', markerfacecolor='none')
399399
fig = viz.probplot(plot_data, ax=ax, plottype='pp', datascale='linear',
400-
xlabel='test x', ylabel='test y', scatter_kws=scatter_kws)
400+
datalabel='test x', problabel='test y',
401+
scatter_kws=scatter_kws)
401402
return fig
402403

403404

404-
@pytest.mark.mpl_image_compare(
405-
baseline_dir='baseline_images/test_viz',
406-
tolerance=10
407-
)
405+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
408406
def test_probplot_prob_bestfit(plot_data):
409407
fig, ax = plt.subplots()
410-
fig = viz.probplot(plot_data, ax=ax, xlabel='Test xlabel', bestfit=True, datascale='log')
408+
fig = viz.probplot(plot_data, ax=ax, datalabel='Test xlabel', bestfit=True, datascale='log')
411409
assert isinstance(fig, plt.Figure)
412410
return fig
413411

414412

415-
@pytest.mark.mpl_image_compare(
416-
baseline_dir='baseline_images/test_viz',
417-
tolerance=10
418-
)
413+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
419414
def test_probplot_qq_bestfit(plot_data):
420415
fig, ax = plt.subplots()
421416
fig = viz.probplot(plot_data, ax=ax, plottype='qq', bestfit=True,
422-
ylabel='Test label', datascale='log')
417+
problabel='Test label', datascale='log')
423418
return fig
424419

425420

426-
@pytest.mark.mpl_image_compare(
427-
baseline_dir='baseline_images/test_viz',
428-
tolerance=10
429-
)
421+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
430422
def test_probplot_pp_bestfit(plot_data):
431423
fig, ax = plt.subplots()
432424
scatter_kws = {'marker': 's', 'color': 'red'}
433425
line_kws = {'linestyle': '--', 'linewidth': 3}
434426
fig = viz.probplot(plot_data, ax=ax, plottype='pp', datascale='linear',
435-
xlabel='test x', bestfit=True, ylabel='test y',
427+
datalabel='test x', bestfit=True, problabel='test y',
436428
scatter_kws=scatter_kws, line_kws=line_kws)
437429
return fig
438430

439431

440-
@pytest.mark.mpl_image_compare(
441-
baseline_dir='baseline_images/test_viz',
442-
tolerance=10
443-
)
432+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
444433
def test_probplot_prob_probax_y(plot_data):
445434
fig, ax = plt.subplots()
446-
fig = viz.probplot(plot_data, ax=ax, xlabel='Test xlabel', datascale='log', probax='y')
435+
fig = viz.probplot(plot_data, ax=ax, datalabel='Test xlabel', datascale='log', probax='y')
447436
assert isinstance(fig, plt.Figure)
448437
return fig
449438

450439

451-
@pytest.mark.mpl_image_compare(
452-
baseline_dir='baseline_images/test_viz',
453-
tolerance=10
454-
)
440+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
455441
def test_probplot_qq_probax_y(plot_data):
456442
fig, ax = plt.subplots()
457-
fig = viz.probplot(plot_data, ax=ax, plottype='qq', ylabel='Test label', probax='y',
443+
fig = viz.probplot(plot_data, ax=ax, plottype='qq', problabel='Test label', probax='y',
458444
datascale='log', scatter_kws=dict(color='r'))
459445
return fig
460446

461447

462-
@pytest.mark.mpl_image_compare(
463-
baseline_dir='baseline_images/test_viz',
464-
tolerance=10
465-
)
448+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
466449
def test_probplot_pp_probax_y(plot_data):
467450
fig, ax = plt.subplots()
468451
scatter_kws = dict(color='b', linestyle='--', markeredgecolor='g', markerfacecolor='none')
469452
fig = viz.probplot(plot_data, ax=ax, plottype='pp', datascale='linear', probax='y',
470-
xlabel='test x', ylabel='test y', scatter_kws=scatter_kws)
453+
datalabel='test x', problabel='test y', scatter_kws=scatter_kws)
471454
return fig
472455

473456

474-
@pytest.mark.mpl_image_compare(
475-
baseline_dir='baseline_images/test_viz',
476-
tolerance=10
477-
)
457+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
478458
def test_probplot_prob_bestfit_probax_y(plot_data):
479459
fig, ax = plt.subplots()
480-
fig = viz.probplot(plot_data, ax=ax, xlabel='Test xlabel', bestfit=True,
460+
fig = viz.probplot(plot_data, ax=ax, datalabel='Test xlabel', bestfit=True,
481461
datascale='log', probax='y')
482462
assert isinstance(fig, plt.Figure)
483463
return fig
484464

485465

486-
@pytest.mark.mpl_image_compare(
487-
baseline_dir='baseline_images/test_viz',
488-
tolerance=10
489-
)
466+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
490467
def test_probplot_qq_bestfit_probax_y(plot_data):
491468
fig, ax = plt.subplots()
492-
fig = viz.probplot(plot_data, ax=ax, plottype='qq', bestfit=True, ylabel='Test label',
469+
fig = viz.probplot(plot_data, ax=ax, plottype='qq', bestfit=True, problabel='Test label',
493470
datascale='log', probax='y')
494471
return fig
495472

496473

497-
@pytest.mark.mpl_image_compare(
498-
baseline_dir='baseline_images/test_viz',
499-
tolerance=10
500-
)
474+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
501475
def test_probplot_pp_bestfit_probax_y(plot_data):
502476
fig, ax = plt.subplots()
503477
scatter_kws = {'marker': 's', 'color': 'red'}
504478
line_kws = {'linestyle': '--', 'linewidth': 3}
505479
fig = viz.probplot(plot_data, ax=ax, plottype='pp', datascale='linear', probax='y',
506-
xlabel='test x', bestfit=True, ylabel='test y',
480+
datalabel='test x', bestfit=True, problabel='test y',
507481
scatter_kws=scatter_kws, line_kws=line_kws)
508482
return fig
509483

510484

511-
@pytest.mark.mpl_image_compare(
512-
baseline_dir='baseline_images/test_viz',
513-
tolerance=15
514-
)
485+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=15)
515486
@pytest.mark.skipif(stats is None, reason="no scipy")
516487
def test_probplot_beta_dist_best_fit_y(plot_data):
517488
fig, (ax1, ax2) = plt.subplots(ncols=2)
518489
dist = stats.beta(3, 3)
519-
fig = viz.probplot(plot_data, dist=dist, ax=ax1, ylabel='Beta scale',
490+
fig = viz.probplot(plot_data, dist=dist, ax=ax1, problabel='Beta scale',
520491
bestfit=True, datascale='log', probax='y')
521492
ax1.set_ylim(bottom=0.5, top=98)
522493

523-
fig = viz.probplot(plot_data, ax=ax2, xlabel='Default (norm)',
494+
fig = viz.probplot(plot_data, ax=ax2, datalabel='Default (norm)',
524495
bestfit=True, datascale='log', probax='y')
525496
ax2.set_ylim(bottom=0.5, top=98)
526497

527498
assert isinstance(fig, plt.Figure)
528499
return fig
529500

530501

531-
@pytest.mark.mpl_image_compare(
532-
baseline_dir='baseline_images/test_viz',
533-
tolerance=10
534-
)
502+
@pytest.mark.mpl_image_compare(baseline_dir=BASELINE_DIR, tolerance=10)
535503
@pytest.mark.skipif(stats is None, reason="no scipy")
536504
def test_probplot_beta_dist_best_fit_x(plot_data):
537505
fig, (ax1, ax2) = plt.subplots(nrows=2)
538506
dist = stats.beta(3, 3)
539-
fig = viz.probplot(plot_data, dist=dist, ax=ax1, xlabel='Beta scale',
507+
fig = viz.probplot(plot_data, dist=dist, ax=ax1, problabel='Beta scale',
540508
bestfit=True, datascale='log', probax='x')
541509
ax1.set_xlim(left=0.5, right=98)
542510

543-
fig = viz.probplot(plot_data, ax=ax2, xlabel='Default (norm)',
511+
fig = viz.probplot(plot_data, ax=ax2, problabel='Default (norm)',
544512
bestfit=True, datascale='log', probax='x')
545513
ax2.set_xlim(left=0.5, right=98)
546514

@@ -550,9 +518,29 @@ def test_probplot_beta_dist_best_fit_x(plot_data):
550518

551519
def test_probplot_test_results(plot_data):
552520
fig, ax = plt.subplots()
553-
fig, results = viz.probplot(plot_data, return_results=True)
521+
fig, results = viz.probplot(plot_data, return_best_fit_results=True)
554522

555523
assert isinstance(results, dict)
556524
known_keys = sorted(['q', 'x', 'y', 'xhat', 'yhat', 'res'])
557525
assert sorted(list(results.keys())) == known_keys
558526
return fig
527+
528+
529+
530+
531+
@pytest.mark.parametrize('probax', ['x', 'y'])
532+
@pytest.mark.parametrize(('N', 'minval', 'maxval'), [
533+
(8, 10, 90),
534+
(37, 1, 99),
535+
(101, 0.1, 99.9),
536+
(10001, 0.001, 99.999)
537+
])
538+
def test__set_prob_limits_x(probax, N, minval, maxval):
539+
from probscale import validate
540+
ax = mock.Mock()
541+
with mock.patch.object(validate, 'axes_object', return_value=[None, ax]):
542+
viz._set_prob_limits(ax, probax, N)
543+
if probax == 'x':
544+
ax.set_xlim.assert_called_once_with(left=minval, right=maxval)
545+
elif probax == 'y':
546+
ax.set_ylim.assert_called_once_with(bottom=minval, top=maxval)

probscale/validate.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ def axes_object(ax):
1818
return fig, ax
1919

2020

21-
def axis_name(axname, argname):
21+
def axis_name(axis, axname):
2222
valid_args = ['x', 'y']
23-
if axname.lower() not in valid_args:
23+
if axis.lower() not in valid_args:
2424
msg = 'Invalid value for {} ({}). Must be on of {}.'
25-
raise ValueError(msg.format(argname, axname, valid_args))
25+
raise ValueError(msg.format(axname, axis, valid_args))
2626

27-
return axname.lower()
27+
return axis.lower()
2828

2929

3030
def fit_argument(arg, argname):
@@ -42,5 +42,12 @@ def axis_type(axtype):
4242
return axtype.lower()
4343

4444

45+
def axis_label(label):
46+
if label is None:
47+
return ''
48+
else:
49+
return label
50+
51+
4552
def other_options(options):
4653
return dict() if options is None else options.copy()

0 commit comments

Comments
 (0)