Exemplo n.º 1
0
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
Exemplo n.º 2
0
def test_text_from_property_fstring(properties):
    """Test setting text with an f-string from the property value"""
    shape = (10, 4, 2)
    np.random.seed(0)
    data = 20 * np.random.random(shape)
    layer = Shapes(data,
                   properties=copy(properties),
                   text='type: {shape_type}')

    expected_text = ['type: ' + v for v in properties['shape_type']]
    np.testing.assert_equal(layer.text.values, expected_text)

    # test updating the text
    layer.text = 'type-ish: {shape_type}'
    expected_text_2 = ['type-ish: ' + v for v in properties['shape_type']]
    np.testing.assert_equal(layer.text.values, expected_text_2)

    # copy/paste
    layer.selected_data = {0}
    layer._copy_data()
    layer._paste_data()
    expected_text_3 = expected_text_2 + ['type-ish: A']
    np.testing.assert_equal(layer.text.values, expected_text_3)

    # add shape
    layer.selected_data = {0}
    new_shape = np.random.random((1, 4, 2))
    layer.add(new_shape)
    expected_text_4 = expected_text_3 + ['type-ish: A']
    np.testing.assert_equal(layer.text.values, expected_text_4)
Exemplo n.º 3
0
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]))
    )
Exemplo n.º 4
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)
Exemplo n.º 5
0
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']
Exemplo n.º 6
0
def test_selecting_shapes():
    """Test selecting shapes."""
    data = 20 * np.random.random((10, 4, 2))
    np.random.seed(0)
    layer = Shapes(data)
    layer.selected_data = [0, 1]
    assert layer.selected_data == [0, 1]

    layer.selected_data = [9]
    assert layer.selected_data == [9]

    layer.selected_data = []
    assert layer.selected_data == []
Exemplo n.º 7
0
def test_selecting_shapes():
    """Test selecting shapes."""
    data = 20 * np.random.random((10, 4, 2))
    np.random.seed(0)
    layer = Shapes(data)
    layer.selected_data = {0, 1}
    assert layer.selected_data == {0, 1}

    layer.selected_data = {9}
    assert layer.selected_data == {9}

    layer.selected_data = set()
    assert layer.selected_data == set()
Exemplo n.º 8
0
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]
Exemplo n.º 9
0
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]
Exemplo n.º 10
0
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)])
Exemplo n.º 11
0
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]
Exemplo n.º 12
0
def test_interaction_box():
    """Test the creation of the interaction box."""
    shape = (10, 4, 2)
    np.random.seed(0)
    data = 20 * np.random.random(shape)
    layer = Shapes(data)
    assert layer._selected_box == None

    layer.selected_data = [0]
    assert len(layer._selected_box) == 10

    layer.selected_data = [0, 1]
    assert len(layer._selected_box) == 10

    layer.selected_data = []
    assert layer._selected_box == None
Exemplo n.º 13
0
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'
Exemplo n.º 14
0
def test_delete():
    # Test on three four corner rectangle
    layer = Shapes(20 * np.random.random((3, 4, 2)))
    layer.mode = 'direct'

    assert len(layer.data) == 3
    layer.selected_data = {0, 1}

    key_bindings.delete_selected(layer)
    assert len(layer.data) == 1
Exemplo n.º 15
0
def test_copy_and_paste():
    """Test copying and pasting selected shapes."""
    shape = (10, 4, 2)
    np.random.seed(0)
    data = 20 * np.random.random(shape)
    layer = Shapes(data)
    # Clipboard starts empty
    assert layer._clipboard == {}

    # Pasting empty clipboard doesn't change data
    layer._paste_data()
    assert len(layer.data) == 10

    # Copying with nothing selected leave clipboard empty
    layer._copy_data()
    assert layer._clipboard == {}

    # Copying and pasting with two shapes selected adds to clipboard and data
    layer.selected_data = {0, 1}
    layer._copy_data()
    layer._paste_data()
    assert len(layer._clipboard) == 2
    assert len(layer.data) == shape[0] + 2
    assert np.all(
        [np.all(a == b) for a, b in zip(layer.data[:2], layer.data[-2:])]
    )

    # Pasting again adds two more points to data
    layer._paste_data()
    assert len(layer.data) == shape[0] + 4
    assert np.all(
        [np.all(a == b) for a, b in zip(layer.data[:2], layer.data[-2:])]
    )

    # Unselecting everything and copying and pasting will empty the clipboard
    # and add no new data
    layer.selected_data = set()
    layer._copy_data()
    layer._paste_data()
    assert layer._clipboard == {}
    assert len(layer.data) == shape[0] + 4
Exemplo n.º 16
0
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'])
Exemplo n.º 17
0
def test_move_to_back():
    """Test moving shapes to back."""
    shape = (10, 4, 2)
    np.random.seed(0)
    data = 20 * np.random.random(shape)
    z_index_list = [2, 3] * 5
    layer = Shapes(data, z_index=z_index_list)
    assert layer.z_indices == z_index_list

    # Move selected shapes to front
    layer.selected_data = [0, 2]
    layer.move_to_back()
    assert layer.z_indices == [1] + [z_index_list[1]] + [1] + z_index_list[3:]
Exemplo n.º 18
0
def test_copy_paste():
    # Test on three four corner rectangle
    layer = Shapes(20 * np.random.random((3, 4, 2)))
    layer.mode = 'direct'

    assert len(layer.data) == 3
    assert layer._clipboard == {}
    layer.selected_data = {0, 1}

    key_bindings.copy(layer)
    assert len(layer.data) == 3
    assert len(layer._clipboard) == 5

    key_bindings.paste(layer)
    assert len(layer.data) == 5
    assert len(layer._clipboard) == 5
Exemplo n.º 19
0
def test_value():
    """Test getting the value of the data at the current coordinates."""
    shape = (10, 4, 2)
    np.random.seed(0)
    data = 20 * np.random.random(shape)
    data[-1, :] = [[0, 0], [0, 10], [10, 0], [10, 10]]
    layer = Shapes(data)
    value = layer.get_value((0, 0))
    assert value == (9, None)

    layer.mode = 'select'
    layer.selected_data = [9]
    value = layer.get_value((0, 0))
    assert value == (9, 7)

    layer = Shapes(data + 5)
    value = layer.get_value((0, 0))
    assert value == (None, None)
Exemplo n.º 20
0
def test_add_color_cycle_to_empty_layer(attribute):
    """ Test adding a shape to an empty layer when edge/face color is a color cycle

    See: https://github.com/napari/napari/pull/1069
    """
    default_properties = {'shape_type': np.array(['A'])}
    color_cycle = ['red', 'blue']
    shapes_kwargs = {
        'properties': default_properties,
        f'{attribute}_color': 'shape_type',
        f'{attribute}_color_cycle': color_cycle,
    }
    layer = Shapes(**shapes_kwargs)

    # verify the current_edge_color is correct
    expected_color = transform_color(color_cycle[0])
    current_color = getattr(layer, f'_current_{attribute}_color')
    np.testing.assert_allclose(current_color, expected_color)

    # add a shape
    np.random.seed(0)
    new_shape = 20 * np.random.random((1, 4, 2))
    layer.add(new_shape)
    props = {'shape_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 shape with a new property
    layer.selected_data = []
    layer.current_properties = {'shape_type': np.array(['B'])}
    new_shape_2 = 20 * np.random.random((1, 4, 2))
    layer.add(new_shape_2)
    new_color = np.array([0, 0, 1, 1])
    expected_color = np.vstack((expected_color, new_color))
    new_properties = {'shape_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)
Exemplo n.º 21
0
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)