Skip to content

Problem with Colorbars, where intensity value 0 refers to no colour (e.g., transparent) #167

@FloskelSalomon

Description

@FloskelSalomon

Dear Robert,

recently I encountered a error message using the stackview.imshow() function.

What I am trying to do is adding a scalebar to the visualisations of my images.

My approach is as follows, I have an image array and copy an empty array only containing "0" in the same sizes as the image array. Afterwards I take the array only containing "0" and turn the values into "1" where I want to have the scale bar. Appropriately calculated using the microns_per_pixel from the metadata of my images. The result is an array containing only "0" and "1".

In a function the code looks like this:

def scale_bar_image(image, 
                    micron_length, 
                    scale_length,
                    scale_color="white",
                    thickness=4,
                    bottom_margin=0.93,
                    left_margin=0.07):                   
    
    """
    Generates an image with a scale bar at the bottom left side
    
    Parameters:
    - image (numpy.ndarray): The input image (2D numpy array) which will be used to generate the scale bar image.
    - micron_length (float): The physical length (in microns) represented by the scale bar.
    - scale_length (float): The desired length of the scale bar in the generated image.
    - scale_color (str, optional): Color of the scale bar. Default is "white".
    - thickness (int, optional): Thickness of the scale bar. Default is 4 pixels.
    - bottom_margin (float, optional): The position of the scale bar from the bottom as a fraction of the image height. Default is 0.93.
    - left_margin (float, optional): The position of the scale bar from the left as a fraction of the image width. Default is 0.07.
    
    Returns:
    - scale_bar (numpy.ndarray): The image with the overlaid scale bar.
    - colormap (matplotlib.colors.ListedColormap): Colormap used for the scale bar.

    Raises:
    - ValueError: If the input image does not have 2 dimensions.
    """
    
    if len(image.shape) != 2:
        raise ValueError("Out of index. 2-dimensional images are required.")
    
    from matplotlib.colors import ListedColormap
    import numpy as np

    # Create a colormap for drawing the scale bar
    # Intensity value 0 is "none" for transparency
    colormap = ListedColormap(["none", scale_color])

    # Create an empty copy of the image where the scale bar should be drawn
    scale_bar = np.copy(image)
    scale_bar[:] = 0

    # Calculate the required pixels that need to be drawn for the scale bar
    length_pixels = int(scale_length / micron_length)

    # Define a margin from the bottom and the left side
    margin_bottom = int(scale_bar.shape[0] * bottom_margin)
    margin_left = int(scale_bar.shape[1] * left_margin)

    # Draw the scale bar 
    # E.g., at the position of the scale bar everything will be turned into "1"
    # Afterwards the scale_bar image can be overlayed with the colormap above
    scale_bar[margin_bottom:margin_bottom + thickness, 
              margin_left:margin_left + length_pixels] = 1
    
    return scale_bar, colormap

Finally I define a colormap using colormap = plt.color.ListedColormap(["none", "white"]). With that approach the value "0" is transparent. With that I was easily able to overlay a scalebar when the imshow function was still implemented in pyclesperanto (check code here).

However, when I am trying to do the same approach in stackview.imshow. I receive the following error message:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[7], line 15
      7 sv.imshow(np.mean(image_c1[0]["wDataCh0"][1:, ...], axis=2),
      8           plot=axs,
      9           colormap="pure_green",
     10           min_display_intensity=p1,
     11           max_display_intensity=p99,
     12           continue_drawing=True)
     14 # Add scale bar on top
---> 15 sv.imshow(scalebar,
     16           plot=axs,
     17           colormap=cmap)
     19 #plt.savefig(plots + 'M1_RR_RGC3_chirp_C1.png', dpi=300, bbox_inches="tight")

File ~/.local/lib/python3.10/site-packages/stackview/_imshow.py:82, in imshow(image, title, labels, min_display_intensity, max_display_intensity, plot, colorbar, colormap, alpha, continue_drawing, axes, cmap, vmin, vmax)
     79 if colormap is None:
     80     colormap = "Greys_r"
---> 82 if colormap.startswith("pure_"):
     83     colormap = create_colormap(colormap)
     85 if labels:

AttributeError: 'ListedColormap' object has no attribute 'startswith'

Do you have any quick solutions to the problem? Also, do you think you will implement a scale bar argument to stackview's imshow function, similar as it can be done in microfilm?

Many thanks in advance,
Florian

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions