def test_z_index(): """Test setting z-index during instantiation.""" shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Shapes(data) assert layer.z_indices == [0] * shape[0] # Instantiate with custom z-index layer = Shapes(data, z_index=4) assert layer.z_indices == [4] * shape[0] # Instantiate with custom z-index list z_index_list = [2, 3] * 5 layer = Shapes(data, z_index=z_index_list) assert layer.z_indices == z_index_list # Add new shape and its z-index new_shape = np.random.random((1, 4, 2)) layer.add(new_shape) assert len(layer.z_indices) == shape[0] + 1 assert layer.z_indices == z_index_list + [4] # Check removing data adjusts colors correctly layer.selected_data = [0, 2] layer.remove_selected() assert len(layer.data) == shape[0] - 1 assert len(layer.z_indices) == shape[0] - 1 assert layer.z_indices == [z_index_list[1]] + z_index_list[3:] + [4]
def test_removing_selected_shapes(): """Test removing selected shapes.""" np.random.seed(0) data = [ 20 * np.random.random((np.random.randint(2, 12), 2)) for i in range(5) ] + list(np.random.random((5, 4, 2))) shape_type = ['polygon'] * 5 + ['rectangle'] * 3 + ['ellipse'] * 2 layer = Shapes(data, shape_type=shape_type) # With nothing selected no points should be removed layer.remove_selected() assert len(layer.data) == len(data) # Select three shapes and remove them layer.selected_data = [1, 7, 8] layer.remove_selected() keep = [0] + list(range(2, 7)) + [9] data_keep = [data[i] for i in keep] shape_type_keep = [shape_type[i] for i in keep] assert len(layer.data) == len(data_keep) assert len(layer.selected_data) == 0 assert np.all([np.all(ld == d) for ld, d in zip(layer.data, data_keep)]) assert layer.ndim == 2 assert np.all( [s == so for s, so in zip(layer.shape_types, shape_type_keep)])
def test_opacity(): """Test setting opacity.""" shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Shapes(data) # Check default opacity value of 0.7 assert layer.opacity == 0.7 # Select data and change opacity of selection layer.selected_data = {0, 1} assert layer.opacity == 0.7 layer.opacity = 0.5 assert layer.opacity == 0.5 # Add new shape and test its width new_shape = np.random.random((1, 4, 2)) layer.selected_data = set() layer.add(new_shape) assert layer.opacity == 0.5 # Instantiate with custom opacity layer2 = Shapes(data, opacity=0.2) assert layer2.opacity == 0.2 # Check removing data shouldn't change opacity layer2.selected_data = {0, 2} layer2.remove_selected() assert len(layer2.data) == shape[0] - 2 assert layer2.opacity == 0.2
def test_color_cycle(attribute, color_cycle): """Test setting edge/face color with a color cycle list""" # create Shapes using list color cycle shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) properties = {'shape_type': _make_cycled_properties(['A', 'B'], shape[0])} shapes_kwargs = { 'properties': properties, f'{attribute}_color': 'shape_type', f'{attribute}_color_cycle': color_cycle, } layer = Shapes(data, **shapes_kwargs) assert layer.properties == properties color_array = transform_color( list(islice(cycle(color_cycle), 0, shape[0])) ) layer_color = getattr(layer, f'{attribute}_color') np.testing.assert_allclose(layer_color, color_array) # Add new shape and test its color new_shape = np.random.random((1, 4, 2)) layer.selected_data = {0} layer.add(new_shape) layer_color = getattr(layer, f'{attribute}_color') assert len(layer_color) == shape[0] + 1 np.testing.assert_allclose( layer_color, np.vstack((color_array, transform_color('red'))), ) # Check removing data adjusts colors correctly layer.selected_data = {0, 2} layer.remove_selected() assert len(layer.data) == shape[0] - 1 layer_color = getattr(layer, f'{attribute}_color') assert len(layer_color) == shape[0] - 1 np.testing.assert_allclose( layer_color, np.vstack((color_array[1], color_array[3:], transform_color('red'))), ) # refresh colors layer.refresh_colors(update_color_mapping=True) # test adding a shape with a new property value layer.selected_data = {} current_properties = layer.current_properties current_properties['shape_type'] = np.array(['new']) layer.current_properties = current_properties new_shape_2 = np.random.random((1, 4, 2)) layer.add(new_shape_2) color_cycle_map = getattr(layer, f'{attribute}_color_cycle_map') assert 'new' in color_cycle_map np.testing.assert_allclose( color_cycle_map['new'], np.squeeze(transform_color(color_cycle[0])) )
def test_color_direct(attribute: str): """Test setting face/edge color directly.""" shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer_kwargs = {f'{attribute}_color': 'black'} layer = Shapes(data, **layer_kwargs) color_array = transform_color(['black'] * shape[0]) current_color = getattr(layer, f'current_{attribute}_color') layer_color = getattr(layer, f'{attribute}_color') assert current_color == 'black' assert len(layer.edge_color) == shape[0] np.testing.assert_allclose(color_array, layer_color) # With no data selected changing color has no effect setattr(layer, f'current_{attribute}_color', 'blue') current_color = getattr(layer, f'current_{attribute}_color') assert current_color == 'blue' np.testing.assert_allclose(color_array, layer_color) # Select data and change edge color of selection selected_data = {0, 1} layer.selected_data = {0, 1} current_color = getattr(layer, f'current_{attribute}_color') assert current_color == 'black' setattr(layer, f'current_{attribute}_color', 'green') colorarray_green = transform_color(['green'] * len(layer.selected_data)) color_array[list(selected_data)] = colorarray_green layer_color = getattr(layer, f'{attribute}_color') np.testing.assert_allclose(color_array, layer_color) # Add new shape and test its color new_shape = np.random.random((1, 4, 2)) layer.selected_data = set() setattr(layer, f'current_{attribute}_color', 'blue') layer.add(new_shape) color_array = np.vstack([color_array, transform_color('blue')]) layer_color = getattr(layer, f'{attribute}_color') assert len(layer_color) == shape[0] + 1 np.testing.assert_allclose(color_array, layer_color) # Check removing data adjusts colors correctly layer.selected_data = {0, 2} layer.remove_selected() assert len(layer.data) == shape[0] - 1 layer_color = getattr(layer, f'{attribute}_color') assert len(layer_color) == shape[0] - 1 np.testing.assert_allclose( layer_color, np.vstack((color_array[1], color_array[3:])), ) # set the color directly setattr(layer, f'{attribute}_color', 'black') color_array = np.tile([[0, 0, 0, 1]], (len(layer.data), 1)) layer_color = getattr(layer, f'{attribute}_color') np.testing.assert_allclose(color_array, layer_color)
def test_face_color(): """Test setting face color.""" shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Shapes(data) assert layer.face_color == 'white' assert len(layer.face_colors) == shape[0] assert layer.face_colors == ['white'] * shape[0] # With no data selected chaning face color has no effect layer.face_color = 'blue' assert layer.face_color == 'blue' assert layer.face_colors == ['white'] * shape[0] # Select data and change face color of selection layer.selected_data = [0, 1] assert layer.face_color == 'white' layer.face_color = 'green' assert layer.face_colors == ['green'] * 2 + ['white'] * (shape[0] - 2) # Add new shape and test its color new_shape = np.random.random((1, 4, 2)) layer.selected_data = [] layer.face_color = 'blue' layer.add(new_shape) assert len(layer.face_colors) == shape[0] + 1 assert layer.face_colors == ['green'] * 2 + ['white'] * (shape[0] - 2) + [ 'blue' ] # Instantiate with custom face color layer = Shapes(data, face_color='red') assert layer.face_color == 'red' # Instantiate with custom face color list col_list = ['red', 'green'] * 5 layer = Shapes(data, face_color=col_list) assert layer.face_color == 'white' assert layer.face_colors == col_list # Add new point and test its color layer.face_color = 'blue' layer.add(new_shape) assert len(layer.face_colors) == shape[0] + 1 assert layer.face_colors == col_list + ['blue'] # Check removing data adjusts colors correctly layer.selected_data = [0, 2] layer.remove_selected() assert len(layer.data) == shape[0] - 1 assert len(layer.face_colors) == shape[0] - 1 assert layer.face_colors == [col_list[1]] + col_list[3:] + ['blue']
def test_remove_selected_with_derived_text(): """See https://github.com/napari/napari/issues/3504""" shapes = np.random.rand(3, 4, 2) properties = {'class': np.array(['A', 'B', 'C'])} layer = Shapes(shapes, properties=properties, text='class') vispy_layer = VispyShapesLayer(layer) text_node = vispy_layer._get_text_node() np.testing.assert_array_equal(text_node.text, ['A', 'B', 'C']) layer.selected_data = {1} layer.remove_selected() np.testing.assert_array_equal(text_node.text, ['A', 'C'])
def test_opacities(): """Test setting opacities.""" shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Shapes(data) # Check default opacity value of 0.7 assert layer.opacity == 0.7 assert len(layer.opacities) == shape[0] assert layer.opacities == [0.7] * shape[0] # With no data selected chaning opacity has no effect layer.opacity = 1 assert layer.opacity == 1 assert layer.opacities == [0.7] * shape[0] # Select data and change opacity of selection layer.selected_data = [0, 1] assert layer.opacity == 0.7 layer.opacity = 0.5 assert layer.opacities == [0.5] * 2 + [0.7] * (shape[0] - 2) # Add new shape and test its width new_shape = np.random.random((1, 4, 2)) layer.selected_data = [] layer.opacity = 0.3 layer.add(new_shape) assert layer.opacities == [0.5] * 2 + [0.7] * (shape[0] - 2) + [0.3] # Instantiate with custom opacity layer = Shapes(data, opacity=0.2) assert layer.opacity == 0.2 # Instantiate with custom opacity list opacity_list = [0.1, 0.4] * 5 layer = Shapes(data, opacity=opacity_list) assert layer.opacity == 0.7 assert layer.opacities == opacity_list # Add new shape and test its opacity layer.opacity = 0.6 layer.add(new_shape) assert len(layer.opacities) == shape[0] + 1 assert layer.opacities == opacity_list + [0.6] # Check removing data adjusts opacities correctly layer.selected_data = [0, 2] layer.remove_selected() assert len(layer.data) == shape[0] - 1 assert len(layer.opacities) == shape[0] - 1 assert layer.opacities == [opacity_list[1]] + opacity_list[3:] + [0.6]
def test_edge_width(): """Test setting edge width.""" shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Shapes(data) assert layer.edge_width == 1 assert len(layer.edge_widths) == shape[0] assert layer.edge_widths == [1] * shape[0] # With no data selected chaning edge width has no effect layer.edge_width = 2 assert layer.edge_width == 2 assert layer.edge_widths == [1] * shape[0] # Select data and change edge color of selection layer.selected_data = [0, 1] assert layer.edge_width == 1 layer.edge_width = 3 assert layer.edge_widths == [3] * 2 + [1] * (shape[0] - 2) # Add new shape and test its width new_shape = np.random.random((1, 4, 2)) layer.selected_data = [] layer.edge_width = 4 layer.add(new_shape) assert layer.edge_widths == [3] * 2 + [1] * (shape[0] - 2) + [4] # Instantiate with custom edge width layer = Shapes(data, edge_width=5) assert layer.edge_width == 5 # Instantiate with custom edge width list width_list = [2, 3] * 5 layer = Shapes(data, edge_width=width_list) assert layer.edge_width == 1 assert layer.edge_widths == width_list # Add new shape and test its color layer.edge_width = 4 layer.add(new_shape) assert len(layer.edge_widths) == shape[0] + 1 assert layer.edge_widths == width_list + [4] # Check removing data adjusts colors correctly layer.selected_data = [0, 2] layer.remove_selected() assert len(layer.data) == shape[0] - 1 assert len(layer.edge_widths) == shape[0] - 1 assert layer.edge_widths == [width_list[1]] + width_list[3:] + [4]
def test_properties(properties): shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) layer = Shapes(data, properties=copy(properties)) np.testing.assert_equal(layer.properties, properties) current_prop = {'shape_type': np.array(['B'])} assert layer.current_properties == current_prop # test removing shapes layer.selected_data = {0, 1} layer.remove_selected() remove_properties = properties['shape_type'][2::] assert len(layer.properties['shape_type']) == (shape[0] - 2) assert np.all(layer.properties['shape_type'] == remove_properties) # test selection of properties layer.selected_data = {0} selected_annotation = layer.current_properties['shape_type'] assert len(selected_annotation) == 1 assert selected_annotation[0] == 'A' # test adding shapes with properties new_data = np.random.random((1, 4, 2)) new_shape_type = ['rectangle'] layer.add(new_data, shape_type=new_shape_type) add_properties = np.concatenate((remove_properties, ['A']), axis=0) assert np.all(layer.properties['shape_type'] == add_properties) # test copy/paste layer.selected_data = {0, 1} layer._copy_data() assert np.all(layer._clipboard['properties']['shape_type'] == ['A', 'B']) layer._paste_data() paste_properties = np.concatenate((add_properties, ['A', 'B']), axis=0) assert np.all(layer.properties['shape_type'] == paste_properties) # test updating a property layer.mode = 'select' layer.selected_data = {0} new_property = {'shape_type': np.array(['B'])} layer.current_properties = new_property updated_properties = layer.properties assert updated_properties['shape_type'][0] == 'B'
def test_color_colormap(attribute): """Test setting edge/face color with a colormap""" # create Shapes using with a colormap shape = (10, 4, 2) np.random.seed(0) data = 20 * np.random.random(shape) properties = {'shape_type': _make_cycled_properties([0, 1.5], shape[0])} shapes_kwargs = { 'properties': properties, f'{attribute}_color': 'shape_type', f'{attribute}_colormap': 'gray', } layer = Shapes(data, **shapes_kwargs) assert layer.properties == properties color_mode = getattr(layer, f'{attribute}_color_mode') assert color_mode == 'colormap' color_array = transform_color(['black', 'white'] * int((shape[0] / 2))) attribute_color = getattr(layer, f'{attribute}_color') assert np.all(attribute_color == color_array) # change the color cycle - face_color should not change setattr(layer, f'{attribute}_color_cycle', ['red', 'blue']) attribute_color = getattr(layer, f'{attribute}_color') assert np.all(attribute_color == color_array) # Add new shape and test its color new_shape = np.random.random((1, 4, 2)) layer.selected_data = {0} layer.add(new_shape) attribute_color = getattr(layer, f'{attribute}_color') assert len(attribute_color) == shape[0] + 1 np.testing.assert_allclose( attribute_color, np.vstack((color_array, transform_color('black'))), ) # Check removing data adjusts colors correctly layer.selected_data = {0, 2} layer.remove_selected() assert len(layer.data) == shape[0] - 1 attribute_color = getattr(layer, f'{attribute}_color') assert len(attribute_color) == shape[0] - 1 np.testing.assert_allclose( attribute_color, np.vstack(( color_array[1], color_array[3:], transform_color('black'), )), ) # adjust the clims setattr(layer, f'{attribute}_contrast_limits', (0, 3)) layer.refresh_colors(update_color_mapping=False) attribute_color = getattr(layer, f'{attribute}_color') np.testing.assert_allclose(attribute_color[-2], [0.5, 0.5, 0.5, 1]) # change the colormap new_colormap = 'viridis' setattr(layer, f'{attribute}_colormap', new_colormap) attribute_colormap = getattr(layer, f'{attribute}_colormap') assert attribute_colormap[1] == get_colormap(new_colormap)