def setup_method(self, method): self.data = Data(x=[1, 2, 3, 2, 2, 3, 1]) figure = MagicMock() self.collect = DataCollection() self.client = HistogramClient(self.collect, figure) self.axes = self.client.axes self.hub = self.collect.hub self.connect()
def setup_method(self, method): self.data = Data(x=[0, 0, 0, 1, 2, 3, 3, 10, 20], y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0
def load_data_files(datafiles): """Load data files and return a DataCollection""" from glue.core.data_collection import DataCollection from glue.core.data_factories import auto_data, load_data dc = DataCollection() for df in datafiles: dc.append(load_data(df, auto_data)) return dc
def setup_method(self, method): self.data = Data(y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.data.add_component( CategoricalComponent(['a', 'a', 'a', 'b', 'c', 'd', 'd', 'e', 'f']), 'x') self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0
def test_links(self): d1 = Data(label='x', x=[1, 2, 3]) d2 = Data(label='y', y=[3, 4, 8]) dc = DataCollection([d1, d2]) link = ComponentLink([d1.id['x']], d2.id['y'], doubler) dc.add_link(link) np.testing.assert_array_equal(d1['y'], [2, 4, 6]) app = GlueApplication(dc) self.check_clone(app)
def test_subset_groups_remain_synced_after_restore(self): # regrssion test for 352 d = Data(label='hist', x=[[1, 2], [2, 3]]) dc = DataCollection([d]) dc.new_subset_group() app = GlueApplication(dc) app2 = clone(app) sg = app2.data_collection.subset_groups[0] assert sg.style.parent is sg sg.style.color = '#112233' assert sg.subsets[0].style.color == '#112233'
def test_histogram(self): d = Data(label='hist', x=[[1, 2], [2, 3]]) dc = DataCollection([d]) app = GlueApplication(dc) w = app.new_data_viewer(HistogramViewer, data=d) self.check_clone(app) dc.new_subset_group() assert len(w.layers) == 2 self.check_clone(app) w.nbins = 7 self.check_clone(app)
def test_histogram(self): d = Data(label='hist', x=[[1, 2], [2, 3]]) dc = DataCollection([d]) app = GlueApplication(dc) w = app.new_data_viewer(HistogramWidget, data=d) self.check_clone(app) dc.new_subset_group() assert len(w.layers) == 2 self.check_clone(app) w.nbins = 7 self.check_clone(app)
def test_numerical_values_changed(self): # Here we slice two of the dimensions and then compare the results to a # manually sliced dataset. derived = IndexedData(self.data, (None, 2, None, 4, None)) data_collection = DataCollection([self.data, derived]) class CustomListener(HubListener): def __init__(self, hub): self.received = 0 hub.subscribe(self, NumericalDataChangedMessage, handler=self.receive_message) def receive_message(self, message): self.received += 1 listener = CustomListener(data_collection.hub) assert listener.received == 0 derived.indices = (None, 3, None, 5, None) assert listener.received == 1 derived.indices = (None, 3, None, 5, None) assert listener.received == 1
def test_scatter_viewer(self): d = Data(label='x', x=[1, 2, 3, 4, 5], y=[2, 3, 4, 5, 6]) dc = DataCollection([d]) app = GlueApplication(dc) w = app.new_data_viewer(ScatterViewer, data=d) self.check_clone(app) s1 = dc.new_subset_group() s2 = dc.new_subset_group() assert len(w.layers) == 3 l1, l2, l3 = w.layers l1.zorder, l2.zorder = l2.zorder, l1.zorder l3.visible = False assert l3.visible is False copy = self.check_clone(app) assert copy.viewers[0][0].layers[-1].visible is False
def test_scatter_viewer(self): d = Data(label='x', x=[1, 2, 3, 4, 5], y=[2, 3, 4, 5, 6]) dc = DataCollection([d]) app = GlueApplication(dc) w = app.new_data_viewer(ScatterWidget, data=d) self.check_clone(app) s1 = dc.new_subset_group() s2 = dc.new_subset_group() assert len(w.layers) == 3 l1, l2, l3 = w.layers l1.zorder, l2.zorder = l2.zorder, l1.zorder l3.visible = False assert l3.visible is False copy = self.check_clone(app) assert copy.viewers[0][0].layers[-1].visible is False
def setup_method(self, method): self.data = Data(y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.data.add_component(CategoricalComponent(['a', 'a', 'a', 'b', 'c', 'd', 'd', 'e', 'f']), 'x') self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0
def test_histogram(self): d = Data(label='hist', x=[[1, 2], [2, 3]]) dc = DataCollection([d]) app = GlueApplication(dc) w = app.new_data_viewer(HistogramViewer, data=d) copy1 = self.check_clone(app) dc.new_subset_group() assert len(w.layers) == 2 copy2 = self.check_clone(app) w.nbins = 7 copy3 = self.check_clone(app) app.close() copy1.close() copy2.close() copy3.close()
def test_multi_tab(self): d = Data(label='hist', x=[[1, 2], [2, 3]]) dc = DataCollection([d]) app = GlueApplication(dc) w1 = app.new_data_viewer(HistogramWidget, data=d) app.new_tab() w2 = app.new_data_viewer(HistogramWidget, data=d) assert app.viewers == ((w1, ), (w2, )) self.check_clone(app)
def __init__(self, application=None, data_collection=None, command_stack=None, hub=None): self.application = application self.data_collection = data_collection or DataCollection() self.hub = self.data_collection.hub self.command_stack = command_stack or CommandStack() self.command_stack.session = self self.edit_subset_mode = EditSubsetMode() self.edit_subset_mode.data_collection = self.data_collection
def setup_method(self, method): self.data = example_data.test_data() self.ids = [ self.data[0].find_component_id('a'), self.data[0].find_component_id('b'), self.data[1].find_component_id('c'), self.data[1].find_component_id('d') ] self.roi_limits = (0.5, 0.5, 1.5, 1.5) self.roi_points = (np.array([1]), np.array([1])) self.collect = DataCollection() EditSubsetMode().data_collection = self.collect self.hub = self.collect.hub FIGURE.clf() axes = FIGURE.add_subplot(111) self.client = ScatterClient(self.collect, axes=axes) self.connect()
def main(): app = QApplication(sys.argv) win = QMainWindow() data = example_data.simple_image() dc = DataCollection([data]) histo_client = HistogramWidget(dc) hub = Hub(dc, histo_client) win.setCentralWidget(histo_client) win.show() sys.exit(app.exec_())
def __init__(self, application=None, data_collection=None, command_stack=None, hub=None): # applications can be added after instantiation self.application = application self.data_collection = data_collection or DataCollection() self.hub = self.data_collection.hub self.command_stack = command_stack or CommandStack() self.command_stack.session = self # set the global data_collection for subset updates from glue.core.edit_subset_mode import EditSubsetMode EditSubsetMode().data_collection = self.data_collection
def main(): from glue.core.data import Data from glue.core.data_collection import DataCollection import numpy as np x = np.random.random((5, 5)) y = x * 3 data = DataCollection(Data(label='test', x=x, y=y)) CustomComponentWidget.create_component(data) for d in data: print(d.label) for c in d.components: print('\t%s' % c)
def __init__(self, data_collection=None, session=None): if session is not None: self._session = session session.application = self self._data = session.data_collection else: self._data = data_collection or DataCollection() self._session = Session(data_collection=self._data, application=self) self._hub = self._session.hub self._cmds = self._session.command_stack self._cmds.add_callback(self._update_undo_redo_enabled) self._settings = {} for key, value, validator in settings: self._settings[key] = [value, validator]
def setup_method(self, method): self.data = example_data.test_data() self.ids = [self.data[0].find_component_id('a'), self.data[0].find_component_id('b'), self.data[1].find_component_id('c'), self.data[1].find_component_id('d')] self.roi_limits = (0.5, 0.5, 1.5, 1.5) self.roi_points = (np.array([1]), np.array([1])) self.collect = DataCollection() EditSubsetMode().data_collection = self.collect self.hub = self.collect.hub FIGURE.clf() axes = FIGURE.add_subplot(111) self.client = ScatterClient(self.collect, axes=axes) self.connect()
def setup_method(self, method): self.data = example_data.test_categorical_data() self.ids = [ self.data[0].find_component_id('x1'), self.data[0].find_component_id('y1'), self.data[1].find_component_id('x2'), self.data[1].find_component_id('y2') ] self.roi_limits = (0.5, 0.5, 4, 4) self.roi_points = (np.array([1]), np.array([3])) self.collect = DataCollection() self.hub = self.collect.hub FIGURE.clf() axes = FIGURE.add_subplot(111) self.client = ScatterClient(self.collect, axes=axes) self.connect()
def test_deselect_tool_on_viewer_change(self): d = Data(label='hist', x=[[1, 2], [2, 3]]) dc = DataCollection([d]) app = GlueApplication(dc) v1 = app.new_data_viewer(HistogramViewer, data=d) v2 = app.new_data_viewer(HistogramViewer, data=d) assert v1.toolbar.active_tool is None assert v2.toolbar.active_tool is None v2.toolbar.active_tool = 'select:xrange' assert v1.toolbar.active_tool is None assert v2.toolbar.active_tool.tool_id == 'select:xrange' app.current_tab.activateNextSubWindow() assert v1.toolbar.active_tool is None assert v2.toolbar.active_tool is None v1.toolbar.active_tool = 'select:xrange' # Emit a signal without changing the active subWindow to make sure that # the tool doesn't get reset. app.current_tab.subWindowActivated.emit( app.current_tab.activeSubWindow()) assert v1.toolbar.active_tool.tool_id == 'select:xrange' assert v2.toolbar.active_tool is None app.current_tab.activateNextSubWindow() assert v1.toolbar.active_tool is None assert v2.toolbar.active_tool is None app.close()
class TestHistogramClient(object): def setup_method(self, method): self.data = Data(x=[0, 0, 0, 1, 2, 3, 3, 10, 20], y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0 def draw_count(self): return self.axes.figure.canvas.draw.call_count def layer_drawn(self, layer): return layer in self.client._artists and \ all(a.visible for a in self.client._artists[layer]) and \ all(len(a.artists) > 0 for a in self.client._artists[layer]) def layer_present(self, layer): return layer in self.client._artists def assert_autoscaled(self): yra = self.client.axes.get_ylim() datara = [99999, -99999] for a in self.client._artists: if a.y.size > 0: datara[0] = min(datara[0], a.y.min()) datara[1] = max(datara[1], a.y.max()) assert yra[0] <= datara[0] assert yra[1] >= datara[1] def test_empty_on_creation(self): assert self.data not in self.client._artists def test_add_layer(self): self.client.add_layer(self.data) assert self.layer_present(self.data) assert not self.layer_drawn(self.data) self.client.set_component(self.data.components[0]) assert self.layer_drawn(self.data) def test_add_invalid_layer_raises(self): self.collect.remove(self.data) with pytest.raises(IncompatibleDataException): self.client.add_layer(self.data) def test_add_subset_auto_adds_data(self): subset = self.data.new_subset() self.client.add_layer(subset) assert self.layer_present(self.data) assert self.layer_present(subset) self.client.set_component(self.data.components[0]) assert self.layer_drawn(self.data) def test_double_add_ignored(self): self.client.add_layer(self.data) art = self.client._artists[self.data] self.client.add_layer(self.data) assert self.client._artists[self.data] == art def test_add_data_auto_adds_subsets(self): s = self.data.new_subset() self.client.add_layer(self.data) assert self.layer_present(s) def test_data_removal(self): self.client.add_layer(self.data) self.client.remove_layer(self.data) assert not (self.layer_present(self.data)) def test_data_removal_removes_subsets(self): self.client.add_layer(self.data) self.client.remove_layer(self.data) self.data.new_subset() assert len(self.data.subsets) > 0 for subset in self.data.subsets: assert not (self.layer_present(subset)) def test_layer_updates_on_data_add(self): self.client.add_layer(self.data) for s in self.data.subsets: assert s in self.client._artists def test_set_component_updates_component(self): self.client.add_layer(self.data) comp = self.data.find_component_id('uniform') self.client.set_component(comp) assert self.client._component is comp def test_set_component_redraws(self): self.client.add_layer(self.data) comp = self.data.id['x'] comp2 = self.data.id['y'] self.client.set_component(comp) ct0 = self.draw_count() self.client.set_component(comp2) assert self.draw_count() > ct0 def test_remove_not_present_ignored(self): self.client.remove_layer(self.data) def test_set_visible_external_data(self): self.client.set_layer_visible(None, False) def test_get_visible_external_data(self): assert not (self.client.is_layer_visible(None)) def test_set_visible(self): self.client.add_layer(self.data) self.client.set_layer_visible(self.data, False) assert not (self.client.is_layer_visible(self.data)) def test_draw_histogram_one_layer(self): self.client.add_layer(self.data) self.client.set_component(self.data.find_component_id('uniform')) def test_draw_histogram_subset_hidden(self): self.client.add_layer(self.data) s = self.data.new_subset() self.client.set_layer_visible(s, False) self.client.set_component(self.data.find_component_id('uniform')) def test_draw_histogram_two_layers(self): self.client.add_layer(self.data) self.client.set_component(self.data.find_component_id('uniform')) def test_update_property_set_triggers_redraw(self): self.client.add_layer(self.data) ct = self.draw_count() self.client.normed ^= True assert self.draw_count() > ct @pytest.mark.parametrize(('prop'), ['normed', 'cumulative']) def test_set_boolean_property(self, prop): """Boolean properties should sync with artists""" self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) setattr(self.client, prop, False) for a in self.client._artists: assert not getattr(a, prop) setattr(self.client, prop, True) for a in self.client._artists: assert getattr(a, prop) def test_set_nbins(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.nbins = 100 for a in self.client._artists[self.data]: assert a.nbins == 100 assert a.x.size == 100 + 1 def test_autoscale(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.axes.set_ylim(0, .1) self.client.autoscale = False self.client.autoscale = True self.assert_autoscaled() def test_xlimits(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.xlimits = -12, 20 assert self.client.xlimits == (-12, 20) for a in self.client._artists[self.data]: assert a.lo == -12 assert a.hi == 20 def test_set_xlimits_out_of_data_range(self): """Setting xlimits outside of range shouldn't crash""" self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.xlimits = 100, 200 self.client.xlimits = -200, -100 def test_component_property(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) assert self.client.component is self.data.components[0] def test_apply_roi(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['y']) # bins are -7...-1 self.data.edit_subset = [self.data.subsets[0]] roi = PolygonalROI(vx=[-5.1, -4.5, -3.2], vy=[2, 3, 4]) self.client.apply_roi(roi) state = self.data.subsets[0].subset_state assert isinstance(state, RangeSubsetState) # range should expand to nearest bin edge assert state.lo == -6 assert state.hi == -3 def test_apply_roi_xlog(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.data.edit_subset = [self.data.subsets[0]] self.client.xlog = True roi = PolygonalROI(vx=[1, 2, 3], vy=[2, 3, 4]) self.client.apply_roi(roi) state = self.data.subsets[0].subset_state assert isinstance(state, RangeSubsetState) np.testing.assert_allclose(state.lo, 7.3680629972807736) np.testing.assert_allclose(state.hi, 1000) def test_xlimits_sticky_with_component(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.xlimits = 5, 6 self.client.set_component(self.data.components[1]) self.client.xlimits = 7, 8 self.client.set_component(self.data.components[0]) assert self.client.xlimits == (5, 6) self.client.set_component(self.data.components[1]) assert self.client.xlimits == (7, 8) def test_default_xlimits(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) assert self.client.xlimits == (0, 20) self.client.set_component(self.data.id['y']) assert self.client.xlimits == (-7, -1) def test_xlimit_single_set(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlimits = (None, 5) assert self.client.xlimits == (0, 5) self.client.xlimits = (3, None) assert self.client.xlimits == (3, 5) def test_xlimit_reverse_set(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlimits = 5, 3 assert self.client.xlimits == (3, 5) def test_xlog_axes_labels(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlog = True assert self.client.axes.get_xlabel() == 'Log x' self.client.xlog = False assert self.client.axes.get_xlabel() == 'x' self.client.ylog = True assert self.client.axes.get_ylabel() == 'N' self.client.ylog = False assert self.client.axes.get_ylabel() == 'N' def test_xlog_snaps_limits(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.axes.set_xlim((-1, 1)) self.client.xlog = True assert self.client.axes.get_xlim() != (-1, 1) def test_artist_clear_resets_arrays(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) for a in self.client._artists[self.data]: assert a.get_data()[0].size > 0 a.clear() assert a.get_data()[0].size == 0 def test_component_replaced(self): # regression test for 508 self.client.register_to_hub(self.collect.hub) self.client.add_layer(self.data) self.client.component = self.data.components[0] test = ComponentID('test') self.data.update_id(self.client.component, test) assert self.client.component is test def test_update_when_limits_unchanged(self): # Regression test for glue-viz/glue#1010 - this bug caused histograms # to not be recomputed if the attribute changed but the limits and # number of bins did not. self.client.add_layer(self.data) self.client.set_component(self.data.id['y']) self.client.xlimits = -20, 20 self.client.nbins = 12 y1 = self.client._artists[0]._y self.client.set_component(self.data.id['x']) self.client.xlimits = -20, 20 self.client.nbins = 12 y2 = self.client._artists[0]._y assert not np.allclose(y1, y2) self.client.set_component(self.data.id['y']) y3 = self.client._artists[0]._y np.testing.assert_allclose(y1, y3)
class TestScatterClient(object): def setup_method(self, method): self.data = example_data.test_data() self.ids = [ self.data[0].find_component_id('a'), self.data[0].find_component_id('b'), self.data[1].find_component_id('c'), self.data[1].find_component_id('d') ] self.roi_limits = (0.5, 0.5, 1.5, 1.5) self.roi_points = (np.array([1]), np.array([1])) self.collect = DataCollection() EditSubsetMode().data_collection = self.collect self.hub = self.collect.hub FIGURE.clf() axes = FIGURE.add_subplot(111) self.client = ScatterClient(self.collect, axes=axes) self.connect() def teardown_method(self, methdod): self.assert_properties_correct() self.assert_axes_ticks_correct() def assert_properties_correct(self): ax = self.client.axes cl = self.client xlim = ax.get_xlim() ylim = ax.get_ylim() assert abs(cl.xmin - min(xlim)) < 1e-2 assert abs(cl.xmax - max(xlim)) < 1e-2 assert abs(cl.ymin - min(ylim)) < 1e-2 assert abs(cl.ymax - max(ylim)) < 1e-2 assert cl.xflip == (xlim[1] < xlim[0]) assert cl.yflip == (ylim[1] < ylim[0]) assert cl.xlog == (ax.get_xscale() == 'log') assert cl.ylog == (ax.get_yscale() == 'log') assert (self.client.xatt is None) or isinstance( self.client.xatt, ComponentID) assert (self.client.yatt is None) or isinstance( self.client.yatt, ComponentID) def check_ticks(self, axis, is_log, is_cat): locator = axis.get_major_locator() formatter = axis.get_major_formatter() if is_log: assert isinstance(locator, LogLocator) assert isinstance(formatter, LogFormatterMathtext) elif is_cat: assert isinstance(locator, MaxNLocator) assert isinstance(formatter, FuncFormatter) else: assert isinstance(locator, AutoLocator) assert isinstance(formatter, ScalarFormatter) def assert_axes_ticks_correct(self): ax = self.client.axes client = self.client if client.xatt is not None: self.check_ticks(ax.xaxis, client.xlog, client._check_categorical(client.xatt)) if client.yatt is not None: self.check_ticks(ax.yaxis, client.ylog, client._check_categorical(client.yatt)) def plot_data(self, layer): """ Return the data bounds for a given layer (data or subset) Output format: [xmin, xmax], [ymin, ymax] """ client = self.client x, y = client.artists[layer][0].get_data() xmin = x.min() xmax = x.max() ymin = y.min() ymax = y.max() return [xmin, xmax], [ymin, ymax] def plot_limits(self): """ Return the plot limits Output format [xmin, xmax], [ymin, ymax] """ ax = self.client.axes xlim = ax.get_xlim() ylim = ax.get_ylim() return (min(xlim), max(xlim)), (min(ylim), max(ylim)) def assert_layer_inside_limits(self, layer): """Assert that points of a layer are within plot limits """ xydata = self.plot_data(layer) xylimits = self.plot_limits() assert xydata[0][0] >= xylimits[0][0] assert xydata[1][0] >= xylimits[1][0] assert xydata[0][1] <= xylimits[0][1] assert xydata[1][1] <= xylimits[1][1] def setup_2d_data(self): d = Data(x=[[1, 2], [3, 4]], y=[[2, 4], [6, 8]]) self.collect.append(d) self.client.add_layer(d) self.client.xatt = d.id['x'] self.client.yatt = d.id['y'] return d def add_data(self, data=None): if data is None: data = self.data[0] data.edit_subset = data.new_subset() self.collect.append(data) self.client.add_data(data) return data def add_data_and_attributes(self): data = self.add_data() data.edit_subset = data.new_subset() self.client.xatt = self.ids[0] self.client.yatt = self.ids[1] return data def is_first_in_front(self, front, back): z1 = self.client.get_layer_order(front) z2 = self.client.get_layer_order(back) return z1 > z2 def connect(self): self.client.register_to_hub(self.hub) self.collect.register_to_hub(self.hub) def layer_drawn(self, layer): return self.client.is_layer_present(layer) and \ all(a.enabled and a.visible for a in self.client.artists[layer]) def layer_data_correct(self, layer, x, y): xx, yy = self.client.artists[layer][0].get_data() if max(abs(xx - x)) > .01: return False if max(abs(yy - y)) > .01: return False return True def test_empty_on_creation(self): for d in self.data: assert not self.client.is_layer_present(d) def test_add_external_data_raises_exception(self): data = Data() with pytest.raises(TypeError) as exc: self.client.add_data(data) assert exc.value.args[0] == "Layer not in data collection" def test_valid_add(self): self.add_data() assert self.client.is_layer_present(self.data[0]) def test_axis_labels_sync_with_setters(self): self.add_data() self.client.xatt = self.ids[1] assert self.client.axes.get_xlabel() == self.ids[1].label self.client.yatt = self.ids[0] assert self.client.axes.get_ylabel() == self.ids[0].label def test_setters_require_componentID(self): self.add_data() with pytest.raises(TypeError): self.client.xatt = self.ids[1]._label self.client.xatt = self.ids[1] def test_logs(self): self.add_data() self.client.xlog = True assert self.client.axes.get_xscale() == 'log' self.client.xlog = False assert self.client.axes.get_xscale() == 'linear' self.client.ylog = True assert self.client.axes.get_yscale() == 'log' self.client.ylog = False assert self.client.axes.get_yscale() == 'linear' def test_flips(self): self.add_data() self.client.xflip = True self.assert_flips(True, False) self.client.xflip = False self.assert_flips(False, False) self.client.yflip = True self.assert_flips(False, True) self.client.yflip = False self.assert_flips(False, False) def assert_flips(self, xflip, yflip): ax = self.client.axes xlim = ax.get_xlim() ylim = ax.get_ylim() assert (xlim[1] < xlim[0]) == xflip assert (ylim[1] < ylim[0]) == yflip def test_double_add(self): n0 = len(self.client.axes.lines) layer = self.add_data_and_attributes() # data present assert len(self.client.axes.lines) == n0 + 1 + len(layer.subsets) layer = self.add_data() # data still present assert len(self.client.axes.lines) == n0 + 1 + len(layer.subsets) def test_data_updates_propagate(self): layer = self.add_data_and_attributes() assert self.layer_drawn(layer) self.client._layer_updated = False layer.style.color = 'k' assert self.client._layer_updated def test_data_removal(self): layer = self.add_data() subset = layer.new_subset() self.collect.remove(layer) assert not self.client.is_layer_present(layer) assert not self.client.is_layer_present(subset) def test_add_subset_while_connected(self): layer = self.add_data() subset = layer.new_subset() assert self.client.is_layer_present(subset) def test_subset_removal(self): layer = self.add_data() subset = layer.new_subset() assert self.client.is_layer_present(layer) subset.delete() assert not self.client.is_layer_present(subset) def test_subset_removal_removes_from_plot(self): layer = self.add_data_and_attributes() subset = layer.new_subset() ct0 = len(self.client.axes.lines) subset.delete() assert len(self.client.axes.lines) == ct0 - 1 def test_add_subset_to_untracked_data(self): subset = self.data[0].new_subset() assert not self.client.is_layer_present(subset) def test_valid_plot_data(self): layer = self.add_data_and_attributes() x = layer[self.ids[0]] y = layer[self.ids[1]] assert self.layer_data_correct(layer, x, y) def test_attribute_update_plot_data(self): layer = self.add_data_and_attributes() x = layer[self.ids[0]] y = layer[self.ids[0]] self.client.yatt = self.ids[0] assert self.layer_data_correct(layer, x, y) def test_invalid_plot(self): layer = self.add_data_and_attributes() assert self.layer_drawn(layer) c = ComponentID('bad id') self.client.xatt = c assert not self.layer_drawn(layer) self.client.xatt = self.ids[0] def test_redraw_called_on_invalid_plot(self): """ Plot should be updated when given invalid data, to sync layers' disabled/invisible states""" ctr = MagicMock() layer = self.add_data_and_attributes() assert self.layer_drawn(layer) c = ComponentID('bad id') self.client._redraw = ctr ct0 = ctr.call_count self.client.xatt = c ct1 = ctr.call_count ncall = ct1 - ct0 expected = len(self.client.artists) assert ncall >= expected self.client.xatt = self.ids[0] def test_two_incompatible_data(self): d0 = self.add_data(self.data[0]) d1 = self.add_data(self.data[1]) self.client.xatt = self.ids[0] self.client.yatt = self.ids[1] x = d0[self.ids[0]] y = d0[self.ids[1]] assert self.layer_drawn(d0) assert self.layer_data_correct(d0, x, y) assert not self.layer_drawn(d1) self.client.xatt = self.ids[2] self.client.yatt = self.ids[3] x = d1[self.ids[2]] y = d1[self.ids[3]] assert self.layer_drawn(d1) assert self.layer_data_correct(d1, x, y) assert not self.layer_drawn(d0) def test_subsets_connect_with_data(self): data = self.data[0] s1 = data.new_subset() s2 = data.new_subset() self.collect.append(data) self.client.add_data(data) assert self.client.is_layer_present(s1) assert self.client.is_layer_present(s2) assert self.client.is_layer_present(data) # should also work with add_layer self.collect.remove(data) assert data not in self.collect assert not self.client.is_layer_present(s1) self.collect.append(data) self.client.add_layer(data) assert self.client.is_layer_present(s1) def test_edit_subset_connect_with_data(self): data = self.add_data() assert self.client.is_layer_present(data.edit_subset) def test_edit_subset_removed_with_data(self): data = self.add_data() self.collect.remove(data) assert not self.client.is_layer_present(data.edit_subset) def test_apply_roi(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert self.layer_data_correct(data.edit_subset, x, y) def test_apply_roi_adds_on_empty(self): data = self.add_data_and_attributes() data._subsets = [] data.edit_subset = None roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert data.edit_subset is not None def test_apply_roi_applies_to_all_editable_subsets(self): d1 = self.add_data_and_attributes() d2 = self.add_data() state1 = d1.edit_subset.subset_state state2 = d2.edit_subset.subset_state roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert d1.edit_subset.subset_state is not state1 assert d1.edit_subset.subset_state is not state2 def test_apply_roi_doesnt_add_if_any_selection(self): d1 = self.add_data_and_attributes() d2 = self.add_data() d1.edit_subset = None d2.edit_subset = d2.new_subset() ct = len(d1.subsets) roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert len(d1.subsets) == ct def test_subsets_drawn_over_data(self): data = self.add_data_and_attributes() subset = data.new_subset() assert self.is_first_in_front(subset, data) def test_log_sticky(self): self.add_data_and_attributes() self.assert_logs(False, False) self.client.xlog = True self.client.ylog = True self.assert_logs(True, True) self.client.xatt = self.ids[1] self.client.yatt = self.ids[0] self.assert_logs(True, True) def test_log_ticks(self): # regression test for 354 self.add_data_and_attributes() self.assert_logs(False, False) self.client.xlog = True self.client.yatt = self.ids[0] self.assert_logs(True, False) assert not isinstance(self.client.axes.yaxis.get_major_locator(), LogLocator) def assert_logs(self, xlog, ylog): ax = self.client.axes assert ax.get_xscale() == ('log' if xlog else 'linear') assert ax.get_yscale() == ('log' if ylog else 'linear') def test_flip_sticky(self): self.add_data_and_attributes() self.client.xflip = True self.assert_flips(True, False) self.client.xatt = self.ids[1] self.assert_flips(True, False) self.client.xatt = self.ids[0] self.assert_flips(True, False) def test_visibility_sticky(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) assert self.client.is_visible(data.edit_subset) self.client.apply_roi(roi) self.client.set_visible(data.edit_subset, False) assert not self.client.is_visible(data.edit_subset) self.client.apply_roi(roi) assert not self.client.is_visible(data.edit_subset) def test_2d_data(self): """Should be abple to plot 2d data""" data = self.setup_2d_data() assert self.layer_data_correct(data, [1, 2, 3, 4], [2, 4, 6, 8]) def test_2d_data_limits_with_subset(self): """visible limits should work with subsets and 2d data""" d = self.setup_2d_data() state = d.id['x'] > 2 s = d.new_subset() s.subset_state = state assert self.client._visible_limits(0) == (1, 4) assert self.client._visible_limits(1) == (2, 8) def test_limits_nans(self): d = Data() x = Component(np.array([[1, 2], [np.nan, 4]])) y = Component(np.array([[2, 4], [np.nan, 8]])) xid = d.add_component(x, 'x') yid = d.add_component(y, 'y') self.collect.append(d) self.client.add_layer(d) self.client.xatt = xid self.client.yatt = yid assert self.client._visible_limits(0) == (1, 4) assert self.client._visible_limits(1) == (2, 8) def test_limits_inf(self): d = Data() x = Component(np.array([[1, 2], [np.infty, 4]])) y = Component(np.array([[2, 4], [-np.infty, 8]])) xid = d.add_component(x, 'x') yid = d.add_component(y, 'y') self.collect.append(d) self.client.add_layer(d) self.client.xatt = xid self.client.yatt = yid assert self.client._visible_limits(0) == (1, 4) assert self.client._visible_limits(1) == (2, 8) def test_xlog_relimits_if_negative(self): self.add_data_and_attributes() self.client.xflip = False self.client.xlog = False self.client.axes.set_xlim(-5, 5) self.client.xlog = True assert self.client.axes.get_xlim()[0] > .9 def test_ylog_relimits_if_negative(self): self.add_data_and_attributes() self.client.yflip = False self.client.ylog = False self.client.axes.set_ylim(-5, 5) self.client.ylog = True assert self.client.axes.get_ylim()[0] > .9 def test_subset_added_only_if_data_layer_present(self): self.collect.append(self.data[0]) assert self.data[0] not in self.client.artists s = self.data[0].new_subset() assert s not in self.client.artists def test_pull_properties(self): ax = self.client.axes ax.set_xlim(6, 5) ax.set_ylim(8, 7) ax.set_xscale('log') ax.set_yscale('log') self.client._pull_properties() self.assert_properties_correct() def test_rescaled_on_init(self): layer = self.setup_2d_data() self.assert_layer_inside_limits(layer) def test_set_limits(self): self.client.xmin = 3 self.client.xmax = 4 self.client.ymin = 5 self.client.ymax = 6 ax = self.client.axes xlim = ax.get_xlim() ylim = ax.get_ylim() assert xlim[0] == self.client.xmin assert xlim[1] == self.client.xmax assert ylim[0] == self.client.ymin assert ylim[1] == self.client.ymax def test_ignore_duplicate_updates(self): """Need not create new artist on every draw. Enforce this""" layer = self.setup_2d_data() m = MagicMock() self.client.artists[layer][0].clear = m self.client._update_layer(layer) ct0 = m.call_count self.client._update_layer(layer) ct1 = m.call_count assert ct1 == ct0 def test_range_rois_preserved(self): data = self.add_data_and_attributes() assert self.client.xatt is not self.client.yatt roi = XRangeROI() roi.set_range(1, 2) self.client.apply_roi(roi) assert isinstance(data.edit_subset.subset_state, RangeSubsetState) assert data.edit_subset.subset_state.att == self.client.xatt roi = RectangularROI() roi = YRangeROI() roi.set_range(1, 2) self.client.apply_roi(roi) assert data.edit_subset.subset_state.att == self.client.yatt def test_component_replaced(self): # regression test for #508 data = self.add_data_and_attributes() test = ComponentID('test') data.update_id(self.client.xatt, test) assert self.client.xatt is test
data.hub.broadcast(msg) else: pc = ParsedCommand(self._state[data][cid_new]['equation']._cmd, components) link = ParsedComponentLink(cid_new, pc) data.add_component_link(link) # Findally, reorder components as needed data.reorder_components(cids_all) super(ArithmeticEditorWidget, self).accept() if __name__ == "__main__": # pragma: nocover from glue.utils.qt import get_qapp app = get_qapp() import numpy as np from glue.core.data import Data from glue.core.data_collection import DataCollection x = np.random.random((5, 5)) y = x * 3 dc = DataCollection() dc.append(Data(label='test1', x=x, y=y)) dc.append(Data(label='test2', a=x, b=y)) widget = ArithmeticEditorWidget(dc) widget.exec_()
hub.subscribe(self, # subscribing object DataMessage, # message type to subscribe to handler = self.receive_message) # method to call def receive_message(self, message): """ Receives each DataMessage relay """ print " MyClient received a message \n" # create objects hub = Hub() client = MyClient() data = Data() subset = data.new_subset() data_collection = DataCollection() # connect them to each other data_collection.append(data) data_collection.register_to_hub(hub) client.register_to_hub(hub) # manually send a DataMessage. Relayed to MyClient print 'Manually sending DataMessage' message = DataMessage(data) hub.broadcast(message) #modify the data object. Automatically generates a DataMessage print 'Automatically triggering DataMessage' data.label = "New label"
class TestCategoricalHistogram(TestHistogramClient): def setup_method(self, method): self.data = Data(y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.data.add_component(CategoricalComponent(['a', 'a', 'a', 'b', 'c', 'd', 'd', 'e', 'f']), 'x') self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0 def test_xlimit_single_set(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlimits = (None, 5) assert self.client.xlimits == (-0.5, 5) self.client.xlimits = (3, None) assert self.client.xlimits == (3, 5) def test_default_xlimits(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) assert self.client.xlimits == (-0.5, 5.5) self.client.set_component(self.data.id['y']) assert self.client.xlimits == (-7, -1) def test_change_default_bins(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) assert self.client.nbins == 6 def test_tick_labels(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) correct_labels = ['a', 'b', 'c', 'd', 'e', 'f'] formatter = self.client.axes.xaxis.get_major_formatter() xlabels = [formatter.format_data(pos) for pos in range(6)] assert correct_labels == xlabels def test_apply_roi(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) # bins are 1...4 self.data.edit_subset = [self.data.subsets[0]] roi = MagicMock() roi.to_polygon.return_value = [1.2, 2, 4], [2, 3, 4] self.client.apply_roi(roi) state = self.data.subsets[0].subset_state assert isinstance(state, CategoricalROISubsetState) np.testing.assert_equal(self.data.subsets[0].subset_state.roi.categories, np.array(['b', 'c', 'd', 'e'])) # REMOVED TESTS def test_xlog_axes_labels(self): """ log-scale doesn't make sense for categorical data""" pass def test_xlog_snaps_limits(self): """ log-scale doesn't make sense for categorical data""" pass def test_apply_roi_xlog(self): """ log-scale doesn't make sense for categorical data""" pass def test_nbin_override_persists_over_attribute_change(self): # regression test for #398 self.collect.append(self.data) self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.nbins = 7 self.client.set_component(self.data.id['y']) assert self.client.nbins == 7
class TestCommunication(object): def setup_method(self, method): self.data = Data(x=[1, 2, 3, 2, 2, 3, 1]) figure = MagicMock() self.collect = DataCollection() self.client = HistogramClient(self.collect, figure) self.axes = self.client.axes self.hub = self.collect.hub self.connect() def draw_count(self): return self.axes.figure.canvas.draw.call_count def connect(self): self.client.register_to_hub(self.hub) self.collect.register_to_hub(self.hub) def test_ignore_data_add_message(self): self.collect.append(self.data) assert not (self.client.layer_present(self.data)) def test_update_data_ignored_if_data_not_present(self): self.collect.append(self.data) ct0 = self.draw_count() self.data.style.color = 'blue' assert self.draw_count() == ct0 def test_update_data_processed_if_data_present(self): self.collect.append(self.data) self.client.add_layer(self.data) ct0 = self.draw_count() self.data.style.color = 'blue' assert self.draw_count() > ct0 def test_add_subset_ignored_if_data_not_present(self): self.collect.append(self.data) sub = self.data.new_subset() assert not (self.client.layer_present(sub)) def test_add_subset_processed_if_data_present(self): self.collect.append(self.data) self.client.add_layer(self.data) sub = self.data.new_subset() assert (self.client.layer_present(sub)) def test_update_subset_ignored_if_not_present(self): self.collect.append(self.data) self.client.add_layer(self.data) sub = self.data.new_subset() self.client.remove_layer(sub) ct0 = self.draw_count() sub.style.color = 'blue' assert self.draw_count() == ct0 def test_update_subset_processed_if_present(self): self.collect.append(self.data) self.client.add_layer(self.data) sub = self.data.new_subset() ct0 = self.draw_count() sub.style.color = 'blue' assert self.draw_count() > ct0 def test_data_remove_message(self): self.collect.append(self.data) self.client.add_layer(self.data) self.collect.remove(self.data) assert not self.client.layer_present(self.data) def test_subset_remove_message(self): self.collect.append(self.data) self.client.add_layer(self.data) sub = self.data.new_subset() assert self.client.layer_present(sub) sub.delete() assert not self.client.layer_present(sub)
class TestHistogramClient(object): def setup_method(self, method): self.data = Data(x=[0, 0, 0, 1, 2, 3, 3, 10, 20], y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0 def draw_count(self): return self.axes.figure.canvas.draw.call_count def layer_drawn(self, layer): return layer in self.client._artists and \ all(a.visible for a in self.client._artists[layer]) and \ all(len(a.artists) > 0 for a in self.client._artists[layer]) def layer_present(self, layer): return layer in self.client._artists def assert_autoscaled(self): yra = self.client.axes.get_ylim() datara = [99999, -99999] for a in self.client._artists: if a.y.size > 0: datara[0] = min(datara[0], a.y.min()) datara[1] = max(datara[1], a.y.max()) assert yra[0] <= datara[0] assert yra[1] >= datara[1] def test_empty_on_creation(self): assert self.data not in self.client._artists def test_add_layer(self): self.client.add_layer(self.data) assert self.layer_present(self.data) assert not self.layer_drawn(self.data) self.client.set_component(self.data.components[0]) assert self.layer_drawn(self.data) def test_add_invalid_layer_raises(self): self.collect.remove(self.data) with pytest.raises(IncompatibleDataException): self.client.add_layer(self.data) def test_add_subset_auto_adds_data(self): subset = self.data.new_subset() self.client.add_layer(subset) assert self.layer_present(self.data) assert self.layer_present(subset) self.client.set_component(self.data.components[0]) assert self.layer_drawn(self.data) def test_double_add_ignored(self): self.client.add_layer(self.data) art = self.client._artists[self.data] self.client.add_layer(self.data) assert self.client._artists[self.data] == art def test_add_data_auto_adds_subsets(self): s = self.data.new_subset() self.client.add_layer(self.data) assert self.layer_present(s) def test_data_removal(self): self.client.add_layer(self.data) self.client.remove_layer(self.data) assert not (self.layer_present(self.data)) def test_data_removal_removes_subsets(self): self.client.add_layer(self.data) self.client.remove_layer(self.data) self.data.new_subset() assert len(self.data.subsets) > 0 for subset in self.data.subsets: assert not (self.layer_present(subset)) def test_layer_updates_on_data_add(self): self.client.add_layer(self.data) for s in self.data.subsets: assert s in self.client._artists def test_set_component_updates_component(self): self.client.add_layer(self.data) comp = self.data.find_component_id('uniform') self.client.set_component(comp) assert self.client._component is comp def test_set_component_redraws(self): self.client.add_layer(self.data) comp = self.data.id['x'] comp2 = self.data.id['y'] self.client.set_component(comp) ct0 = self.draw_count() self.client.set_component(comp2) assert self.draw_count() > ct0 def test_remove_not_present_ignored(self): self.client.remove_layer(self.data) def test_set_visible_external_data(self): self.client.set_layer_visible(None, False) def test_get_visible_external_data(self): assert not (self.client.is_layer_visible(None)) def test_set_visible(self): self.client.add_layer(self.data) self.client.set_layer_visible(self.data, False) assert not (self.client.is_layer_visible(self.data)) def test_draw_histogram_one_layer(self): self.client.add_layer(self.data) self.client.set_component(self.data.find_component_id('uniform')) def test_draw_histogram_subset_hidden(self): self.client.add_layer(self.data) s = self.data.new_subset() self.client.set_layer_visible(s, False) self.client.set_component(self.data.find_component_id('uniform')) def test_draw_histogram_two_layers(self): self.client.add_layer(self.data) self.client.set_component(self.data.find_component_id('uniform')) def test_update_property_set_triggers_redraw(self): self.client.add_layer(self.data) ct = self.draw_count() self.client.normed ^= True assert self.draw_count() > ct @pytest.mark.parametrize(('prop'), ['normed', 'cumulative']) def test_set_boolean_property(self, prop): """Boolean properties should sync with artists""" self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) setattr(self.client, prop, False) for a in self.client._artists: assert not getattr(a, prop) setattr(self.client, prop, True) for a in self.client._artists: assert getattr(a, prop) def test_set_nbins(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.nbins = 100 for a in self.client._artists[self.data]: assert a.nbins == 100 assert a.x.size == 100 + 1 def test_autoscale(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.axes.set_ylim(0, .1) self.client.autoscale = False self.client.autoscale = True self.assert_autoscaled() def test_xlimits(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.xlimits = -12, 20 assert self.client.xlimits == (-12, 20) for a in self.client._artists[self.data]: assert a.lo == -12 assert a.hi == 20 def test_set_xlimits_out_of_data_range(self): """Setting xlimits outside of range shouldn't crash""" self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.xlimits = 100, 200 self.client.xlimits = -200, -100 def test_component_property(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) assert self.client.component is self.data.components[0] def test_apply_roi(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['y']) # bins are -7...-1 self.data.edit_subset = [self.data.subsets[0]] roi = PolygonalROI(vx=[-5.1, -4.5, -3.2], vy=[2, 3, 4]) self.client.apply_roi(roi) state = self.data.subsets[0].subset_state assert isinstance(state, RangeSubsetState) # range should expand to nearest bin edge assert state.lo == -6 assert state.hi == -3 def test_apply_roi_xlog(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.data.edit_subset = [self.data.subsets[0]] self.client.xlog = True roi = PolygonalROI(vx=[1, 2, 3], vy=[2, 3, 4]) self.client.apply_roi(roi) state = self.data.subsets[0].subset_state assert isinstance(state, RangeSubsetState) np.testing.assert_allclose(state.lo, 7.3680629972807736) np.testing.assert_allclose(state.hi, 1000) def test_xlimits_sticky_with_component(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) self.client.xlimits = 5, 6 self.client.set_component(self.data.components[1]) self.client.xlimits = 7, 8 self.client.set_component(self.data.components[0]) assert self.client.xlimits == (5, 6) self.client.set_component(self.data.components[1]) assert self.client.xlimits == (7, 8) def test_default_xlimits(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) assert self.client.xlimits == (0, 20) self.client.set_component(self.data.id['y']) assert self.client.xlimits == (-7, -1) def test_xlimit_single_set(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlimits = (None, 5) assert self.client.xlimits == (0, 5) self.client.xlimits = (3, None) assert self.client.xlimits == (3, 5) def test_xlimit_reverse_set(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlimits = 5, 3 assert self.client.xlimits == (3, 5) def test_xlog_axes_labels(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlog = True assert self.client.axes.get_xlabel() == 'Log x' self.client.xlog = False assert self.client.axes.get_xlabel() == 'x' self.client.ylog = True assert self.client.axes.get_ylabel() == 'N' self.client.ylog = False assert self.client.axes.get_ylabel() == 'N' def test_xlog_snaps_limits(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.axes.set_xlim((-1, 1)) self.client.xlog = True assert self.client.axes.get_xlim() != (-1, 1) def test_artist_clear_resets_arrays(self): self.client.add_layer(self.data) self.client.set_component(self.data.components[0]) for a in self.client._artists[self.data]: assert a.get_data()[0].size > 0 a.clear() assert a.get_data()[0].size == 0 def test_component_replaced(self): # regression test for 508 self.client.register_to_hub(self.collect.hub) self.client.add_layer(self.data) self.client.component = self.data.components[0] test = ComponentID('test') self.data.update_id(self.client.component, test) assert self.client.component is test
def test_data_application(self): dc = DataCollection([Data(label='test', x=[1, 2, 3], y=[2, 3, 4])]) app = GlueApplication(dc) self.check_clone(app)
class TestCategoricalHistogram(TestHistogramClient): def setup_method(self, method): self.data = Data(y=[-1, -1, -1, -2, -2, -2, -3, -5, -7]) self.data.add_component( CategoricalComponent(['a', 'a', 'a', 'b', 'c', 'd', 'd', 'e', 'f']), 'x') self.subset = self.data.new_subset() self.collect = DataCollection(self.data) self.client = HistogramClient(self.collect, FIGURE) self.axes = self.client.axes FIGURE.canvas.draw = MagicMock() assert FIGURE.canvas.draw.call_count == 0 def test_xlimit_single_set(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.xlimits = (None, 5) assert self.client.xlimits == (-0.5, 5) self.client.xlimits = (3, None) assert self.client.xlimits == (3, 5) def test_default_xlimits(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) assert self.client.xlimits == (-0.5, 5.5) self.client.set_component(self.data.id['y']) assert self.client.xlimits == (-7, -1) def test_change_default_bins(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) assert self.client.nbins == 6 def test_tick_labels(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) correct_labels = ['a', 'b', 'c', 'd', 'e', 'f'] formatter = self.client.axes.xaxis.get_major_formatter() xlabels = [formatter.format_data(pos) for pos in range(6)] assert correct_labels == xlabels def test_apply_roi(self): self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) # bins are 1...4 self.data.edit_subset = [self.data.subsets[0]] roi = MagicMock() roi.to_polygon.return_value = [1.2, 2, 4], [2, 3, 4] self.client.apply_roi(roi) state = self.data.subsets[0].subset_state assert isinstance(state, CategoricalROISubsetState) np.testing.assert_equal( self.data.subsets[0].subset_state.roi.categories, np.array(['b', 'c', 'd', 'e'])) # REMOVED TESTS def test_xlog_axes_labels(self): """ log-scale doesn't make sense for categorical data""" pass def test_xlog_snaps_limits(self): """ log-scale doesn't make sense for categorical data""" pass def test_apply_roi_xlog(self): """ log-scale doesn't make sense for categorical data""" pass def test_nbin_override_persists_over_attribute_change(self): # regression test for #398 self.collect.append(self.data) self.client.add_layer(self.data) self.client.set_component(self.data.id['x']) self.client.nbins = 7 self.client.set_component(self.data.id['y']) assert self.client.nbins == 7
raise NotImplementedError() self.ui.layerTree[key] = value def __contains__(self, obj): return obj in self.ui.layerTree def __len__(self): return len(self.ui.layerTree) def save_subset(subset): assert isinstance(subset, core.subset.Subset) fname, fltr = QtGui.QFileDialog.getSaveFileName( caption="Select an output name", filter='FITS mask (*.fits);; Fits mask (*.fits)') fname = str(fname) if not fname: return subset.write_mask(fname) if __name__ == "__main__": from glue.core.data_collection import DataCollection collection = DataCollection() from glue.external.qt import get_qapp app = get_qapp() widget = LayerTreeWidget() widget.setup(collection) widget.show() app.exec_()
from glue.viewers.image.qt import ImageViewer # create some data data_path = Path("/home/stuart/sunpy/data/iris_glue/") rasters = list(data_path.glob("*raster*")) sji = list(data_path.glob("*SJI*")) raster_data = _parse_iris_raster(read_iris_spectrograph_level2_fits(rasters), 'iris') sji_data = [] for s in sji: sji_data += load_data(s) dc = DataCollection(raster_data + sji_data) ga = GlueApplication(dc) im1 = ga.new_data_viewer(ImageViewer) im1.add_data(raster_data[0]) im2 = ga.new_data_viewer(ImageViewer) im2.add_data(sji_data[0]) class IRISLinker: def __init__(self, im1, im2): self.im_raster = im1 self.im_sji = im2 self.im_raster.state.add_callback("slices", self._raster_update)
def test_pixel_selection_subset_state(): data1 = Data(x=np.ones((2, 4, 3))) data2 = Data(y=np.ones((4, 3, 2))) data3 = Data(z=np.ones((2, 3))) y_id = data2.main_components[0] z_id = data3.main_components[0] slice_1d = [slice(1, 2), slice(None), slice(None)] slice_2d = [slice(None), slice(2, 3), slice(1, 2)] slice_3d = [slice(1, 2), slice(2, 3), slice(1, 2)] state_1d = PixelSubsetState(data1, slice_1d) state_2d = PixelSubsetState(data1, slice_2d) state_3d = PixelSubsetState(data1, slice_3d) states = [state_1d, state_2d, state_3d] dc = DataCollection([data1, data2, data3]) # Calling to_array with reference data should work by default, and not work # with unlinked datasets. for data in dc: for state in states: cid = data.main_components[0] if data is data1: assert_array_equal(state.to_array(data, cid), data[cid][state.slices]) else: with pytest.raises(IncompatibleAttribute): state.to_array(data, cid) # Add one set of links dc.add_link( LinkSame(data1.pixel_component_ids[0], data2.pixel_component_ids[2])) dc.add_link( LinkSame(data1.pixel_component_ids[0], data3.pixel_component_ids[0])) assert_array_equal(state_1d.to_array(data2, y_id), data2[y_id][:, :, 1:2]) with pytest.raises(IncompatibleAttribute): state_2d.to_array(data2, y_id) with pytest.raises(IncompatibleAttribute): state_3d.to_array(data2, y_id) assert_array_equal(state_1d.to_array(data3, z_id), data3[z_id][1:2]) with pytest.raises(IncompatibleAttribute): state_2d.to_array(data3, z_id) with pytest.raises(IncompatibleAttribute): state_3d.to_array(data3, z_id) # Add links with multiple components, in this case linking two cids with two cids def forwards(x, y): return x + y, x - y def backwards(x, y): return 0.5 * (x + y), 0.5 * (x - y) dc.add_link( MultiLink(data1.pixel_component_ids[1:], data2.pixel_component_ids[:2], forwards=forwards, backwards=backwards)) assert_array_equal(state_1d.to_array(data2, y_id), data2[y_id][:, :, 1:2]) assert_array_equal(state_2d.to_array(data2, y_id), data2[y_id][2:3, 1:2, :]) assert_array_equal(state_3d.to_array(data2, y_id), data2[y_id][2:3, 1:2, 1:2]) assert_array_equal(state_1d.to_array(data3, z_id), data3[z_id][1:2]) with pytest.raises(IncompatibleAttribute): state_2d.to_array(data3, z_id) with pytest.raises(IncompatibleAttribute): state_3d.to_array(data3, z_id)
class TestScatterClient(object): def setup_method(self, method): self.data = example_data.test_data() self.ids = [self.data[0].find_component_id('a'), self.data[0].find_component_id('b'), self.data[1].find_component_id('c'), self.data[1].find_component_id('d')] self.roi_limits = (0.5, 0.5, 1.5, 1.5) self.roi_points = (np.array([1]), np.array([1])) self.collect = DataCollection() EditSubsetMode().data_collection = self.collect self.hub = self.collect.hub FIGURE.clf() axes = FIGURE.add_subplot(111) self.client = ScatterClient(self.collect, axes=axes) self.connect() def teardown_method(self, methdod): self.assert_properties_correct() self.assert_axes_ticks_correct() def assert_properties_correct(self): ax = self.client.axes cl = self.client xlim = ax.get_xlim() ylim = ax.get_ylim() assert abs(cl.xmin - min(xlim)) < 1e-2 assert abs(cl.xmax - max(xlim)) < 1e-2 assert abs(cl.ymin - min(ylim)) < 1e-2 assert abs(cl.ymax - max(ylim)) < 1e-2 assert cl.xflip == (xlim[1] < xlim[0]) assert cl.yflip == (ylim[1] < ylim[0]) assert cl.xlog == (ax.get_xscale() == 'log') assert cl.ylog == (ax.get_yscale() == 'log') assert (self.client.xatt is None) or isinstance( self.client.xatt, ComponentID) assert (self.client.yatt is None) or isinstance( self.client.yatt, ComponentID) def check_ticks(self, axis, is_log, is_cat): locator = axis.get_major_locator() formatter = axis.get_major_formatter() if is_log: assert isinstance(locator, LogLocator) assert isinstance(formatter, LogFormatterMathtext) elif is_cat: assert isinstance(locator, MaxNLocator) assert isinstance(formatter, FuncFormatter) else: assert isinstance(locator, AutoLocator) assert isinstance(formatter, ScalarFormatter) def assert_axes_ticks_correct(self): ax = self.client.axes client = self.client if client.xatt is not None: self.check_ticks(ax.xaxis, client.xlog, client._check_categorical(client.xatt)) if client.yatt is not None: self.check_ticks(ax.yaxis, client.ylog, client._check_categorical(client.yatt)) def plot_data(self, layer): """ Return the data bounds for a given layer (data or subset) Output format: [xmin, xmax], [ymin, ymax] """ client = self.client x, y = client.artists[layer][0].get_data() xmin = x.min() xmax = x.max() ymin = y.min() ymax = y.max() return [xmin, xmax], [ymin, ymax] def plot_limits(self): """ Return the plot limits Output format [xmin, xmax], [ymin, ymax] """ ax = self.client.axes xlim = ax.get_xlim() ylim = ax.get_ylim() return (min(xlim), max(xlim)), (min(ylim), max(ylim)) def assert_layer_inside_limits(self, layer): """Assert that points of a layer are within plot limits """ xydata = self.plot_data(layer) xylimits = self.plot_limits() assert xydata[0][0] >= xylimits[0][0] assert xydata[1][0] >= xylimits[1][0] assert xydata[0][1] <= xylimits[0][1] assert xydata[1][1] <= xylimits[1][1] def setup_2d_data(self): d = Data(x=[[1, 2], [3, 4]], y=[[2, 4], [6, 8]]) self.collect.append(d) self.client.add_layer(d) self.client.xatt = d.id['x'] self.client.yatt = d.id['y'] return d def add_data(self, data=None): if data is None: data = self.data[0] data.edit_subset = data.new_subset() self.collect.append(data) self.client.add_data(data) return data def add_data_and_attributes(self): data = self.add_data() data.edit_subset = data.new_subset() self.client.xatt = self.ids[0] self.client.yatt = self.ids[1] return data def is_first_in_front(self, front, back): z1 = self.client.get_layer_order(front) z2 = self.client.get_layer_order(back) return z1 > z2 def connect(self): self.client.register_to_hub(self.hub) self.collect.register_to_hub(self.hub) def layer_drawn(self, layer): return self.client.is_layer_present(layer) and \ all(a.enabled and a.visible for a in self.client.artists[layer]) def layer_data_correct(self, layer, x, y): xx, yy = self.client.artists[layer][0].get_data() if max(abs(xx - x)) > .01: return False if max(abs(yy - y)) > .01: return False return True def test_empty_on_creation(self): for d in self.data: assert not self.client.is_layer_present(d) def test_add_external_data_raises_exception(self): data = Data() with pytest.raises(TypeError) as exc: self.client.add_data(data) assert exc.value.args[0] == "Layer not in data collection" def test_valid_add(self): self.add_data() assert self.client.is_layer_present(self.data[0]) def test_axis_labels_sync_with_setters(self): self.add_data() self.client.xatt = self.ids[1] assert self.client.axes.get_xlabel() == self.ids[1].label self.client.yatt = self.ids[0] assert self.client.axes.get_ylabel() == self.ids[0].label def test_setters_require_componentID(self): self.add_data() with pytest.raises(TypeError): self.client.xatt = self.ids[1]._label self.client.xatt = self.ids[1] def test_logs(self): self.add_data() self.client.xlog = True assert self.client.axes.get_xscale() == 'log' self.client.xlog = False assert self.client.axes.get_xscale() == 'linear' self.client.ylog = True assert self.client.axes.get_yscale() == 'log' self.client.ylog = False assert self.client.axes.get_yscale() == 'linear' def test_flips(self): self.add_data() self.client.xflip = True self.assert_flips(True, False) self.client.xflip = False self.assert_flips(False, False) self.client.yflip = True self.assert_flips(False, True) self.client.yflip = False self.assert_flips(False, False) def assert_flips(self, xflip, yflip): ax = self.client.axes xlim = ax.get_xlim() ylim = ax.get_ylim() assert (xlim[1] < xlim[0]) == xflip assert (ylim[1] < ylim[0]) == yflip def test_double_add(self): n0 = len(self.client.axes.lines) layer = self.add_data_and_attributes() # data present assert len(self.client.axes.lines) == n0 + 1 + len(layer.subsets) layer = self.add_data() # data still present assert len(self.client.axes.lines) == n0 + 1 + len(layer.subsets) def test_data_updates_propagate(self): layer = self.add_data_and_attributes() assert self.layer_drawn(layer) self.client._layer_updated = False layer.style.color = 'k' assert self.client._layer_updated def test_data_removal(self): layer = self.add_data() subset = layer.new_subset() self.collect.remove(layer) assert not self.client.is_layer_present(layer) assert not self.client.is_layer_present(subset) def test_add_subset_while_connected(self): layer = self.add_data() subset = layer.new_subset() assert self.client.is_layer_present(subset) def test_subset_removal(self): layer = self.add_data() subset = layer.new_subset() assert self.client.is_layer_present(layer) subset.delete() assert not self.client.is_layer_present(subset) def test_subset_removal_removes_from_plot(self): layer = self.add_data_and_attributes() subset = layer.new_subset() ct0 = len(self.client.axes.lines) subset.delete() assert len(self.client.axes.lines) == ct0 - 1 def test_add_subset_to_untracked_data(self): subset = self.data[0].new_subset() assert not self.client.is_layer_present(subset) def test_valid_plot_data(self): layer = self.add_data_and_attributes() x = layer[self.ids[0]] y = layer[self.ids[1]] assert self.layer_data_correct(layer, x, y) def test_attribute_update_plot_data(self): layer = self.add_data_and_attributes() x = layer[self.ids[0]] y = layer[self.ids[0]] self.client.yatt = self.ids[0] assert self.layer_data_correct(layer, x, y) def test_invalid_plot(self): layer = self.add_data_and_attributes() assert self.layer_drawn(layer) c = ComponentID('bad id') self.client.xatt = c assert not self.layer_drawn(layer) self.client.xatt = self.ids[0] def test_redraw_called_on_invalid_plot(self): """ Plot should be updated when given invalid data, to sync layers' disabled/invisible states""" ctr = MagicMock() layer = self.add_data_and_attributes() assert self.layer_drawn(layer) c = ComponentID('bad id') self.client._redraw = ctr ct0 = ctr.call_count self.client.xatt = c ct1 = ctr.call_count ncall = ct1 - ct0 expected = len(self.client.artists) assert ncall >= expected self.client.xatt = self.ids[0] def test_two_incompatible_data(self): d0 = self.add_data(self.data[0]) d1 = self.add_data(self.data[1]) self.client.xatt = self.ids[0] self.client.yatt = self.ids[1] x = d0[self.ids[0]] y = d0[self.ids[1]] assert self.layer_drawn(d0) assert self.layer_data_correct(d0, x, y) assert not self.layer_drawn(d1) self.client.xatt = self.ids[2] self.client.yatt = self.ids[3] x = d1[self.ids[2]] y = d1[self.ids[3]] assert self.layer_drawn(d1) assert self.layer_data_correct(d1, x, y) assert not self.layer_drawn(d0) def test_subsets_connect_with_data(self): data = self.data[0] s1 = data.new_subset() s2 = data.new_subset() self.collect.append(data) self.client.add_data(data) assert self.client.is_layer_present(s1) assert self.client.is_layer_present(s2) assert self.client.is_layer_present(data) # should also work with add_layer self.collect.remove(data) assert data not in self.collect assert not self.client.is_layer_present(s1) self.collect.append(data) self.client.add_layer(data) assert self.client.is_layer_present(s1) def test_edit_subset_connect_with_data(self): data = self.add_data() assert self.client.is_layer_present(data.edit_subset) def test_edit_subset_removed_with_data(self): data = self.add_data() self.collect.remove(data) assert not self.client.is_layer_present(data.edit_subset) def test_apply_roi(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert self.layer_data_correct(data.edit_subset, x, y) def test_apply_roi_adds_on_empty(self): data = self.add_data_and_attributes() data._subsets = [] data.edit_subset = None roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert data.edit_subset is not None def test_apply_roi_applies_to_all_editable_subsets(self): d1 = self.add_data_and_attributes() d2 = self.add_data() state1 = d1.edit_subset.subset_state state2 = d2.edit_subset.subset_state roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert d1.edit_subset.subset_state is not state1 assert d1.edit_subset.subset_state is not state2 def test_apply_roi_doesnt_add_if_any_selection(self): d1 = self.add_data_and_attributes() d2 = self.add_data() d1.edit_subset = None d2.edit_subset = d2.new_subset() ct = len(d1.subsets) roi = RectangularROI() roi.update_limits(*self.roi_limits) x, y = self.roi_points self.client.apply_roi(roi) assert len(d1.subsets) == ct def test_subsets_drawn_over_data(self): data = self.add_data_and_attributes() subset = data.new_subset() assert self.is_first_in_front(subset, data) def test_log_sticky(self): self.add_data_and_attributes() self.assert_logs(False, False) self.client.xlog = True self.client.ylog = True self.assert_logs(True, True) self.client.xatt = self.ids[1] self.client.yatt = self.ids[0] self.assert_logs(True, True) def test_log_ticks(self): # regression test for 354 self.add_data_and_attributes() self.assert_logs(False, False) self.client.xlog = True self.client.yatt = self.ids[0] self.assert_logs(True, False) assert not isinstance(self.client.axes.yaxis.get_major_locator(), LogLocator) def assert_logs(self, xlog, ylog): ax = self.client.axes assert ax.get_xscale() == ('log' if xlog else 'linear') assert ax.get_yscale() == ('log' if ylog else 'linear') def test_flip_sticky(self): self.add_data_and_attributes() self.client.xflip = True self.assert_flips(True, False) self.client.xatt = self.ids[1] self.assert_flips(True, False) self.client.xatt = self.ids[0] self.assert_flips(True, False) def test_visibility_sticky(self): data = self.add_data_and_attributes() roi = RectangularROI() roi.update_limits(*self.roi_limits) assert self.client.is_visible(data.edit_subset) self.client.apply_roi(roi) self.client.set_visible(data.edit_subset, False) assert not self.client.is_visible(data.edit_subset) self.client.apply_roi(roi) assert not self.client.is_visible(data.edit_subset) def test_2d_data(self): """Should be abple to plot 2d data""" data = self.setup_2d_data() assert self.layer_data_correct(data, [1, 2, 3, 4], [2, 4, 6, 8]) def test_2d_data_limits_with_subset(self): """visible limits should work with subsets and 2d data""" d = self.setup_2d_data() state = d.id['x'] > 2 s = d.new_subset() s.subset_state = state assert self.client._visible_limits(0) == (1, 4) assert self.client._visible_limits(1) == (2, 8) def test_limits_nans(self): d = Data() x = Component(np.array([[1, 2], [np.nan, 4]])) y = Component(np.array([[2, 4], [np.nan, 8]])) xid = d.add_component(x, 'x') yid = d.add_component(y, 'y') self.collect.append(d) self.client.add_layer(d) self.client.xatt = xid self.client.yatt = yid assert self.client._visible_limits(0) == (1, 4) assert self.client._visible_limits(1) == (2, 8) def test_limits_inf(self): d = Data() x = Component(np.array([[1, 2], [np.infty, 4]])) y = Component(np.array([[2, 4], [-np.infty, 8]])) xid = d.add_component(x, 'x') yid = d.add_component(y, 'y') self.collect.append(d) self.client.add_layer(d) self.client.xatt = xid self.client.yatt = yid assert self.client._visible_limits(0) == (1, 4) assert self.client._visible_limits(1) == (2, 8) def test_xlog_relimits_if_negative(self): self.add_data_and_attributes() self.client.xflip = False self.client.xlog = False self.client.axes.set_xlim(-5, 5) self.client.xlog = True assert self.client.axes.get_xlim()[0] > .9 def test_ylog_relimits_if_negative(self): self.add_data_and_attributes() self.client.yflip = False self.client.ylog = False self.client.axes.set_ylim(-5, 5) self.client.ylog = True assert self.client.axes.get_ylim()[0] > .9 def test_subset_added_only_if_data_layer_present(self): self.collect.append(self.data[0]) assert self.data[0] not in self.client.artists s = self.data[0].new_subset() assert s not in self.client.artists def test_pull_properties(self): ax = self.client.axes ax.set_xlim(6, 5) ax.set_ylim(8, 7) ax.set_xscale('log') ax.set_yscale('log') self.client._pull_properties() self.assert_properties_correct() def test_rescaled_on_init(self): layer = self.setup_2d_data() self.assert_layer_inside_limits(layer) def test_set_limits(self): self.client.xmin = 3 self.client.xmax = 4 self.client.ymin = 5 self.client.ymax = 6 ax = self.client.axes xlim = ax.get_xlim() ylim = ax.get_ylim() assert xlim[0] == self.client.xmin assert xlim[1] == self.client.xmax assert ylim[0] == self.client.ymin assert ylim[1] == self.client.ymax def test_ignore_duplicate_updates(self): """Need not create new artist on every draw. Enforce this""" layer = self.setup_2d_data() m = MagicMock() self.client.artists[layer][0].clear = m self.client._update_layer(layer) ct0 = m.call_count self.client._update_layer(layer) ct1 = m.call_count assert ct1 == ct0 def test_range_rois_preserved(self): data = self.add_data_and_attributes() assert self.client.xatt is not self.client.yatt roi = XRangeROI() roi.set_range(1, 2) self.client.apply_roi(roi) assert isinstance(data.edit_subset.subset_state, RangeSubsetState) assert data.edit_subset.subset_state.att == self.client.xatt roi = RectangularROI() roi = YRangeROI() roi.set_range(1, 2) self.client.apply_roi(roi) assert data.edit_subset.subset_state.att == self.client.yatt def test_component_replaced(self): # regression test for #508 data = self.add_data_and_attributes() test = ComponentID('test') data.update_id(self.client.xatt, test) assert self.client.xatt is test