def test_n_dimensional(): """Test setting n_dimensional flag for 2D and 4D data.""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Points(data) assert layer.n_dimensional is False layer.n_dimensional = True assert layer.n_dimensional is True layer = Points(data, n_dimensional=True) assert layer.n_dimensional is True shape = (10, 4) data = 20 * np.random.random(shape) layer = Points(data) assert layer.n_dimensional is False layer.n_dimensional = True assert layer.n_dimensional is True layer = Points(data, n_dimensional=True) assert layer.n_dimensional is True
def test_write(mock_pm: PluginManager): # saving an image without a writer goes straight to npe2.write # it will use our plugin writer image = Image(np.random.rand(20, 20), name='ex_img') _npe2.write_layers('some_file.tif', [image]) mock_pm.commands.get.assert_called_once_with(f'{PLUGIN_NAME}.my_writer') # points won't trigger our sample writer mock_pm.commands.get.reset_mock() points = Points(np.random.rand(20, 2), name='ex_points') _npe2.write_layers('some_file.tif', [points]) mock_pm.commands.get.assert_not_called() # calling _npe2.write_layers with a specific writer contribution should # directly execute the writer.exec with arguments appropriate for the # writer spec (single or multi-writer) mock_pm.commands.get.reset_mock() writer = mock_pm.get_manifest(PLUGIN_NAME).contributions.writers[0] writer = MagicMock(wraps=writer) writer.exec.return_value = [''] assert _npe2.write_layers('some_file.tif', [points], writer=writer) == [''] mock_pm.commands.get.assert_not_called() expected_args = ('some_file.tif', *points.as_layer_data_tuple()[:2]) writer.exec.assert_called_once_with(args=expected_args)
def test_empty_points_with_properties(): """ Test instantiating an empty Points layer with properties See: https://github.com/napari/napari/pull/1069 """ properties = { 'label': np.array(['label1', 'label2']), 'cont_prop': np.array([0], dtype=np.float), } pts = Points(properties=properties) current_props = {k: v[0] for k, v in properties.items()} np.testing.assert_equal(pts.current_properties, current_props) # verify the property datatype is correct assert pts.properties['cont_prop'].dtype == np.float # add two points and verify the default property was applied pts.add([10, 10]) pts.add([20, 20]) props = { 'label': np.array(['label1', 'label1']), 'cont_prop': np.array([0, 0], dtype=np.float), } np.testing.assert_equal(pts.properties, props)
def test_color_cycle_dict(attribute): """Test setting edge/face color with a color cycle dict""" data = np.array([[0, 0], [100, 0], [0, 100]]) properties = {'my_colors': [2, 6, 3]} points_kwargs = { 'properties': properties, f'{attribute}_color': 'my_colors', f'{attribute}_color_cycle': {1: 'green', 2: 'red', 3: 'blue'}, } layer = Points(data, **points_kwargs) color_cycle_map = getattr(layer, f'{attribute}_color_cycle_map') np.testing.assert_allclose(color_cycle_map[2], [1, 0, 0, 1]) # 2 is red np.testing.assert_allclose(color_cycle_map[3], [0, 0, 1, 1]) # 3 is blue np.testing.assert_allclose(color_cycle_map[6], [1, 1, 1, 1]) # 6 is white
def update_points(self): if self.settings.points is not None: self.points_view_button.setVisible(True) if self.points_layer is None or self.points_layer not in self.viewer.layers: self.points_layer = Points( self.settings.points, scale=self.settings.image.normalized_scaling()) self.viewer.add_layer(self.points_layer) else: self.points_layer.data = self.settings.points self.points_layer.scale = self.settings.image.normalized_scaling( ) elif self.points_layer is not None and self.points_layer in self.viewer.layers: self.points_view_button.setVisible(False) self.points_layer.data = np.empty((0, 4))
def test_empty_layer_with_face_colormap(): """Test creating an empty layer where the face color is a colormap See: https://github.com/napari/napari/pull/1069 """ default_properties = {'point_type': np.array([1.5], dtype=float)} layer = Points( properties=default_properties, face_color='point_type', face_colormap='gray', ) assert layer.face_color_mode == 'colormap' # verify the current_face_color is correct face_color = np.array([1, 1, 1, 1]) np.testing.assert_allclose(layer._face.current_color, face_color)
def test_empty_layer_with_edge_colormap(): """ Test creating an empty layer where the face color is a colormap See: https://github.com/napari/napari/pull/1069 """ default_properties = {'point_type': np.array([1.5], dtype=np.float)} layer = Points( properties=default_properties, edge_color='point_type', edge_colormap='grays', ) assert layer.edge_color_mode == 'colormap' # verify the current_face_color is correct edge_color = np.array([1, 1, 1, 1]) assert np.all(layer._current_edge_color == edge_color)
def test_view_data(): coords = np.array([[0, 1, 1], [0, 2, 2], [1, 3, 3], [3, 3, 3]]) layer = Points(coords) layer.dims.set_point(0, 0) assert np.all( layer._view_data == coords[np.ix_([0, 1], layer.dims.displayed)] ) layer.dims.set_point(0, 1) assert np.all( layer._view_data == coords[np.ix_([2], layer.dims.displayed)] ) layer.dims.ndisplay = 3 assert np.all(layer._view_data == coords)
def test_thumbnail_with_n_points_greater_than_max(): """Test thumbnail generation with n_points > _max_points_thumbnail see: https://github.com/napari/napari/pull/934 """ # 2D max_points = Points._max_points_thumbnail * 2 bigger_data = np.random.randint(10, 100, (max_points, 2)) big_layer = Points(bigger_data) big_layer._update_thumbnail() assert big_layer.thumbnail.shape == big_layer._thumbnail_shape # #3D bigger_data_3d = np.random.randint(10, 100, (max_points, 3)) bigger_layer_3d = Points(bigger_data_3d) bigger_layer_3d.dims.ndisplay = 3 bigger_layer_3d._update_thumbnail() assert bigger_layer_3d.thumbnail.shape == bigger_layer_3d._thumbnail_shape
def test_push_button(qtbot): """Make sure the QtModePushButton works with callbacks""" layer = Points() def set_test_prop(): layer.test_prop = True btn = QtModePushButton(layer, 'test_button', slot=set_test_prop, tooltip='tooltip') assert btn.property('mode') == 'test_button' assert btn.toolTip() == 'tooltip' btn.click() qtbot.wait(50) assert layer.test_prop
def test_message(): """Test converting value and coords to message.""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) data[-1] = [0, 0] layer = Points(data) value = layer.get_value() msg = layer.get_message(layer.coordinates, value) assert type(msg) == str layer.data = layer.data + 5 value = layer.get_value() msg = layer.get_message(layer.coordinates, value) assert type(msg) == str
def layers(): """Fixture that supplies a layers list for testing. Returns ------- napari.components.LayerList The desired napari LayerList. """ np.random.seed(0) list_of_layers = [ Image(np.random.rand(20, 20)), Labels(np.random.randint(10, size=(20, 2))), Points(np.random.rand(20, 2)), Shapes(np.random.rand(10, 2, 2)), Vectors(np.random.rand(10, 2, 2)), ] return LayerList(list_of_layers)
def test_add_colormap(attribute): """Test directly adding a vispy Colormap object""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) annotations = {'point_type': _make_cycled_properties([0, 1.5], shape[0])} color_kwarg = f'{attribute}_color' colormap_kwarg = f'{attribute}_colormap' args = {color_kwarg: 'point_type', colormap_kwarg: 'viridis'} layer = Points( data, properties=annotations, **args, ) setattr(layer, f'{attribute}_colormap', get_colormap('gray')) layer_colormap = getattr(layer, f'{attribute}_colormap') assert layer_colormap[0] == 'unknown_colormap'
def test_view_colors(): coords = [[0, 1, 1], [0, 2, 2], [1, 3, 3], [3, 3, 3]] face_color = np.array([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], [0, 0, 1, 1]]) edge_color = np.array([[0, 0, 1, 1], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]]) layer = Points(coords, face_color=face_color, edge_color=edge_color) layer._slice_dims([0, slice(None), slice(None)]) assert np.all(layer._view_face_color == face_color[[0, 1]]) assert np.all(layer._view_edge_color == edge_color[[0, 1]]) layer._slice_dims([1, slice(None), slice(None)]) assert np.all(layer._view_face_color == face_color[[2]]) assert np.all(layer._view_edge_color == edge_color[[2]]) # view colors should return empty array if there are no points layer._slice_dims([2, slice(None), slice(None)]) assert len(layer._view_face_color) == 0 assert len(layer._view_edge_color) == 0
def test_slice_data(): data = [ (10, 2, 4), (10 + 2 * 1e-7, 4, 6), (8, 1, 7), (10.1, 7, 2), (10 - 2 * 1e-7, 1, 6), ] layer = Points(data) assert len(layer._slice_data((8, slice(None), slice(None)))[0]) == 1 assert len(layer._slice_data((10, slice(None), slice(None)))[0]) == 3 assert (len( layer._slice_data((10 + 2 * 1e-12, slice(None), slice(None)))[0]) == 3) assert len(layer._slice_data((10.1, slice(None), slice(None)))[0]) == 1
def layer(request): """Parameterized fixture that supplies a layer for testing. Parameters ---------- request : _pytest.fixtures.SubRequest The pytest request object Returns ------- napari.layers.Layer The desired napari Layer. """ np.random.seed(0) if request.param == 'image': data = np.random.rand(20, 20) return Image(data) elif request.param == 'labels': data = np.random.randint(10, size=(20, 20)) return Labels(data) elif request.param == 'points': data = np.random.rand(20, 2) return Points(data) elif request.param == 'shapes': data = [ np.random.rand(2, 2), np.random.rand(2, 2), np.random.rand(6, 2), np.random.rand(6, 2), np.random.rand(2, 2), ] shape_type = ['ellipse', 'line', 'path', 'polygon', 'rectangle'] return Shapes(data, shape_type=shape_type) elif request.param == 'shapes-rectangles': data = np.random.rand(7, 4, 2) return Shapes(data) elif request.param == 'vectors': data = np.random.rand(20, 2, 2) return Vectors(data) else: return None
def test_blending(): """Test setting layer blending.""" np.random.seed(0) data = 20 * np.random.random((10, 2)) layer = Points(data) assert layer.blending == 'translucent' layer.blending = 'additive' assert layer.blending == 'additive' layer = Points(data, blending='additive') assert layer.blending == 'additive' layer.blending = 'opaque' assert layer.blending == 'opaque'
def test_visiblity(): """Test setting layer visiblity.""" np.random.seed(0) data = 20 * np.random.random((10, 2)) layer = Points(data) assert layer.visible is True layer.visible = False assert layer.visible is False layer = Points(data, visible=False) assert layer.visible is False layer.visible = True assert layer.visible is True
def test_opacity(): """Test setting layer opacity.""" np.random.seed(0) data = 20 * np.random.random((10, 2)) layer = Points(data) assert layer.opacity == 1.0 layer.opacity = 0.5 assert layer.opacity == 0.5 layer = Points(data, opacity=0.6) assert layer.opacity == 0.6 layer.opacity = 0.3 assert layer.opacity == 0.3
def test_is_color_mapped(): shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) annotations = {'point_type': np.array(['A', 'B'] * int((shape[0] / 2)))} layer = Points(data, properties=annotations) # giving the name of an annotation should return True assert layer._is_color_mapped('point_type') # giving a list should return false (i.e., could be an RGBA color) assert not layer._is_color_mapped([1, 1, 1, 1]) # giving an ndarray should return false (i.e., could be an RGBA color) assert not layer._is_color_mapped(np.array([1, 1, 1, 1])) # give an invalid color argument with pytest.raises(ValueError): layer._is_color_mapped((123, 323))
def test_add_color_cycle_to_empty_layer(attribute): """Test adding a point to an empty layer when edge/face color is a color cycle See: https://github.com/napari/napari/pull/1069 """ default_properties = {'point_type': np.array(['A'])} color_cycle = ['red', 'blue'] points_kwargs = { 'properties': default_properties, f'{attribute}_color': 'point_type', f'{attribute}_color_cycle': color_cycle, } layer = Points(**points_kwargs) # verify the current_edge_color is correct expected_color = transform_color(color_cycle[0])[0] color_manager = getattr(layer, f'_{attribute}') current_color = color_manager.current_color np.testing.assert_allclose(current_color, expected_color) # add a point layer.add([10, 10]) props = {'point_type': np.array(['A'])} expected_color = np.array([[1, 0, 0, 1]]) np.testing.assert_equal(layer.properties, props) attribute_color = getattr(layer, f'{attribute}_color') np.testing.assert_allclose(attribute_color, expected_color) # add a point with a new property layer.selected_data = [] layer.current_properties = {'point_type': np.array(['B'])} layer.add([12, 12]) new_color = np.array([0, 0, 1, 1]) expected_color = np.vstack((expected_color, new_color)) new_properties = {'point_type': np.array(['A', 'B'])} attribute_color = getattr(layer, f'{attribute}_color') np.testing.assert_allclose(attribute_color, expected_color) np.testing.assert_equal(layer.properties, new_properties)
class Points2DSuite: """Benchmarks for the Points layer with 2D data""" params = [2**i for i in range(4, 18, 2)] def setup(self, n): np.random.seed(0) self.data = np.random.random((n, 2)) self.layer = Points(self.data) def time_create_layer(self, n): """Time to create layer.""" Points(self.data) def time_refresh(self, n): """Time to refresh view.""" self.layer.refresh() def time_set_view_slice(self, n): """Time to set view slice.""" self.layer._set_view_slice() def time_update_thumbnail(self, n): """Time to update thumbnail.""" self.layer._update_thumbnail() def time_get_value(self, n): """Time to get current value.""" self.layer.get_value() def mem_layer(self, n): """Memory used by layer.""" return self.layer def mem_data(self, n): """Memory used by raw data.""" return self.data
def test_view_colors(): coords = [[0, 1, 1], [0, 2, 2], [1, 3, 3], [3, 3, 3]] face_color = np.array([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], [0, 0, 1, 1]]) edge_color = np.array([[0, 0, 1, 1], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]]) layer = Points(coords, face_color=face_color, edge_color=edge_color) layer.dims.set_point(0, 0) print(layer.face_color) print(layer._view_face_color) assert np.all(layer._view_face_color == face_color[[0, 1]]) assert np.all(layer._view_edge_color == edge_color[[0, 1]]) layer.dims.set_point(0, 1) assert np.all(layer._view_face_color == face_color[[2]]) assert np.all(layer._view_edge_color == edge_color[[2]]) # view colors should return empty array if there are no points layer.dims.set_point(0, 2) assert len(layer._view_face_color) == 0 assert len(layer._view_edge_color) == 0
def test_adding_points(): """Test adding Points data.""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Points(data) assert len(layer.data) == 10 coord = [20, 20] layer.add(coord) assert len(layer.data) == 11 assert np.all(layer.data[10] == coord) # the added point should be selected assert layer.selected_data == {10} # test adding multiple points coords = [[10, 10], [15, 15]] layer.add(coords) assert len(layer.data) == 13 assert np.all(layer.data[11:, :] == coords) # test that the last added points can be deleted layer.remove_selected() np.testing.assert_equal(layer.data, np.vstack((data, coord)))
def test_set_text_with_kwarg_dict(properties): text_kwargs = { 'text': 'type: {point_type}', 'color': [0, 0, 0, 1], 'rotation': 10, 'translation': [5, 5], 'anchor': 'upper_left', 'size': 10, 'visible': True, } shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Points(data, properties=copy(properties), text=text_kwargs) expected_text = ['type: ' + v for v in properties['point_type']] np.testing.assert_equal(layer.text.values, expected_text) for property, value in text_kwargs.items(): if property == 'text': continue layer_value = getattr(layer._text, property) np.testing.assert_equal(layer_value, value)
def create_known_points_layer(): """Create points layer with known coordinates Returns ------- layer : napari.layers.Points Points layer. n_points : int Number of points in the points layer known_non_point : list Data coordinates that are known to contain no points. Useful during testing when needing to guarantee no point is clicked on. """ data = [[1, 3], [8, 4], [10, 10], [15, 4]] known_non_point = [20, 30] n_points = len(data) layer = Points(data, size=1) assert np.all(layer.data == data) assert layer.ndim == 2 assert len(layer.data) == n_points assert len(layer.selected_data) == 0 return layer, n_points, known_non_point
def test_adding_points(): """Test adding Points data.""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Points(data) assert len(layer.data) == 10 coord = [20, 20] layer.add(coord) assert len(layer.data) == 11 assert np.all(layer.data[10] == coord) # the added point should be selected assert layer.selected_data == {10} # test adding multiple points coords = [[10, 10], [15, 15]] layer.add(coords) assert len(layer.data) == 13 assert np.all(layer.data[11:, :] == coords)
def test_changing_modes(): """Test changing modes.""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Points(data) assert layer.mode == 'pan_zoom' assert layer.interactive is True layer.mode = 'add' assert layer.mode == 'add' layer.mode = 'select' assert layer.mode == 'select' assert layer.interactive is False layer.mode = 'pan_zoom' assert layer.mode == 'pan_zoom' assert layer.interactive is True with pytest.raises(ValueError): layer.mode = 'not_a_mode'
def test_adding_properties(attribute): """Test adding properties to an existing layer""" shape = (10, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Points(data) # add properties properties = {'point_type': _make_cycled_properties(['A', 'B'], shape[0])} layer.properties = properties np.testing.assert_equal(layer.properties, properties) # add properties as a dataframe properties_df = pd.DataFrame(properties) layer.properties = properties_df np.testing.assert_equal(layer.properties, properties) # add properties as a dictionary with list values properties_list = { 'point_type': list(_make_cycled_properties(['A', 'B'], shape[0])) } layer.properties = properties_list assert isinstance(layer.properties['point_type'], np.ndarray) # removing a property that was the _*_color_property should give a warning color_manager = getattr(layer, f'_{attribute}') color_manager.color_properties = { 'name': 'point_type', 'values': np.empty(0), 'current_value': 'A', } properties_2 = { 'not_point_type': _make_cycled_properties(['A', 'B'], shape[0]) } with pytest.warns(RuntimeWarning): layer.properties = properties_2
def _make_points_layer(self, points, name, **kwargs): layer = Points(points, name=name, n_dimensional=True, **kwargs) self._init_layer(layer)