YMa-lab / CARD

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Overlay with H&E image

amachadolopez opened this issue · comments

Hi!

First of all, thanks for the awesome package. I am analyzing some data we generated using 10x Visium and I was wondering if there is any way to overlay CARD proportions with the original H&E image I have for the tissue? (e.g. as in Figure 3D in your Nat Biotechnol. paper)

So far I have added CARD as an additional Assay in a Seurat object with the images but this does not seem too efficient, and besides that, I cannot do it for the refined spatial map obtained with CARD.imputation.

Thank you in advance,
Alba

Hi @amachadolopez,

Sorry about the delayed response.

For the figure3D, I actually using python functions to plot it, based on the cell type proportions extracted from CARD. Here is the python function that I used to plot each cell type proportion.

"""

"""
import sys


import os
import numpy as np
import pandas as pd
import matplotlib as mpl
import random
mpl.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import transforms
from matplotlib.colors import ListedColormap
import numpy as np
import seaborn as sns
import matplotlib.colors as clr
import statistics 
from matplotlib import cm

color_map = ["red", "green", "blue", "orange", "cyan", "yellow", "orchid", 
             "saddlebrown", "darkcyan", "gray", "darkred", "darkgreen", "darkblue", 
             "antiquewhite", "bisque", "black", "slategray", "gold", "floralwhite",
             "aliceblue", "plum", "cadetblue", "coral", "olive", "khaki", "lightsalmon"]


def scatter_plot(x_points, y_points, output=None, colors=None,
                 alignment=None, cmap=None, title='Scatter', xlabel='X', 
                 ylabel='Y', image=None, alpha=1.0, size=10, 
                 show_legend=True, show_color_bar=False, vmin=None, vmax=None):
    """ 
    This function makes a scatter plot of a set of points (x,y).
    The alignment matrix is optional to transform the coordinates
    of the points to pixel space.
    If an image is given the image will be set as background.
    The plot will always use a predefine set of colors.
    The plot will be written to a file.
    :param x_points: a list of x coordinates
    :param y_points: a list of y coordinates
    :param output: the name/path of the output file
    :param colors: a color int value label for each point (can be None), here we use cell type proportion
    :param alignment: an alignment 3x3 matrix (pass identity to not align)
    :param cmap: Matplotlib color mapping object (optional)
    :param title: the title for the plot
    :param xlabel: the name of the X label
    :param ylabel: the name of the Y label
    :param image: the path to the image file
    :param alpha: the alpha transparency level for the dots
    :param size: the size of the dots
    :param show_legend: True draws a legend with the unique colors
    :param show_color_bar: True draws the color bar distribution
    :raises: RuntimeError
    """
    # Plot spots with the color class in the tissue image
    fig, a = plt.subplots()
    base_trans = a.transData
    # Extend (left, right, bottom, top)
    # The location, in data-coordinates, of the lower-left and upper-right corners. 
    # If None, the image is positioned such that the pixel centers fall on zero-based (row, column) indices.
    extent_size = [1,33,35,1]
    # If alignment is None we re-size the image to chip size (1,1,33,35)
    # Otherwise we keep the image intact and apply the 3x3 transformation
    if alignment is not None and not np.array_equal(alignment, np.identity(3)):
        base_trans = transforms.Affine2D(matrix = alignment) + base_trans
        extent_size = None
    # We convert the list of color int values to color labels
    color_values = None
    unique_colors = set(colors)
    #cNorm  = [(float(i)-min(colors))/(max(colors)-min(colors)) for i in colors]
    cNorm = colors
    #cmap = plt.cm.get_cmap('BuPu')
    x,y,c = zip(*np.random.rand(30,3)*4-2)
    #colors = ["#80abaa","#f9e7d2","#c79cba"]
    #colors = ["lavender","#FFAEB9","#FF4500"]
    #tuples = list(zip(map(cNorm,colors), colors))
    colors = ["#453781FF","#B8DE29FF","#FDE725FF"]
    cmap = clr.LinearSegmentedColormap.from_list("", colors,N=256)
    cmap = plt.cm.get_cmap('RdPu')
    sc = a.scatter(x_points, y_points, c=cNorm, edgecolor="none",
                   cmap=cmap, s=size, transform=base_trans, alpha=alpha,
                   vmin=0, vmax=1.0)
    # Plot the image
    if image is not None and os.path.isfile(image):
        img = plt.imread(image)
        a.imshow(img, extent=extent_size)
    # Add labels and title
    a.set_xlabel(xlabel)
    a.set_ylabel(ylabel)
    a.set_title(title, size=10)
    # Add legend
    if color_values is not None and show_legend:
        a.legend([plt.Line2D((0,1),(0,0), color=x) for x in cmap], 
                 unique_colors, loc="lower left",markerscale=1.0, 
                 ncol=1, scatterpoints=1, fontsize=7)
        a.legend(loc="lower left")
    # Add color bar
    #if colors is not None and show_color_bar:
    #    a = plt.colorbar(sc,orientation='horizontal',fraction=0.03,pad=0.13,aspect=10,ticks=[0,0.25,0.5,0.75,1.0])
    #    a.ax.tick_params(labelsize=7)  # set
    # Save or show the plot
    if output is not None:
        fig.savefig("{}.png".format(os.path.splitext(os.path.basename(output))[0]), 
                    format='png', dpi=300)
    else:
        fig.show()

In this function, x_points and y_points represent the list of coordinates correspondingly, output is the file, i.e. output = "CARD_withHE.pdf", colors is the vector of cell type proportions. alignment_matrix is from the website: https://www.spatialresearch.org/resources-published-datasets/doi-10-1126science-aaf2403/ since I have to match the spot coordinates to image pixel coordinates.

Besides this, I know some R package may have some functions to overlay the image, but not sure if it can be directly used for plotting the cell type proportions here. For example: the STUtility: https://rdrr.io/github/jbergenstrahle/STUtility/man/FeatureOverlay.html, it takes the input from a Seurat object.

Best,
Ying

Hi Ying,

Thank you so much for such a detailed reply. I will try with the STUtilty package since I usually work in R, but otherwise your python function will surely be really helpful!

Again, thanks for the package and your time.

Best,
Alba