Пример #1
0
    def test_session_cube_back_compat(self, protocol):

        filename = os.path.join(DATA, 'image_cube_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'array'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 1

        assert viewer1.state.x_att_world is dc[0].id['World 2']
        assert viewer1.state.y_att_world is dc[0].id['World 1']
        assert viewer1.state.slices == [2, 0, 0, 1]

        ga.close()
Пример #2
0
def test_load_coordinate_link_helpers_013():

    # This loads a session file made with Glue v0.13. In this session, we have
    # two tables, and we use all the celestial link functions that were present
    # in Glue v0.13. We now check that the paths are patched when loading the
    # session (since the functions have been moved to a deprecated location)

    with open(os.path.join(DATA, 'session_coordinate_links_013.glu'), 'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    data1, data2 = ga.session.data_collection

    print(data1)
    print(data2)

    # Check that the links works
    data1[data2.id['x']]
    data1[data2.id['y']]
    data2[data1.id['x']]
    data2[data1.id['y']]

    ga.close()
Пример #3
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'scatter_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'basic'

        viewer1 = ga.viewers[0][0]
        assert len(viewer1.state.layers) == 3
        assert viewer1.state.x_att is dc[0].id['a']
        assert viewer1.state.y_att is dc[0].id['b']
        assert_allclose(viewer1.state.x_min, -1.04)
        assert_allclose(viewer1.state.x_max, 1.04)
        assert_allclose(viewer1.state.y_min, 1.98)
        assert_allclose(viewer1.state.y_max, 3.02)
        assert not viewer1.state.x_log
        assert not viewer1.state.y_log
        assert viewer1.state.layers[0].visible
        assert viewer1.state.layers[1].visible
        assert viewer1.state.layers[2].visible

        viewer2 = ga.viewers[0][1]
        assert len(viewer2.state.layers) == 3
        assert viewer2.state.x_att is dc[0].id['a']
        assert viewer2.state.y_att is dc[0].id['c']
        assert_allclose(viewer2.state.x_min, 9.5e-6)
        assert_allclose(viewer2.state.x_max, 1.05)
        assert_allclose(viewer2.state.y_min, 0.38)
        assert_allclose(viewer2.state.y_max, 5.25)
        assert viewer2.state.x_log
        assert viewer2.state.y_log
        assert viewer2.state.layers[0].visible
        assert not viewer2.state.layers[1].visible
        assert viewer2.state.layers[2].visible

        viewer3 = ga.viewers[0][2]
        assert len(viewer3.state.layers) == 3
        assert viewer3.state.x_att is dc[0].id['b']
        assert viewer3.state.y_att is dc[0].id['a']
        assert_allclose(viewer3.state.x_min, 0)
        assert_allclose(viewer3.state.x_max, 5)
        assert_allclose(viewer3.state.y_min, -5)
        assert_allclose(viewer3.state.y_max, 5)
        assert not viewer3.state.x_log
        assert not viewer3.state.y_log
        assert viewer3.state.layers[0].visible
        assert viewer3.state.layers[1].visible
        assert not viewer3.state.layers[2].visible

        ga.close()
Пример #4
0
    def test_session_line_back_compat(self):

        # Backward-compatibility for v0.11 files in which the line and scatter
        # plots were defined as separate styles.

        filename = os.path.join(DATA, 'scatter_and_line_v1.glu')

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'table'

        viewer1 = ga.viewers[0][0]
        assert len(viewer1.state.layers) == 1
        assert viewer1.state.x_att is dc[0].id['a']
        assert viewer1.state.y_att is dc[0].id['b']
        assert viewer1.state.layers[0].markers_visible
        assert not viewer1.state.layers[0].line_visible

        viewer1 = ga.viewers[0][1]
        assert len(viewer1.state.layers) == 1
        assert viewer1.state.x_att is dc[0].id['a']
        assert viewer1.state.y_att is dc[0].id['b']
        assert not viewer1.state.layers[0].markers_visible
        assert viewer1.state.layers[0].line_visible

        ga.close()
Пример #5
0
    def restore_session(path):
        """
        Reload a previously-saved session

        Parameters
        ----------
        path : str
            Path to the file to load

        Returns
        -------
        app : :class:`Application`
            The loaded application
        """
        from glue.core.state import GlueUnSerializer

        # In case relative paths are needed in the session file, we do the
        # loading while setting the current directory to the directory
        # in which the session file is so that relative paths are interpreted
        # as relative to the session file.
        start_dir = os.path.abspath('.')
        session_dir = os.path.dirname(path) or '.'
        session_file = os.path.basename(path)

        try:
            os.chdir(session_dir)
            with open(session_file) as infile:
                state = GlueUnSerializer.load(infile)
            return state.object('__main__')
        finally:
            os.chdir(start_dir)
Пример #6
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'dendro_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'data'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 2

        assert viewer1.state.parent_att is dc[0].id['parent']
        assert viewer1.state.height_att is dc[0].id['height']
        assert viewer1.state.order_att is dc[0].id['height']

        layer_state = viewer1.state.layers[0]
        assert layer_state.visible
        assert layer_state.layer is dc[0]

        layer_state = viewer1.state.layers[1]
        assert layer_state.visible
        assert layer_state.layer is dc[0].subsets[0]

        ga.close()
Пример #7
0
def test_load_hdf5_grids_04():

    # This loads a session file made with Glue v0.4. In this session, we have
    # loaded two gridded datasets from an HDF5 datafile: the first one loaded
    # via the auto loader and the other via the FITS/HDF5 loader.

    with open(os.path.join(DATA, 'simple_hdf5_grid.glu'), 'r') as f:
        template = f.read()

    content = template.replace('{DATA_PATH}', (DATA + os.sep).replace('\\', '\\\\'))
    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    dc = ga.session.data_collection

    assert len(dc) == 2

    assert dc[0].label == 'single_grid_auto'
    assert dc[1].label == 'single_grid'

    np.testing.assert_equal(dc[0]['/array1'], 1)
    np.testing.assert_equal(dc[0]['/array1'].shape, (2, 3, 4))

    ga.close()
Пример #8
0
    def test_session_categorical(self, tmpdir):

        def visible_xaxis_labels(ax):
            # Due to a bug in Matplotlib the labels returned outside the field
            # of view may be incorrect: https://github.com/matplotlib/matplotlib/issues/9397
            pos = ax.xaxis.get_ticklocs()
            labels = [tick.get_text() for tick in ax.xaxis.get_ticklabels()]
            xmin, xmax = ax.get_xlim()
            return [labels[i] for i in range(len(pos)) if pos[i] >= xmin and pos[i] <= xmax]

        # Regression test for a bug that caused a restored scatter viewer
        # with a categorical component to not show the categorical labels
        # as tick labels.

        filename = tmpdir.join('test_session_categorical.glu').strpath

        self.viewer.add_data(self.data)
        self.viewer.state.x_att = self.data.id['z']

        assert visible_xaxis_labels(self.viewer.axes) == ['a', 'b', 'c']

        self.session.application.save_session(filename)

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        viewer = ga.viewers[0][0]
        assert viewer.state.x_att is dc[0].id['z']
        assert visible_xaxis_labels(self.viewer.axes) == ['a', 'b', 'c']
Пример #9
0
def test_load_link_helpers_04():

    # This loads a session file made with Glue v0.4. In this session, we have
    # two tables, and we use all the celestial link functions that were present
    # in Glue v0.4. We now check that the paths are patched when loading the
    # session (since the functions have been moved to a deprecated location)

    with open(os.path.join(DATA, 'session_links.glu'), 'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')
Пример #10
0
    def test_datetime64_support(self, tmpdir):

        self.data.add_component(np.array([100, 200, 300, 400], dtype='M8[D]'), 't1')
        self.viewer.add_data(self.data)
        self.viewer.state.x_att = self.data.id['t1']

        wait_for_layers(self.viewer)

        # Matplotlib deals with dates by converting them to the number of days
        # since 01-01-0001, so we can check that the limits are correctly
        # converted (and not 100 to 400)
        assert self.viewer.axes.get_xlim() == (719263.0, 719563.0)

        # Apply an ROI selection in plotting coordinates
        roi = XRangeROI(719313, 719513)
        self.viewer.apply_roi(roi)

        wait_for_layers(self.viewer)

        # Check that the two middle elements are selected
        assert_equal(self.data.subsets[0].to_mask(), [0, 1, 1, 0])

        # Make sure that the Qt labels look ok
        options = self.viewer.options_widget().ui
        assert options.valuetext_x_min.text() == '1970-04-11'
        assert options.valuetext_x_max.text() == '1971-02-05'

        # Make sure that we can set the xmin/xmax to a string date
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-11', 'D'))
        options.valuetext_x_min.setText('1970-04-14')
        options.valuetext_x_min.editingFinished.emit()
        assert self.viewer.axes.get_xlim() == (719266.0, 719563.0)
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        # Make sure that everything works fine after saving/reloading
        filename = tmpdir.join('test_datetime64.glu').strpath
        self.session.application.save_session(filename)
        with open(filename, 'r') as f:
            session = f.read()
        state = GlueUnSerializer.loads(session)
        ga = state.object('__main__')
        viewer = ga.viewers[0][0]
        options = viewer.options_widget().ui

        wait_for_layers(viewer)

        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        assert options.valuetext_x_min.text() == '1970-04-14'
        assert options.valuetext_x_max.text() == '1971-02-05'
Пример #11
0
def test_load_pixel_components_07():

    # This loads a session file made with Glue v0.7. In 0.7 and before,
    # PixelComponentID did not exist, so we need to make sure that when loading
    # in such files, we transform the appropriate ComponentIDs to
    # PixelComponentIDs.

    with open(os.path.join(DATA, 'glue_v0.7_pixel_roi_selection.glu'), 'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    assert isinstance(ga.data_collection[0].pixel_component_ids[0], PixelComponentID)
    assert isinstance(ga.data_collection[0].pixel_component_ids[1], PixelComponentID)
Пример #12
0
def test_load_viewers_04():

    # FIXME - for some reason this test with PySide2 causes a leftover reference
    # to GlueApplication and appears to be due to x_log being True in the
    # scatter plot. I suspect maybe there is some kind of circular reference

    # This loads a session file made with Glue v0.4. In this session, we have
    # three viewers: one scatter viewer, one image viewer, and one histogram
    # viewer.

    with open(os.path.join(DATA, 'simple_viewers.glu'), 'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    assert len(ga.viewers[0]) == 3
    labels = sorted([x.LABEL for x in ga.viewers[0]])

    assert labels == ['1D Histogram', '2D Image', '2D Scatter']

    viewers = {}
    for x in ga.viewers[0]:
        viewers[x.LABEL] = x

    h = viewers['1D Histogram']
    assert h.viewer_size == (1235, 531)
    assert h.position == (0, 535)
    assert h.state.x_att.label == 'b'

    i = viewers['2D Image']
    assert i.viewer_size == (562, 513)
    assert i.position == (672, 0)
    assert i.state.layers[0].attribute.label == "image"

    s = viewers['2D Scatter']
    assert s.viewer_size == (670, 512)
    assert s.position == (0, 0)
    assert s.state.x_att.label == 'b'
    assert s.state.y_att.label == 'a'
    assert s.state.x_log
    assert not s.state.y_log

    ga.close()
Пример #13
0
def test_load_log(protocol):

    # Prior to Glue v0.13, components were added to the data as: first
    # non-coordinate component, then coordinate components, then remaining non-
    # coordinate components. In Glue v0.13, this changed to be coordinate
    # components then non-coordinate components. The LoadLog functionality
    # relies on an absolute component index, so we need to be careful - if the
    # session file was created prior to Glue v0.13, we need to load the
    # components in the log using the old order. The load_log_1.glu file was
    # made with Glue v0.12.2, while the load_log_2.glu file was made with
    # Glue v0.13.

    with open(os.path.join(DATA, 'load_log_{0}.glu'.format(protocol)), 'r') as f:
        template = f.read()

    content = template.replace('{DATA_PATH}', (DATA + os.sep).replace('\\', '\\\\'))
    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    dc = ga.session.data_collection

    assert len(dc) == 1

    data = dc[0]

    assert data.label == 'simple'

    np.testing.assert_equal(data['Pixel Axis 0 [x]'], [0, 1, 2])
    np.testing.assert_equal(data['World 0'], [0, 1, 2])
    np.testing.assert_equal(data['a'], [1, 3, 5])
    np.testing.assert_equal(data['b'], [2, 2, 3])

    if protocol == 0:
        assert data.components == [data.id['a'], data.id['Pixel Axis 0 [x]'], data.id['World 0'], data.id['b']]
    else:
        assert data.components == [data.id['Pixel Axis 0 [x]'], data.id['World 0'], data.id['a'], data.id['b']]

    assert type(data.get_component('Pixel Axis 0 [x]')) == CoordinateComponent
    assert type(data.get_component('World 0')) == CoordinateComponent
    assert type(data.get_component('a')) == Component
    assert type(data.get_component('b')) == Component

    ga.close()
Пример #14
0
    def restore_session(path):
        """
        Reload a previously-saved session

        Parameters
        ----------
        path : str
            Path to the file to load

        Returns
        -------
        app : :class:`Application`
            The loaded application
        """
        from glue.core.state import GlueUnSerializer

        with open(path) as infile:
            state = GlueUnSerializer.load(infile)

        return state.object('__main__')
Пример #15
0
def test_load_viewers_04():

    # This loads a session file made with Glue v0.4. In this session, we have
    # three viewers: one scatter viewer, one image viewer, and one histogram
    # viewer.

    with open(os.path.join(DATA, 'simple_viewers.glu'), 'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    assert len(ga.viewers[0]) == 3
    labels = sorted([x.LABEL for x in ga.viewers[0]])

    assert labels == ['1D Histogram', '2D Image Viewer', '2D Scatter Plot']

    viewers = {}
    for x in ga.viewers[0]:
        viewers[x.LABEL] = x

    h = viewers['1D Histogram']
    assert h.viewer_size == (1235, 531)
    assert h.position == (0, 535)
    assert h.component.label == 'b'

    i = viewers['2D Image Viewer']
    assert i.viewer_size == (562, 513)
    assert i.position == (672, 0)
    assert i.attribute.label == "image"

    s = viewers['2D Scatter Plot']
    assert s.viewer_size == (670, 512)
    assert s.position == (0, 0)
    assert s.xatt.label == 'b'
    assert s.yatt.label == 'a'
    assert s.xlog
    assert not s.ylog
    assert not s.xflip
    assert s.yflip
Пример #16
0
def test_load_simple_tables_04():

    # This loads a session file made with Glue v0.4. In this session, we have
    # loaded four tables. The first two are from the same file, but one loaded
    # via the auto loader and the other via the Astropy FITS table loader. The
    # second two were loaded similarly to the first two, but the file contains
    # two HDUs this time. However, in Glue v0.4, only the first HDU was read so
    # we shouldn't have access to columns c and d in ``double_tables.fits``.

    with open(os.path.join(DATA, 'simple_tables.glu'), 'r') as f:
        template = f.read()

    content = template.replace('{DATA_PATH}',
                               (DATA + os.sep).replace('\\', '\\\\'))
    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    dc = ga.session.data_collection

    # All tables should actually be the same because the FITS reader back at
    # 0.4 only read in the first HDU so the new reader is back-compatible
    # since it preserves HDU order.

    assert len(dc) == 4

    assert dc[0].label == 'single_table_auto'
    assert dc[1].label == 'single_table'
    assert dc[2].label == 'double_tables_auto'
    assert dc[3].label == 'double_tables'

    np.testing.assert_equal(dc[0]['a'], [1, 2, 3])
    np.testing.assert_equal(dc[0]['b'], [4, 5, 6])
    np.testing.assert_equal(dc[0]['a'], dc[1]['a'])
    np.testing.assert_equal(dc[0]['b'], dc[1]['b'])
    np.testing.assert_equal(dc[0]['a'], dc[2]['a'])
    np.testing.assert_equal(dc[0]['b'], dc[2]['b'])
    np.testing.assert_equal(dc[0]['a'], dc[3]['a'])
    np.testing.assert_equal(dc[0]['b'], dc[3]['b'])

    ga.close()
Пример #17
0
def test_load_viewers_04():

    # This loads a session file made with Glue v0.4. In this session, we have
    # three viewers: one scatter viewer, one image viewer, and one histogram
    # viewer.

    with open(os.path.join(DATA, 'simple_viewers.glu'), 'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    assert len(ga.viewers[0]) == 3
    labels = sorted([x.LABEL for x in ga.viewers[0]])

    assert labels == ['1D Histogram', '2D Image Viewer', '2D Scatter Plot']

    viewers = {}
    for x in ga.viewers[0]:
        viewers[x.LABEL] = x

    h = viewers['1D Histogram']
    assert h.viewer_size == (1235, 531)
    assert h.position == (0, 535)
    assert h.component.label == 'b'

    i = viewers['2D Image Viewer']
    assert i.viewer_size == (562, 513)
    assert i.position == (672, 0)
    assert i.attribute.label == "image"

    s = viewers['2D Scatter Plot']
    assert s.viewer_size == (670, 512)
    assert s.position == (0, 0)
    assert s.xatt.label == 'b'
    assert s.yatt.label == 'a'
    assert s.xlog
    assert not s.ylog
    assert not s.xflip
    assert s.yflip
Пример #18
0
    def test_session_categorical(self, tmpdir):
        def visible_xaxis_labels(ax):
            # Due to a bug in Matplotlib the labels returned outside the field
            # of view may be incorrect: https://github.com/matplotlib/matplotlib/issues/9397
            pos = ax.xaxis.get_ticklocs()
            labels = [tick.get_text() for tick in ax.xaxis.get_ticklabels()]
            xmin, xmax = ax.get_xlim()
            return [
                labels[i] for i in range(len(pos))
                if pos[i] >= xmin and pos[i] <= xmax
            ]

        # Regression test for a bug that caused a restored scatter viewer
        # with a categorical component to not show the categorical labels
        # as tick labels.

        filename = tmpdir.join('test_session_categorical.glu').strpath

        self.viewer.add_data(self.data)
        self.viewer.state.x_att = self.data.id['z']

        process_events()

        assert visible_xaxis_labels(self.viewer.axes) == ['a', 'b', 'c']

        self.session.application.save_session(filename)

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        viewer = ga.viewers[0][0]
        assert viewer.state.x_att is dc[0].id['z']
        assert visible_xaxis_labels(self.viewer.axes) == ['a', 'b', 'c']

        ga.close()
Пример #19
0
def test_load_pixel_components_07():

    # This loads a session file made with Glue v0.7. In 0.7 and before,
    # PixelComponentID did not exist, so we need to make sure that when loading
    # in such files, we transform the appropriate ComponentIDs to
    # PixelComponentIDs.

    with open(os.path.join(DATA, 'glue_v0.7_pixel_roi_selection.glu'),
              'r') as f:
        content = f.read()

    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    assert isinstance(ga.data_collection[0].pixel_component_ids[0],
                      PixelComponentID)
    assert isinstance(ga.data_collection[0].pixel_component_ids[1],
                      PixelComponentID)

    ga.close()
Пример #20
0
def test_load_simple_tables_04():

    # This loads a session file made with Glue v0.4. In this session, we have
    # loaded four tables. The first two are from the same file, but one loaded
    # via the auto loader and the other via the Astropy FITS table loader. The
    # second two were loaded similarly to the first two, but the file contains
    # two HDUs this time. However, in Glue v0.4, only the first HDU was read so
    # we shouldn't have access to columns c and d in ``double_tables.fits``.

    with open(os.path.join(DATA, 'simple_tables.glu'), 'r') as f:
        template = f.read()

    content = template.replace('{DATA_PATH}', (DATA + os.sep).replace('\\', '\\\\'))
    state = GlueUnSerializer.loads(content)

    ga = state.object('__main__')

    dc = ga.session.data_collection

    # All tables should actually be the same because the FITS reader back at
    # 0.4 only read in the first HDU so the new reader is back-compatible
    # since it preserves HDU order.

    assert len(dc) == 4

    assert dc[0].label == 'single_table_auto'
    assert dc[1].label == 'single_table'
    assert dc[2].label == 'double_tables_auto'
    assert dc[3].label == 'double_tables'

    np.testing.assert_equal(dc[0]['a'], [1, 2, 3])
    np.testing.assert_equal(dc[0]['b'], [4, 5, 6])
    np.testing.assert_equal(dc[0]['a'], dc[1]['a'])
    np.testing.assert_equal(dc[0]['b'], dc[1]['b'])
    np.testing.assert_equal(dc[0]['a'], dc[2]['a'])
    np.testing.assert_equal(dc[0]['b'], dc[2]['b'])
    np.testing.assert_equal(dc[0]['a'], dc[3]['a'])
    np.testing.assert_equal(dc[0]['b'], dc[3]['b'])

    ga.close()
Пример #21
0
def test_table_widget_010():

    from glue.viewers.table.qt.tests.test_data_viewer import check_values_and_color

    # This loads a session file made with Glue v0.10 that includes a table
    # viewer. This is to make sure that loading table viewers from old files
    # will always be backward-compatible.

    with open(os.path.join(DATA, 'glue_v0.10_table.glu'), 'r') as f:
        state = GlueUnSerializer.load(f)

    ga = state.object('__main__')

    viewer = ga.viewers[0][0]

    data = {'x': [1, 2, 3], 'y': [4, 5, 6]}

    colors = ['#e31a1c', '#6d7326', None]

    check_values_and_color(viewer.model, data, colors)

    ga.close()
Пример #22
0
    def test_session_rgb_back_compat(self, protocol):

        filename = os.path.join(DATA, 'image_rgb_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'rgbcube'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 3
        assert viewer1.state.color_mode == 'One color per layer'

        layer_state = viewer1.state.layers[0]
        assert layer_state.visible
        assert layer_state.attribute.label == 'a'
        assert layer_state.color == 'r'

        layer_state = viewer1.state.layers[1]
        assert not layer_state.visible
        assert layer_state.attribute.label == 'c'
        assert layer_state.color == 'g'

        layer_state = viewer1.state.layers[2]
        assert layer_state.visible
        assert layer_state.attribute.label == 'b'
        assert layer_state.color == 'b'

        ga.close()
Пример #23
0
    def test_session_rgb_back_compat(self, protocol):

        filename = os.path.join(DATA, 'image_rgb_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'rgbcube'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 3
        assert viewer1.state.color_mode == 'One color per layer'

        layer_state = viewer1.state.layers[0]
        assert layer_state.visible
        assert layer_state.attribute.label == 'a'
        assert layer_state.color == 'r'

        layer_state = viewer1.state.layers[1]
        assert not layer_state.visible
        assert layer_state.attribute.label == 'c'
        assert layer_state.color == 'g'

        layer_state = viewer1.state.layers[2]
        assert layer_state.visible
        assert layer_state.attribute.label == 'b'
        assert layer_state.color == 'b'

        ga.close()
Пример #24
0
def test_table_widget_010():

    from glue.viewers.table.qt.tests.test_data_viewer import check_values_and_color

    # This loads a session file made with Glue v0.10 that includes a table
    # viewer. This is to make sure that loading table viewers from old files
    # will always be backward-compatible.

    with open(os.path.join(DATA, 'glue_v0.10_table.glu'), 'r') as f:
        state = GlueUnSerializer.load(f)

    ga = state.object('__main__')

    viewer = ga.viewers[0][0]

    data = {'x': [1, 2, 3],
            'y': [4, 5, 6]}

    colors = ['#e31a1c', '#6d7326', None]

    check_values_and_color(viewer.model, data, colors)

    ga.close()
Пример #25
0
    def test_session_cube_back_compat(self, protocol):

        filename = os.path.join(DATA, 'image_cube_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'array'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 1

        assert viewer1.state.x_att_world is dc[0].id['World 2']
        assert viewer1.state.y_att_world is dc[0].id['World 1']
        assert viewer1.state.slices == [2, 0, 0, 1]
Пример #26
0
    def test_datetime64_support(self, tmpdir):

        self.data.add_component(np.array([100, 200, 300, 400], dtype='M8[D]'),
                                't1')
        self.data.add_component(np.array([200, 300, 400, 500], dtype='M8[D]'),
                                't2')
        self.viewer.add_data(self.data)
        self.viewer.state.x_att = self.data.id['t1']
        self.viewer.state.y_att = self.data.id['y']

        # Matplotlib deals with dates by converting them to the number of days
        # since 01-01-0001, so we can check that the limits are correctly
        # converted (and not 100 to 400)
        assert self.viewer.axes.get_xlim() == (719248.0, 719578.0)
        assert self.viewer.axes.get_ylim() == (3.2 - 0.015, 3.5 + 0.015)

        # Apply an ROI selection in plotting coordinates
        roi = RectangularROI(xmin=719313, xmax=719513, ymin=3, ymax=4)
        self.viewer.apply_roi(roi)

        # Check that the two middle elements are selected
        assert_equal(self.data.subsets[0].to_mask(), [0, 1, 1, 0])

        # Now do the same with the y axis
        self.viewer.state.y_att = self.data.id['t2']

        assert self.viewer.axes.get_xlim() == (719248.0, 719578.0)
        assert self.viewer.axes.get_ylim() == (719348.0, 719678.0)

        # Apply an ROI selection in plotting coordinates
        edit = self.session.edit_subset_mode
        edit.edit_subset = []
        roi = CircularROI(xc=719463, yc=719563, radius=200)
        self.viewer.apply_roi(roi)
        assert_equal(self.data.subsets[1].to_mask(), [0, 1, 1, 1])

        # Make sure that the Qt labels look ok
        self.viewer.state.y_att = self.data.id['y']
        options = self.viewer.options_widget().ui
        assert options.valuetext_x_min.text() == '1970-03-27'
        assert options.valuetext_x_max.text() == '1971-02-20'
        assert options.valuetext_y_min.text() == '3.185'
        assert options.valuetext_y_max.text() == '3.515'

        # Make sure that we can set the xmin/xmax to a string date
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-03-27', 'D'))
        options.valuetext_x_min.setText('1970-04-14')
        options.valuetext_x_min.editingFinished.emit()
        assert self.viewer.axes.get_xlim() == (719266.0, 719578.0)
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        # Make sure that everything works fine after saving/reloading
        filename = tmpdir.join('test_datetime64.glu').strpath
        self.session.application.save_session(filename)
        with open(filename, 'r') as f:
            session = f.read()
        state = GlueUnSerializer.loads(session)
        ga = state.object('__main__')
        viewer = ga.viewers[0][0]
        options = viewer.options_widget().ui

        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        assert options.valuetext_x_min.text() == '1970-04-14'
        assert options.valuetext_x_max.text() == '1971-02-20'
        assert options.valuetext_y_min.text() == '3.185'
        assert options.valuetext_y_max.text() == '3.515'
Пример #27
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'image_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 2

        assert dc[0].label == 'data1'
        assert dc[1].label == 'data2'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 3

        assert viewer1.state.x_att_world is dc[0].id['World 1']
        assert viewer1.state.y_att_world is dc[0].id['World 0']

        assert viewer1.state.x_min < -0.5
        assert viewer1.state.x_max > 1.5
        assert viewer1.state.y_min <= -0.5
        assert viewer1.state.y_max >= 1.5

        layer_state = viewer1.state.layers[0]
        assert isinstance(layer_state, ImageLayerState)
        assert layer_state.visible
        assert layer_state.bias == 0.5
        assert layer_state.contrast == 1.0
        assert layer_state.stretch == 'sqrt'
        assert layer_state.percentile == 99

        layer_state = viewer1.state.layers[1]
        assert isinstance(layer_state, ScatterLayerState)
        assert layer_state.visible

        layer_state = viewer1.state.layers[2]
        assert isinstance(layer_state, ImageSubsetLayerState)
        assert not layer_state.visible

        viewer2 = ga.viewers[0][1]

        assert len(viewer2.state.layers) == 2

        assert viewer2.state.x_att_world is dc[0].id['World 1']
        assert viewer2.state.y_att_world is dc[0].id['World 0']

        assert viewer2.state.x_min < -0.5
        assert viewer2.state.x_max > 1.5
        assert viewer2.state.y_min <= -0.5
        assert viewer2.state.y_max >= 1.5

        layer_state = viewer2.state.layers[0]
        assert layer_state.visible
        assert layer_state.stretch == 'arcsinh'
        assert layer_state.v_min == 1
        assert layer_state.v_max == 4

        layer_state = viewer2.state.layers[1]
        assert layer_state.visible

        viewer3 = ga.viewers[0][2]

        assert len(viewer3.state.layers) == 2

        assert viewer3.state.x_att_world is dc[0].id['World 1']
        assert viewer3.state.y_att_world is dc[0].id['World 0']

        assert viewer3.state.x_min < -0.5
        assert viewer3.state.x_max > 1.5
        assert viewer3.state.y_min <= -0.5
        assert viewer3.state.y_max >= 1.5

        layer_state = viewer3.state.layers[0]
        assert layer_state.visible
        assert layer_state.stretch == 'linear'
        assert layer_state.v_min == -2
        assert layer_state.v_max == 2

        layer_state = viewer3.state.layers[1]
        assert layer_state.visible

        ga.close()
Пример #28
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'profile_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'array'

        viewer1 = ga.viewers[0][0]
        assert len(viewer1.state.layers) == 3
        assert viewer1.state.x_att_pixel is dc[0].pixel_component_ids[0]
        assert_allclose(viewer1.state.x_min, -0.5)
        assert_allclose(viewer1.state.x_max, 2.5)
        assert_allclose(viewer1.state.y_min, 13)
        assert_allclose(viewer1.state.y_max, 63)
        assert viewer1.state.function == 'maximum'
        assert not viewer1.state.normalize
        assert viewer1.state.layers[0].visible
        assert viewer1.state.layers[1].visible
        assert viewer1.state.layers[2].visible

        viewer2 = ga.viewers[0][1]
        assert viewer2.state.x_att_pixel is dc[0].pixel_component_ids[1]
        assert_allclose(viewer2.state.x_min, -0.5)
        assert_allclose(viewer2.state.x_max, 3.5)
        assert_allclose(viewer2.state.y_min, -0.1)
        assert_allclose(viewer2.state.y_max, 1.1)
        assert viewer2.state.function == 'maximum'
        assert viewer2.state.normalize
        assert viewer2.state.layers[0].visible
        assert not viewer2.state.layers[1].visible
        assert viewer2.state.layers[2].visible

        viewer3 = ga.viewers[0][2]
        assert viewer3.state.x_att_pixel is dc[0].pixel_component_ids[2]
        assert_allclose(viewer3.state.x_min, -0.5)
        assert_allclose(viewer3.state.x_max, 4.5)
        assert_allclose(viewer3.state.y_min, -0.4)
        assert_allclose(viewer3.state.y_max, 4.4)
        assert viewer3.state.function == 'minimum'
        assert not viewer3.state.normalize
        assert viewer3.state.layers[0].visible
        assert viewer3.state.layers[1].visible
        assert not viewer3.state.layers[2].visible

        viewer4 = ga.viewers[0][3]
        assert viewer4.state.x_att_pixel is dc[0].pixel_component_ids[2]
        assert_allclose(viewer4.state.x_min, -5.5)
        assert_allclose(viewer4.state.x_max, 9.5)
        assert_allclose(viewer4.state.y_min, 27.1)
        assert_allclose(viewer4.state.y_max, 31.9)
        assert viewer4.state.function == 'mean'
        assert not viewer4.state.normalize
        assert viewer4.state.layers[0].visible
        assert not viewer4.state.layers[1].visible
        assert not viewer4.state.layers[2].visible

        ga.close()
Пример #29
0
def test_scatter_volume(protocol):

    filename = os.path.join(DATA, 'scatter_volume_v{0}.glu'.format(protocol))

    with open(filename, 'r') as f:
        session = f.read()

    with patch.object(QMessageBox, 'question') as question:
        question.return_value = QMessageBox.Yes
        state = GlueUnSerializer.loads(session)
        ga = state.object('__main__')

    dc = ga.session.data_collection

    assert len(dc) == 2

    assert dc[0].label == 'table'
    assert dc[1].label == 'array'

    # SCATTER VIEWER

    scatter = ga.viewers[0][0]

    viewer_state = scatter.state

    assert viewer_state.x_att.label == 'b'
    assert viewer_state.x_min == 8
    assert viewer_state.x_max == 0
    np.testing.assert_allclose(viewer_state.x_stretch, 0.4, rtol=1.e-3)

    assert viewer_state.y_att.label == 'a'
    assert viewer_state.y_min == 0.4
    assert viewer_state.y_max == 4
    np.testing.assert_allclose(viewer_state.y_stretch, 0.6, rtol=1.e-3)

    assert viewer_state.z_att.label == 'c'
    assert viewer_state.z_min == 2
    assert viewer_state.z_max == 5.4
    np.testing.assert_allclose(viewer_state.z_stretch, 1.4, rtol=1.e-3)

    assert viewer_state.perspective_view
    assert not viewer_state.visible_axes
    if protocol >= 1:
        assert not viewer_state.native_aspect
        assert viewer_state.clip_data

    layer_state = viewer_state.layers[0]

    assert layer_state.size_mode == 'Linear'
    assert layer_state.size_attribute.label == 'e'
    assert layer_state.size_vmin == 3
    assert layer_state.size_vmax == 4
    np.testing.assert_allclose(layer_state.size_scaling, 1.51356, rtol=1.e-3)

    assert layer_state.color_mode == 'Linear'
    assert layer_state.cmap_attribute.label == 'd'
    assert layer_state.cmap_vmin == 0
    assert layer_state.cmap_vmax == 10
    assert layer_state.alpha == 0.66

    # VOLUME VIEWER

    volume = ga.viewers[0][1]

    viewer_state = volume.state

    assert viewer_state.x_att.label == 'Pixel Axis 2 [x]'
    assert viewer_state.x_min == 3.5
    assert viewer_state.x_max == -0.5
    np.testing.assert_allclose(viewer_state.x_stretch, 0.2, rtol=1.e-3)

    assert viewer_state.y_att.label == 'Pixel Axis 1 [y]'
    assert viewer_state.y_min == -0.5
    assert viewer_state.y_max == 2.5
    np.testing.assert_allclose(viewer_state.y_stretch, 1.2, rtol=1.e-3)

    assert viewer_state.z_att.label == 'Pixel Axis 0 [z]'
    assert viewer_state.z_min == -0.5
    assert viewer_state.z_max == 1.5
    np.testing.assert_allclose(viewer_state.z_stretch, 1.3, rtol=1.e-3)

    assert not viewer_state.perspective_view
    assert viewer_state.visible_axes
    if protocol >= 1:
        assert viewer_state.native_aspect
        assert not viewer_state.clip_data

    layer_state = viewer_state.layers[0]

    assert layer_state.attribute == 'array'
    assert layer_state.vmin == 0
    assert layer_state.vmax == 23
    assert layer_state.color == '#e60010'
    assert layer_state.alpha == 0.36

    ga.close()
Пример #30
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'histogram_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'data'

        viewer1 = ga.viewers[0][0]
        assert len(viewer1.state.layers) == 2
        assert viewer1.state.x_att is dc[0].id['a']
        assert_allclose(viewer1.state.x_min, 0)
        assert_allclose(viewer1.state.x_max, 9)
        assert_allclose(viewer1.state.y_min, 0)
        assert_allclose(viewer1.state.y_max, 2.4)
        assert_allclose(viewer1.state.hist_x_min, 0)
        assert_allclose(viewer1.state.hist_x_max, 9)
        assert_allclose(viewer1.state.hist_n_bin, 6)
        assert not viewer1.state.x_log
        assert not viewer1.state.y_log
        assert viewer1.state.layers[0].visible
        assert not viewer1.state.layers[1].visible
        assert not viewer1.state.cumulative
        assert not viewer1.state.normalize

        viewer2 = ga.viewers[0][1]
        assert viewer2.state.x_att is dc[0].id['b']
        assert_allclose(viewer2.state.x_min, 2)
        assert_allclose(viewer2.state.x_max, 16)
        assert_allclose(viewer2.state.y_min, 0)
        assert_allclose(viewer2.state.y_max, 1.2)
        assert_allclose(viewer2.state.hist_x_min, 2)
        assert_allclose(viewer2.state.hist_x_max, 16)
        assert_allclose(viewer2.state.hist_n_bin, 8)
        assert not viewer2.state.x_log
        assert not viewer2.state.y_log
        assert viewer2.state.layers[0].visible
        assert viewer2.state.layers[1].visible
        assert not viewer2.state.cumulative
        assert not viewer2.state.normalize

        viewer3 = ga.viewers[0][2]
        assert viewer3.state.x_att is dc[0].id['a']
        assert_allclose(viewer3.state.x_min, 0)
        assert_allclose(viewer3.state.x_max, 9)
        assert_allclose(viewer3.state.y_min, 0.01111111111111111)
        assert_allclose(viewer3.state.y_max, 0.7407407407407407)
        assert_allclose(viewer3.state.hist_x_min, 0)
        assert_allclose(viewer3.state.hist_x_max, 9)
        assert_allclose(viewer3.state.hist_n_bin, 10)
        assert not viewer3.state.x_log
        assert viewer3.state.y_log
        assert viewer3.state.layers[0].visible
        assert viewer3.state.layers[1].visible
        assert not viewer3.state.cumulative
        assert viewer3.state.normalize

        viewer4 = ga.viewers[0][3]
        assert viewer4.state.x_att is dc[0].id['a']
        assert_allclose(viewer4.state.x_min, -1)
        assert_allclose(viewer4.state.x_max, 10)
        assert_allclose(viewer4.state.y_min, 0)
        assert_allclose(viewer4.state.y_max, 12)
        assert_allclose(viewer4.state.hist_x_min, -1)
        assert_allclose(viewer4.state.hist_x_max, 10)
        assert_allclose(viewer4.state.hist_n_bin, 4)
        assert not viewer4.state.x_log
        assert not viewer4.state.y_log
        assert viewer4.state.layers[0].visible
        assert viewer4.state.layers[1].visible
        assert viewer4.state.cumulative
        assert not viewer4.state.normalize
Пример #31
0
    def test_datetime64_support(self, tmpdir):

        self.data.add_component(np.array([100, 200, 300, 400], dtype='M8[D]'), 't1')
        self.data.add_component(np.array([200, 300, 400, 500], dtype='M8[D]'), 't2')
        self.viewer.add_data(self.data)
        self.viewer.state.x_att = self.data.id['t1']
        self.viewer.state.y_att = self.data.id['y']

        # Matplotlib deals with dates by converting them to the number of days
        # since 01-01-0001, so we can check that the limits are correctly
        # converted (and not 100 to 400)
        assert self.viewer.axes.get_xlim() == (719251.0, 719575.0)
        assert self.viewer.axes.get_ylim() == (3.2 - 0.012, 3.5 + 0.012)

        # Apply an ROI selection in plotting coordinates
        roi = RectangularROI(xmin=719313, xmax=719513, ymin=3, ymax=4)
        self.viewer.apply_roi(roi)

        # Check that the two middle elements are selected
        assert_equal(self.data.subsets[0].to_mask(), [0, 1, 1, 0])

        # Now do the same with the y axis
        self.viewer.state.y_att = self.data.id['t2']

        assert self.viewer.axes.get_xlim() == (719251.0, 719575.0)
        assert self.viewer.axes.get_ylim() == (719351.0, 719675.0)

        # Apply an ROI selection in plotting coordinates
        edit = self.session.edit_subset_mode
        edit.edit_subset = []
        roi = CircularROI(xc=719463, yc=719563, radius=200)
        self.viewer.apply_roi(roi)
        assert_equal(self.data.subsets[1].to_mask(), [0, 1, 1, 1])

        # Make sure that the Qt labels look ok
        self.viewer.state.y_att = self.data.id['y']
        options = self.viewer.options_widget().ui
        assert options.valuetext_x_min.text() == '1970-03-30'
        assert options.valuetext_x_max.text() == '1971-02-17'
        assert options.valuetext_y_min.text() == '3.188'
        assert options.valuetext_y_max.text() == '3.512'

        # Make sure that we can set the xmin/xmax to a string date
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-03-30', 'D'))
        options.valuetext_x_min.setText('1970-04-14')
        options.valuetext_x_min.editingFinished.emit()
        assert self.viewer.axes.get_xlim() == (719266.0, 719575.0)
        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        # Make sure that everything works fine after saving/reloading
        filename = tmpdir.join('test_datetime64.glu').strpath
        self.session.application.save_session(filename)
        with open(filename, 'r') as f:
            session = f.read()
        state = GlueUnSerializer.loads(session)
        ga = state.object('__main__')
        viewer = ga.viewers[0][0]
        options = viewer.options_widget().ui

        assert_equal(self.viewer.state.x_min, np.datetime64('1970-04-14', 'D'))

        assert options.valuetext_x_min.text() == '1970-04-14'
        assert options.valuetext_x_max.text() == '1971-02-17'
        assert options.valuetext_y_min.text() == '3.188'
        assert options.valuetext_y_max.text() == '3.512'

        ga.close()
Пример #32
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'image_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 2

        assert dc[0].label == 'data1'
        assert dc[1].label == 'data2'

        viewer1 = ga.viewers[0][0]

        assert len(viewer1.state.layers) == 3

        assert viewer1.state.x_att_world is dc[0].id['World 1']
        assert viewer1.state.y_att_world is dc[0].id['World 0']

        assert viewer1.state.x_min < -0.5
        assert viewer1.state.x_max > 1.5
        assert viewer1.state.y_min <= -0.5
        assert viewer1.state.y_max >= 1.5

        layer_state = viewer1.state.layers[0]
        assert isinstance(layer_state, ImageLayerState)
        assert layer_state.visible
        assert layer_state.bias == 0.5
        assert layer_state.contrast == 1.0
        assert layer_state.stretch == 'sqrt'
        assert layer_state.percentile == 99

        layer_state = viewer1.state.layers[1]
        assert isinstance(layer_state, ScatterLayerState)
        assert layer_state.visible

        layer_state = viewer1.state.layers[2]
        assert isinstance(layer_state, ImageSubsetLayerState)
        assert not layer_state.visible

        viewer2 = ga.viewers[0][1]

        assert len(viewer2.state.layers) == 2

        assert viewer2.state.x_att_world is dc[0].id['World 1']
        assert viewer2.state.y_att_world is dc[0].id['World 0']

        assert viewer2.state.x_min < -0.5
        assert viewer2.state.x_max > 1.5
        assert viewer2.state.y_min <= -0.5
        assert viewer2.state.y_max >= 1.5

        layer_state = viewer2.state.layers[0]
        assert layer_state.visible
        assert layer_state.stretch == 'arcsinh'
        assert layer_state.v_min == 1
        assert layer_state.v_max == 4

        layer_state = viewer2.state.layers[1]
        assert layer_state.visible

        viewer3 = ga.viewers[0][2]

        assert len(viewer3.state.layers) == 2

        assert viewer3.state.x_att_world is dc[0].id['World 1']
        assert viewer3.state.y_att_world is dc[0].id['World 0']

        assert viewer3.state.x_min < -0.5
        assert viewer3.state.x_max > 1.5
        assert viewer3.state.y_min <= -0.5
        assert viewer3.state.y_max >= 1.5

        layer_state = viewer3.state.layers[0]
        assert layer_state.visible
        assert layer_state.stretch == 'linear'
        assert layer_state.v_min == -2
        assert layer_state.v_max == 2

        layer_state = viewer3.state.layers[1]
        assert layer_state.visible

        ga.close()
Пример #33
0
def roundtrip_transform(transform):
    gs = GlueSerializer(transform)
    out_str = gs.dumps()
    obj = GlueUnSerializer.loads(out_str)
    return obj.object('__main__')
Пример #34
0
    def test_session_back_compat(self, protocol):

        filename = os.path.join(DATA, 'histogram_v{0}.glu'.format(protocol))

        with open(filename, 'r') as f:
            session = f.read()

        state = GlueUnSerializer.loads(session)

        ga = state.object('__main__')

        dc = ga.session.data_collection

        assert len(dc) == 1

        assert dc[0].label == 'data'

        viewer1 = ga.viewers[0][0]
        assert len(viewer1.state.layers) == 2
        assert viewer1.state.x_att is dc[0].id['a']
        assert_allclose(viewer1.state.x_min, 0)
        assert_allclose(viewer1.state.x_max, 9)
        assert_allclose(viewer1.state.y_min, 0)
        assert_allclose(viewer1.state.y_max, 2.4)
        assert_allclose(viewer1.state.hist_x_min, 0)
        assert_allclose(viewer1.state.hist_x_max, 9)
        assert_allclose(viewer1.state.hist_n_bin, 6)
        assert not viewer1.state.x_log
        assert not viewer1.state.y_log
        assert viewer1.state.layers[0].visible
        assert not viewer1.state.layers[1].visible
        assert not viewer1.state.cumulative
        assert not viewer1.state.normalize

        viewer2 = ga.viewers[0][1]
        assert viewer2.state.x_att is dc[0].id['b']
        assert_allclose(viewer2.state.x_min, 2)
        assert_allclose(viewer2.state.x_max, 16)
        assert_allclose(viewer2.state.y_min, 0)
        assert_allclose(viewer2.state.y_max, 1.2)
        assert_allclose(viewer2.state.hist_x_min, 2)
        assert_allclose(viewer2.state.hist_x_max, 16)
        assert_allclose(viewer2.state.hist_n_bin, 8)
        assert not viewer2.state.x_log
        assert not viewer2.state.y_log
        assert viewer2.state.layers[0].visible
        assert viewer2.state.layers[1].visible
        assert not viewer2.state.cumulative
        assert not viewer2.state.normalize

        viewer3 = ga.viewers[0][2]
        assert viewer3.state.x_att is dc[0].id['a']
        assert_allclose(viewer3.state.x_min, 0)
        assert_allclose(viewer3.state.x_max, 9)
        assert_allclose(viewer3.state.y_min, 0.037037037037037035)
        assert_allclose(viewer3.state.y_max, 0.7407407407407407)
        assert_allclose(viewer3.state.hist_x_min, 0)
        assert_allclose(viewer3.state.hist_x_max, 9)
        assert_allclose(viewer3.state.hist_n_bin, 10)
        assert not viewer3.state.x_log
        assert viewer3.state.y_log
        assert viewer3.state.layers[0].visible
        assert viewer3.state.layers[1].visible
        assert not viewer3.state.cumulative
        assert viewer3.state.normalize

        viewer4 = ga.viewers[0][3]
        assert viewer4.state.x_att is dc[0].id['a']
        assert_allclose(viewer4.state.x_min, -1)
        assert_allclose(viewer4.state.x_max, 10)
        assert_allclose(viewer4.state.y_min, 0)
        assert_allclose(viewer4.state.y_max, 12)
        assert_allclose(viewer4.state.hist_x_min, -1)
        assert_allclose(viewer4.state.hist_x_max, 10)
        assert_allclose(viewer4.state.hist_n_bin, 4)
        assert not viewer4.state.x_log
        assert not viewer4.state.y_log
        assert viewer4.state.layers[0].visible
        assert viewer4.state.layers[1].visible
        assert viewer4.state.cumulative
        assert not viewer4.state.normalize