-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2524 from astrofrog/python-export-tests
Move Python export tests from glue-qt to here
- Loading branch information
Showing
8 changed files
with
660 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from astropy.utils import NumpyRNGContext | ||
|
||
from glue.core import Data, DataCollection | ||
from glue.core.application_base import Application | ||
from glue.viewers.histogram.viewer import SimpleHistogramViewer | ||
from glue.viewers.matplotlib.tests.test_python_export import BaseTestExportPython, random_with_nan | ||
|
||
|
||
class TestExportPython(BaseTestExportPython): | ||
|
||
def setup_method(self, method): | ||
|
||
with NumpyRNGContext(12345): | ||
self.data = Data(**dict((name, random_with_nan(100, nan_index=idx + 1)) for idx, name in enumerate('abcdefgh'))) | ||
self.data_collection = DataCollection([self.data]) | ||
self.app = Application(self.data_collection) | ||
self.viewer = self.app.new_data_viewer(SimpleHistogramViewer) | ||
self.viewer.add_data(self.data) | ||
self.viewer.state.x_att = self.data.id['a'] | ||
|
||
def teardown_method(self, method): | ||
self.viewer = None | ||
self.app = None | ||
|
||
def test_simple(self, tmpdir): | ||
self.assert_same(tmpdir) | ||
|
||
def test_simple_visual(self, tmpdir): | ||
self.viewer.state.layers[0].color = 'blue' | ||
self.viewer.state.layers[0].alpha = 0.5 | ||
self.assert_same(tmpdir) | ||
|
||
def test_simple_visual_legend(self, tmpdir): | ||
self.viewer.state.legend.visible = True | ||
self.viewer.state.layers[0].color = 'blue' | ||
self.viewer.state.layers[0].alpha = 0.5 | ||
self.assert_same(tmpdir) | ||
|
||
def test_cumulative(self, tmpdir): | ||
self.viewer.state.cumulative = True | ||
self.assert_same(tmpdir) | ||
|
||
def test_normalize(self, tmpdir): | ||
self.viewer.state.normalize = True | ||
self.assert_same(tmpdir) | ||
|
||
def test_subset(self, tmpdir): | ||
self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) | ||
self.assert_same(tmpdir) | ||
|
||
def test_subset_legend(self, tmpdir): | ||
self.viewer.state.legend.visible = True | ||
self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) | ||
self.assert_same(tmpdir) | ||
|
||
def test_empty(self, tmpdir): | ||
self.viewer.state.x_min = 10 | ||
self.viewer.state.x_max = 11 | ||
self.viewer.state.hist_x_min = 10 | ||
self.viewer.state.hist_x_max = 11 | ||
self.assert_same(tmpdir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import pytest | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
from astropy.utils import NumpyRNGContext | ||
from astropy.wcs import WCS | ||
|
||
from glue.core import Data, DataCollection | ||
from glue.core.coordinates import AffineCoordinates | ||
from glue.core.application_base import Application | ||
from glue.viewers.image.viewer import SimpleImageViewer | ||
from glue.viewers.matplotlib.tests.test_python_export import BaseTestExportPython | ||
|
||
|
||
class TestExportPython(BaseTestExportPython): | ||
|
||
def setup_method(self, method): | ||
|
||
with NumpyRNGContext(12345): | ||
self.data = Data(cube=np.random.random((30, 50, 20))) | ||
# Create data versions with WCS and affine coordinates | ||
matrix = np.array([[2, 0, 0, -1], [0, 2, 1, 2], [0, 3, 1, -2], [0, 0, 0, 1]]) | ||
affine = AffineCoordinates(matrix, units=['Mm', 'Mm', 'km'], labels=['xw', 'yw', 'zw']) | ||
|
||
self.data_wcs = Data(label='cube', cube=self.data['cube'], coords=WCS(naxis=3)) | ||
self.data_affine = Data(label='cube', cube=self.data['cube'], coords=affine) | ||
self.data_collection = DataCollection([self.data, self.data_wcs, self.data_affine]) | ||
self.app = Application(self.data_collection) | ||
self.viewer = self.app.new_data_viewer(SimpleImageViewer) | ||
self.viewer.add_data(self.data) | ||
# FIXME: On some platforms, using an integer label size | ||
# causes some of the labels to be non-deterministically | ||
# shifted by one pixel, so we pick a non-round font size | ||
# to avoid this. | ||
self.viewer.state.x_ticklabel_size = 8.21334111 | ||
self.viewer.state.y_ticklabel_size = 8.21334111 | ||
|
||
def teardown_method(self, method): | ||
self.viewer = None | ||
self.app = None | ||
|
||
def assert_same(self, tmpdir, tol=0.1): | ||
BaseTestExportPython.assert_same(self, tmpdir, tol=tol) | ||
|
||
def viewer_load(self, coords): | ||
if coords is not None: | ||
self.viewer.add_data(getattr(self, f'data_{coords}')) | ||
self.viewer.remove_data(self.data) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_simple(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_simple_legend(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.viewer.state.show_legend = True | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_simple_att(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.viewer.state.x_att = self.viewer.state.reference_data.pixel_component_ids[1] | ||
self.viewer.state.y_att = self.viewer.state.reference_data.pixel_component_ids[0] | ||
if coords == 'affine': | ||
pytest.xfail('Known issue with axis label rendering') | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_simple_visual(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.viewer.state.legend.visible = True | ||
self.viewer.state.layers[0].cmap = plt.cm.RdBu | ||
self.viewer.state.layers[0].v_min = 0.2 | ||
self.viewer.state.layers[0].v_max = 0.8 | ||
self.viewer.state.layers[0].stretch = 'sqrt' | ||
self.viewer.state.layers[0].stretch = 'sqrt' | ||
self.viewer.state.layers[0].contrast = 0.9 | ||
self.viewer.state.layers[0].bias = 0.6 | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_slice(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.viewer.state.x_att = self.viewer.state.reference_data.pixel_component_ids[1] | ||
self.viewer.state.y_att = self.viewer.state.reference_data.pixel_component_ids[0] | ||
self.viewer.state.slices = (2, 3, 4) | ||
if coords == 'affine': | ||
pytest.xfail('Known issue with axis label rendering') | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_aspect(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.viewer.state.aspect = 'auto' | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_subset(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) | ||
self.assert_same(tmpdir) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_subset_legend(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.data_collection.new_subset_group('mysubset', | ||
self.viewer.state.reference_data.id['cube'] > 0.5) | ||
self.viewer.state.legend.visible = True | ||
self.assert_same(tmpdir, tol=0.15) # transparency and such | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_subset_slice(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) | ||
self.test_slice(tmpdir, coords) | ||
|
||
@pytest.mark.parametrize('coords', [None, 'wcs', 'affine']) | ||
def test_subset_transposed(self, tmpdir, coords): | ||
self.viewer_load(coords) | ||
self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) | ||
self.viewer.state.x_att = self.data.pixel_component_ids[0] | ||
self.viewer.state.y_att = self.data.pixel_component_ids[1] | ||
self.assert_same(tmpdir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import os | ||
import sys | ||
import pytest | ||
import subprocess | ||
|
||
from glue.config import settings | ||
|
||
import numpy as np | ||
|
||
from matplotlib.testing.compare import compare_images | ||
|
||
__all__ = ['random_with_nan', 'BaseTestExportPython'] | ||
|
||
|
||
def random_with_nan(nsamples, nan_index): | ||
x = np.random.random(nsamples) | ||
x[nan_index] = np.nan | ||
return x | ||
|
||
|
||
class BaseTestExportPython: | ||
|
||
def assert_same(self, tmpdir, tol=0.1): | ||
|
||
os.chdir(tmpdir.strpath) | ||
|
||
expected = tmpdir.join('expected.png').strpath | ||
script = tmpdir.join('actual.py').strpath | ||
actual = tmpdir.join('glue_plot.png').strpath | ||
|
||
self.viewer.axes.figure.savefig(expected) | ||
|
||
self.viewer.export_as_script(script) | ||
subprocess.call([sys.executable, script]) | ||
|
||
msg = compare_images(expected, actual, tol=tol) | ||
|
||
if msg: | ||
|
||
from base64 import b64encode | ||
|
||
print("SCRIPT:") | ||
with open(script, 'r') as f: | ||
print(f.read()) | ||
|
||
print("EXPECTED:") | ||
with open(expected, 'rb') as f: | ||
print(b64encode(f.read()).decode()) | ||
|
||
print("ACTUAL:") | ||
with open(actual, 'rb') as f: | ||
print(b64encode(f.read()).decode()) | ||
|
||
pytest.fail(msg, pytrace=False) | ||
|
||
def test_color_settings(self, tmpdir): | ||
settings.FOREGROUND_COLOR = '#a51d2d' | ||
settings.BACKGROUND_COLOR = '#99c1f1' | ||
self.viewer._update_appearance_from_settings() | ||
self.assert_same(tmpdir) | ||
settings.reset_defaults() | ||
self.viewer._update_appearance_from_settings() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from astropy.utils import NumpyRNGContext | ||
|
||
from glue.core import Data, DataCollection | ||
from glue.core.application_base import Application | ||
from glue.viewers.profile.viewer import SimpleProfileViewer | ||
from glue.viewers.matplotlib.tests.test_python_export import BaseTestExportPython, random_with_nan | ||
from glue.viewers.profile.tests.test_state import SimpleCoordinates | ||
|
||
|
||
class TestExportPython(BaseTestExportPython): | ||
|
||
def setup_method(self, method): | ||
|
||
self.data = Data(label='d1') | ||
self.data.coords = SimpleCoordinates() | ||
with NumpyRNGContext(12345): | ||
self.data['x'] = random_with_nan(48, 5).reshape((6, 4, 2)) | ||
self.data['y'] = random_with_nan(48, 12).reshape((6, 4, 2)) | ||
self.data_collection = DataCollection([self.data]) | ||
self.app = Application(self.data_collection) | ||
self.viewer = self.app.new_data_viewer(SimpleProfileViewer) | ||
self.viewer.add_data(self.data) | ||
# Make legend location deterministic | ||
self.viewer.state.legend.location = 'lower left' | ||
|
||
def teardown_method(self, method): | ||
self.viewer = None | ||
self.app = None | ||
|
||
def test_simple(self, tmpdir): | ||
self.assert_same(tmpdir) | ||
|
||
def test_simple_legend(self, tmpdir): | ||
self.viewer.state.legend.visible = True | ||
self.assert_same(tmpdir) | ||
|
||
def test_color(self, tmpdir): | ||
self.viewer.state.layers[0].color = '#ac0567' | ||
self.assert_same(tmpdir) | ||
|
||
def test_linewidth(self, tmpdir): | ||
self.viewer.state.layers[0].linewidth = 7.25 | ||
self.assert_same(tmpdir) | ||
|
||
def test_max(self, tmpdir): | ||
self.viewer.state.function = 'maximum' | ||
self.assert_same(tmpdir) | ||
|
||
def test_min(self, tmpdir): | ||
self.viewer.state.function = 'minimum' | ||
self.assert_same(tmpdir) | ||
|
||
def test_mean(self, tmpdir): | ||
self.viewer.state.function = 'mean' | ||
self.assert_same(tmpdir) | ||
|
||
def test_median(self, tmpdir): | ||
self.viewer.state.function = 'median' | ||
self.assert_same(tmpdir) | ||
|
||
def test_sum(self, tmpdir): | ||
self.viewer.state.function = 'sum' | ||
self.assert_same(tmpdir) | ||
|
||
def test_normalization(self, tmpdir): | ||
self.viewer.state.normalize = True | ||
self.assert_same(tmpdir) | ||
|
||
def test_subset(self, tmpdir): | ||
self.viewer.state.function = 'mean' | ||
self.data_collection.new_subset_group('mysubset', self.data.id['x'] > 0.25) | ||
self.assert_same(tmpdir) | ||
|
||
def test_subset_legend(self, tmpdir): | ||
self.viewer.state.legend.visible = True | ||
self.viewer.state.function = 'mean' | ||
self.viewer.state.layers[0].linewidth = 7.25 | ||
self.data_collection.new_subset_group('mysubset', self.data.id['x'] > 0.25) | ||
self.assert_same(tmpdir) | ||
|
||
def test_xatt(self, tmpdir): | ||
self.viewer.x_att = self.data.pixel_component_ids[1] | ||
self.assert_same(tmpdir) | ||
|
||
def test_profile_att(self, tmpdir): | ||
self.viewer.layers[0].state.attribute = self.data.id['y'] | ||
self.assert_same(tmpdir) |
Oops, something went wrong.