Useful Functions in Python
Recommendation: 【Python】 Python index, 【Bioinformatics】 Bioinformatics analysis index
1. Overview
2. Basics
7. Data Science
10. Bioinformatics
c. A collection of main functions useful in R
1. Overview
⑴ Functions defined below can be called as follows. Calling .py from GitHub to python.
### Reference : https://changhsinlee.com/colab-import-python/
import requests
# Save datagenerators as file to colab working directory
# If you are using GitHub, make sure you get the "Raw" version of the code
url = 'https://github.com/JB243/nate9389/blob/main/Python/A_Collection_of_Useful_Functions_in_Python.py?raw=true'
r = requests.get(url)
# make sure your filename is the same as how you want to import
with open('A_Collection_of_Useful_Functions_in_Python.py', 'w') as f:
f.write(r.text)
# now we can import
from A_Collection_of_Useful_Functions_in_Python import SUM
### Warning
# Only SUM is implemented, but it seems to be implemented only at the beginning
SUM(2,6)
⑵ Functions defined below can be used as follows. Python uses ‘def’ when defining a function, like C language.
def SUM(a, b):
return a+b
SUM(1,2)
# 3
2. Basics
⑴ Code that you must remember
① Type check:
type(x)
② Length:
len(x)
③ Dimension (e.g.,
numpy.ndarray
,cv2.imread
):x.shape
④ Dimension (e.g.,
PIL.PngImagePlugin.PngImageFile
,PIL.Image.open
):x.size
⑤ Casting into
int
:.astype(int)
⑥ A set of unique elements in a given array:
.unique()
⑦ Wait for x seconds:
time.sleep(x)
⑧ An easy way to create a for loop with an index when you have a list:
for index, e in enumerate(my_list): ...
⑨ Split the given sentence by ‘_’ and take only the front part:
myStr.split('')[0]
⑵ A function that fills the natural number with zero to make it a total of five digits
n = 55
idx = str(n).zfill(5)
⑶ All lowercase letters or all uppercase letters for a given string
_str = "ABCdef"
_str.lower()
# 'abcdef'
_str.upper()
# 'ABCDEF'
⑷ Whether the given string includes a partial string
a = "ABCD"
a.startswith('AB')
# TRUE
''' if a is not string object
a.str.startswith('AB')
# TRUE
'''
⑸ Whether a given string ends with a specific string
a = "ABCD"
a.endswith('CD')
# TRUE
⑹ Whether the given string (give_str) contains a specific string (partial_str)
def is_contain(given_str, partial_str):
s = ''
for char in given_str:
s = s + char
if s.endswith(partial_str):
return True
return False
⑺ Function that removes the first few characters from a given string (str) and returns them
def str_omit_forward(_str, n):
return _str[n:]
⑻ A function that removes the last few characters from a given string (str) and returns them
def str_omit_backward(_str, n):
return _str[:-n]
⑼ Whether a given element (e) is included in the list (l)
def is_element_in_list(e, l):
for i in range(len(l)):
if e == l[i]:
return True
return False
⑽ Function that outputs which element (e) is in the list (l)
def where_element_in_list(e, l):
for i in range(len(l)):
if e == l[i]:
return i
return -1
⑾ Function that outputs the intersection of two lists
def is_element_in_list(e, l):
for i in range(len(l)):
if e == l[i]:
return True
return False
def my_intersection(l1, l2):
l = []
flag = 0
for i in range(len(l1)):
if is_element_in_list(l1[i], l2):
l[flag] = l1[i]
flag = flag + 1
return l
⑿ Date notation conversion function: It converts ‘Mar 02, 2018’ to 20180301, as an example.
def convert_date(_str):
def month_to_num(_str):
if _str == 'Jan':
return '01'
if _str == 'Feb':
return '02'
if _str == 'Mar':
return '03'
if _str == 'Apr':
return '04'
if _str == 'May':
return '05'
if _str == 'Jun':
return '06'
if _str == 'Jul':
return '07'
if _str == 'Aug':
return '08'
if _str == 'Sep':
return '09'
if _str == 'Oct':
return '10'
if _str == 'Nov':
return '11'
if _str == 'Dec':
return '12'
flag = 0
s1 = '' # Mar
s2 = '' # 01
s3 = '' # 2018
for char in _str:
## closing
if char == ' ' and flag == 0:
flag = 1
elif char == ',' and flag == 1:
flag = 2
elif char == ' ' and flag == 2:
flag = 3
## propagation
elif flag == 0:
s1 = s1 + char
elif flag == 1:
s2 = s2 + char
elif flag == 3:
s3 = s3 + char
return str(s3) + str(month_to_num(s1)) + str(s2)
⒀ Creating a data frame with two lists
import pandas as pd
v1 = []
v2 = []
...
df = pd.DataFrame(
{'Column1': v1,
'Column2': v2
})
⒁ Getting the source code of a function
import inspect
lines = inspect.getsource(MyFunc)
print(lines)
⒂ Receive variable names as strings and dynamically utilize them
def set_variable_from_string(variable_name, value):
globals()[variable_name] = value
def get_variable_value_from_string(variable_name):
return globals().get(variable_name, None)
# Set variable name to string
var_name = "sample_variable"
# Use string to create variables
set_variable_from_string(var_name, 12345)
# Get value of variable using string
value = get_variable_value_from_string(var_name)
print(f"{var_name} = {value}")
3. Mathematics Functions
⑴ Code to obtain the greatest common divisor
def gcd(x: int, y: int) -> int:
while y:
x, y = y, x % y
return x
4. Fild Input and Output
⑴ csv file read
import pandas as pd
x = pd.read_csv("FILE.csv", header=None, names= ['barcodes','tissue','row','col','imgrow','imgcol'])
⑵ Text file read
import csv
import sys
def read_txt(txt_dir):
l = []
f = open(txt_dir, 'r', encoding = 'utf-8')
for line in csv.reader(f):
### if you want elements of list ###
l.append(line)
### if you want elements of str ###
# l.append(''.join(line))
f.close()
return l
⑶ Switch to a data frame and write to a .csv: Use iloc to get the exact rows and columns from pandas.DataFrame
# https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html
pandas.DataFrame(MY_VARIABLE).to_csv(FILE_PATH)
⑷ Read all .csv files in the directory
import glob
print(glob.glob("./dir/*.csv"))
⑸ Creating, reading, and grouping HDF (.h5) files
⑹ Website crawling (Reference)
import io
import requests
import pandas as pd
url = 'https://typeset.io/search?q=Microbiome'
github_session = requests.Session()
download = github_session.get(url).content
print(download)
⑺ Merging PDF files (ref)
from PyPDF2 import PdfWriter
merger = PdfWriter()
for pdf in ['pdf_1.pdf', 'pdf_2.pdf', 'pdf_3.pdf']:
merger.append(pdf)
merger.write(target + ".pdf")
merger.close()
⑻ HTML to MarkDown
!pip install html2text
import html2text
def html_to_markdown(html_content):
# Create an html2text converter object
h = html2text.HTML2Text()
h.ignore_links = False
# Convert the HTML to Markdown
markdown_content = h.handle(html_content)
return markdown_content
# Example Usage
html_code = """
<h1>Hello World</h1>
<p>This is a paragraph. <a href="https://example.com">Here is a link</a>.</p>
"""
markdown_code = html_to_markdown(html_code)
print(markdown_code)
⑼ MarkDown to HTML
import markdown
def md_to_html(md_file_path, html_file_path):
"""
Convert a Markdown file to an HTML file.
:param md_file_path: Path to the input Markdown file.
:param html_file_path: Path to the output HTML file.
"""
# Read the Markdown file
with open(md_file_path, 'r', encoding='utf-8') as file:
md_content = file.read()
# Convert Markdown to HTML
html_content = markdown.markdown(md_content)
# Write the HTML content to a file
with open(html_file_path, 'w', encoding='utf-8') as file:
file.write(html_content)
# Example usage
md_to_html('example.md', 'example.html')
⑽ Merge all PDF files in the given folder (in alphabetical order)
import os
import glob
import fitz # PyMuPDF library
def merge_pdfs(input_folder, output_path):
# input_folder: Directory containing PDF files
# output_path: Path for the output PDF file
# Retrieve list of PDF files from the input folder
pdf_files = glob.glob(os.path.join(input_folder, '*.pdf'))
print(pdf_files)
# Sort in alphabetical order
pdf_files.sort()
# Create PyMuPDF's PdfWriter object
pdf_writer = fitz.open()
# Merge all PDF files
for pdf_file in pdf_files:
pdf_document = fitz.open(pdf_file)
for page_num in range(pdf_document.page_count):
page = pdf_document[page_num]
pdf_writer.insert_pdf(pdf_document, from_page=page_num, to_page=page_num)
# Save the output PDF file
pdf_writer.save(output_path)
pdf_writer.close()
# Print completion message for file merging
print(f'PDF files have been merged into {output_path}.')
# Set the input folder and output file path
input_folder = r'D:/1'
output_path = r'D:/output.pdf'
# Execute PDF file merging
merge_pdfs(input_folder, output_path)
⑾ Collect all download links from a specific HTML document and then download the files
import requests
from bs4 import BeautifulSoup
import os
def download_file(url, local_filename):
"""Function to download a file from a given URL."""
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return local_filename
# Read the modified HTML file
with open('modified_html_file.html', 'r') as file:
html_content = file.read()
# Parse the HTML
soup = BeautifulSoup(html_content, 'html.parser')
# Find all 'a' tags with href attributes
links = soup.find_all('a', href=True)
# Folder to save files
save_folder = 'out' ## You must make this folder
os.makedirs(save_folder, exist_ok=True)
# Download each file
for link in links:
url = link['href']
filename = os.path.join(save_folder, url.split('/')[-1])
print(f"Downloading {url}...")
download_file(url, filename)
print("Download completed.")
⑿ Code to split a GIF file into multiple PNG files.
from PIL import Image
import os
def gif_to_png(gif_filename, output_folder):
# Ensure the output folder exists
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Open the GIF file
with Image.open(gif_filename) as img:
# Loop over each frame in the GIF
for frame in range(img.n_frames):
# Select the frame
img.seek(frame)
# Save the frame as a PNG file
frame_filename = f"{output_folder}/frame_{frame}.png"
img.save(frame_filename)
print(f"Saved {frame_filename}")
# Example usage
gif_filename = 'img.gif' # Replace with your GIF file path
output_folder = 'out' # Folder where PNG files will be saved
gif_to_png(gif_filename, output_folder)
⒀ Code to output the directory tree structure
import os
def print_tree(directory, prefix=''):
"""Recursively prints a tree diagram of the directory structure."""
files = sorted(os.listdir(directory))
for i, file in enumerate(files):
path = os.path.join(directory, file)
is_last = i == (len(files) - 1)
print(f"{prefix}{'└── ' if is_last else '├── '}{file}")
if os.path.isdir(path):
# Add custom annotations here if file/directory matches certain criteria
new_prefix = prefix + (' ' if is_last else '│ ')
print_tree(path, new_prefix)
# Replace '/path/to/directory' with the actual directory path you want to visualize
print_tree('/path/to/directory')
⒁ Split a PDF file into separate PDF files for each page
import PyPDF2
def split_pdf_pages(input_pdf_path, output_folder):
# Open the PDF file
with open(input_pdf_path, "rb") as file:
reader = PyPDF2.PdfReader(file)
num_pages = len(reader.pages)
# Save each page as an independent PDF file
for i in range(num_pages):
writer = PyPDF2.PdfWriter()
writer.add_page(reader.pages[i])
output_filename = f"{output_folder}/page_{i+1}.pdf"
with open(output_filename, "wb") as output_file:
writer.write(output_file)
print(f"Saved: {output_filename}")
# Example usage of the function
split_pdf_pages("path_to_your_input.pdf", "output_directory")
5. Data Structure
⑴ Overview
① Array
③ Stack
④ Queue
⑤ Tree
⑥ Graph
⑦ Hash
⑧ Set
⑵ Counting Island Algorithm: A function that counts the number of islands when 1 is land and 0 is water in the world, which is a list of M × N
def counting_island(world: list)->int:
class Node():
def __init__(self, i, j):
self.i = i
self.j = j
class undirected_graph():
def __init__(self, V:list, E:list)->None:
self.V = V[:]
self.neighbor = {}
for v in V:
self.neighbor[v] = []
for (v,w) in E:
self.neighbor[v].append(w)
def DFT_preorder(self)->int:
count = 0
if self.V:
visited = {}
for v in self.V:
visited[v]=False
for v in self.V:
if not visited[v]:
count += 1
self.__DFT__preorderHelp(visited, v)
return count
def __DFT__preorderHelp(self, visited: list, v: int)->None:
if not visited[v]:
visited[v] = True
for w in self.neighbor[v]:
self.__DFT__preorderHelp(visited, w)
V = []
E = []
for i in range(len(world)):
for j in range(len(world[0])):
if world[i][j] == 1:
V.append(Node(i, j))
for v in V:
for w in V:
if w.i == v.i and w.j == v.j - 1:
E.append((v,w))
if w.i == v.i and w.j == v.j + 1:
E.append((v,w))
if w.i == v.i - 1 and w.j == v.j:
E.append((v,w))
if w.i == v.i + 1 and w.j == v.j:
E.append((v,w))
g = undirected_graph(V, E)
return g.DFT_preorder()
world1 = [[1,1,1,1,0], [1,0,0,1,0], [1,1,0,1,0], [1,1,0,0,0]]
counting_island(world1) # 1
world2 = [[1,1,0,0,0], [1,1,0,0,0], [0,0,1,1,0], [0,0,0,0,1]]
counting_island(world2) # 3
world3 = [[0,1,0,1,0,1]]
counting_island(world3) # 3
6. Image Processing
⑴ Basic graph generation codes
① A function that draws a scatter plot given x, y
plt.scatter(x, y, alpha = 0.01)
plt.xlabel('brightness of img1')
plt.ylabel('brightness of img2')
② A function that draws a histogram of a given image
import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('image.png')
fig, axes = plt.subplots(1, 1)
axes.hist(img.ravel(), bins=20)
axes.set_title('Histogram')
③ Code for drawing a 4-parameter logistic (4PL) curve: used a lot in pharmacology’s drug-response curve.
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# 4PL Model Definition
def four_param_logistic(x, A, B, C, D):
return A + (B - A) / (1 + (x / C)**D)
# Example Data
x_data = np.linspace(1, 100, 100)
y_data = four_param_logistic(x_data, 0.5, 10, 50, 1.5) + np.random.normal(size=len(x_data), scale=0.5)
# Parameter Assumption
popt, pcov = curve_fit(four_param_logistic, x_data, y_data, p0=[1, 1, 1, 1])
# Model Prediction based on Assumed Parameters
x_fit = np.linspace(1, 100, 400)
y_fit = four_param_logistic(x_fit, *popt)
# Plotting Results
plt.figure(figsize=(10, 5))
plt.scatter(x_data, y_data, label='Data')
plt.plot(x_fit, y_fit, color='red', label='4PL fit')
plt.title('4-Parameter Logistic Fit')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.show()
⑵ Image Save
① Example of saving an image as a png (ref)
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(5, 5))
fig.patch.set_visible(False)
plt.imshow(demask_image_t[0], interpolation='nearest')
plt.axis('off')
plt.savefig('foo.png', bbox_inches='tight', dpi = 300)
② Example of saving an image as a pdf
...
plt.show()
fig.savefig('foo.pdf', bbox_inches='tight', dpi = 300)
⑶ cv2 image RGB color rearrangement
import cv2
d = cv2.imread("/home/data/ST/WuSZ_2021_NG_TNBC/GSE/1160920F_spatial/spatial/tissue_hires_image.png")
d_array = cv2.cvtColor(d, cv2.COLOR_BGR2RGB)
plt.imshow(d_array)
⑷ cv2 image resize: For example, if img is (1024, 1024, 3), img_re is (512, 512, 3).
img_re = cv2.resize(img, dsize = (512, 512))
⑸ Conversion of an RGB image to a grayscale image
## version 1.
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
## version 2
import numpy as np
def RGBtoGray(img):
out = np.empty((img.shape[0], img.shape[1]))
for i in range(img.shape[0]):
for j in range(img.shape[1]):
out[i:i+1, j:j+1] = ( 0.2989*img[i:i+1, j:j+1, 0:1] +
0.5870*img[i:i+1, j:j+1, 1:2] +
0.1140*img[i:i+1, j:j+1, 2:3]
).item()
return out
⑹ A function that modifies a red image (1 × W × H) from a 3-channel RGB image to a two-dimensional image (W × H)
img_ = img[:,:,0:1].reshape(img.shape[0], img.shape[1])
⑺ A function that replaces one value with another in an image
def recolor(img, pre, post):
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if img[i:i+1, j:j+1] == pre:
img[i:i+1, j:j+1] = post
return(img)
⑻ Change numpy.ndarray of integers to numpy.ndarray of real numbers (reference)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('img.png')
img_cvt = np.array(img[:,:,:], dtype=np.float64)
⑼ Correlation between red and green in one image
import cv2
import matplotlib.pyplot as plt
from skimage.util import view_as_windows
import numpy as np
import scipy.stats
def two_image_correlation_RG(img1_dir):
img1 = cv2.imread(img1_dir) # RGB image
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
l_img1 = []
l_img2 = []
for i in range(img1.shape[0]):
for j in range(img1.shape[1]):
l_img1.append((
img1[i:i+1, j:j+1, 0:1]
).item())
l_img2.append((
img1[i:i+1, j:j+1, 1:2]
).item())
print("brightness of img1")
print(np.mean(l_img1))
print("brightness of img2")
print(np.mean(l_img2))
print("img1-img2 correlation")
print(scipy.stats.pearsonr(l_img1, l_img2) )
plt.scatter(l_img1, l_img2, alpha = 0.01)
plt.xlabel('brightness of img1')
plt.ylabel('brightness of img2')
⑽ Correlation between two images
import cv2
import matplotlib.pyplot as plt
from skimage.util import view_as_windows
import numpy as np
import scipy.stats
def two_image_correlation(img1_dir, img2_dir):
# img1 and img2 should be same in size
img1 = cv2.imread(img1_dir) # RGB image
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
img2 = cv2.imread(img2_dir) # RGB image
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
l_img1 = []
l_img2 = []
for i in range(img1.shape[0]):
for j in range(img1.shape[1]):
l_img1.append((
0.2989*img1[i:i+1, j:j+1, 0:1] +
0.5870*img1[i:i+1, j:j+1, 1:2] +
0.1140*img1[i:i+1, j:j+1, 2:3]
).item())
l_img2.append((
0.2989*img2[i:i+1, j:j+1, 0:1] +
0.5870*img2[i:i+1, j:j+1, 1:2] +
0.1140*img2[i:i+1, j:j+1, 2:3]
).item())
print("brightness of img1")
print(np.mean(l_img1))
print("brightness of img2")
print(np.mean(l_img2))
print("img1-img2 correlation")
print(scipy.stats.pearsonr(l_img1, l_img2) )
plt.scatter(l_img1, l_img2, alpha = 0.05)
plt.xlabel('brightness of img1')
plt.ylabel('brightness of img2')
# sns.regplot(l_b_CD31, l_b_Lipo, alpha = 0.05)
⑾ Correlation between red and green in one 3D image
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.util import view_as_windows
import scipy.stats
import glob
def two_image_correlation_RG_3D(my_dir):
images = glob.glob(my_dir + "*.jpg")
l_img1 = []
l_img2 = []
for k in range(len(images)):
print(k)
img1 = cv2.imread(images[k])
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
for i in range(img1.shape[0]):
for j in range(img1.shape[1]):
if (img1[i:i+1, j:j+1, 0:1] + img1[i:i+1, j:j+1, 1:2] + img1[i:i+1, j:j+1, 2:3]) != 0:
l_img1.append((
img1[i:i+1, j:j+1, 0:1]
).item())
l_img2.append((
img1[i:i+1, j:j+1, 1:2]
).item())
print("brightness of img1")
print(np.mean(l_img1))
print("brightness of img2")
print(np.mean(l_img2))
print("img1-img2 correlation")
print(scipy.stats.pearsonr(l_img1, l_img2) )
plt.scatter(l_img1, l_img2, alpha = 0.01)
plt.xlabel('brightness of img1')
plt.ylabel('brightness of img2')
⑿ Code for obtaining an SSIM value for a pair of images
def SSIM(x, y):
# assumption : x and y are grayscale images with the same dimension
import numpy as np
def mean(img):
return np.mean(img)
def sigma(img):
return np.std(img)
def cov(img1, img2):
img1_ = np.array(img1[:,:], dtype=np.float64)
img2_ = np.array(img2[:,:], dtype=np.float64)
return np.mean(img1_ * img2_) - mean(img1) * mean(img2)
K1 = 0.01
K2 = 0.03
L = 256 # when each pixel spans 0 to 255
C1 = K1 * K1 * L * L
C2 = K2 * K2 * L * L
C3 = C2 / 2
l = (2 * mean(x) * mean(y) + C1) / (mean(x)**2 + mean(y)**2 + C1)
c = (2 * sigma(x) * sigma(y) + C2) / (sigma(x)**2 + sigma(y)**2 + C2)
s = (cov(x, y) + C3) / (sigma(x) * sigma(y) + C3)
return l * c * s
⒀ Code for obtaining the mutal information value of a pair of images (reference)
def mutual_information(img1, img2):
import numpy as np
import cv2
import matplotlib.pyplot as plt
# img1 and img2 are 3-channel color images
a = img1[:,:,0:1].reshape(img1.shape[0], img1.shape[1])
b = img2[:,:,0:1].reshape(img2.shape[0], img2.shape[1])
hgram, x_edges, y_edges = np.histogram2d(
a.ravel(),
b.ravel(),
bins=20
)
pxy = hgram / float(np.sum(hgram))
px = np.sum(pxy, axis=1) # marginal for x over y
py = np.sum(pxy, axis=0) # marginal for y over x
px_py = px[:, None] * py[None, :] # Broadcast to multiply marginals
nzs = pxy > 0 # Only non-zero pxy values contribute to the sum
return np.sum(pxy[nzs] * np.log(pxy[nzs] / px_py[nzs]))
⒁ Code for obtaining a regression curve
from sklearn import linear_model
reg = linear_model.LinearRegression()
reg.fit([[0,0], [1,1], [2,2]], [0, 1, 2])
# LinearRegression()
reg.coef_
# array([0.5, 0.5])
⒂ Create a spot mapping image when given a background image, x-coordinate, y-coordinate, and color c in a spatial transcriptomics (ST).
def spatial_featuremap(img, x, y, c):
tsimg = np.zeros(img.shape[:2])
tsimg_row = y # np.array형 변수
tsimg_col = x # np.array형 변수
for rr, cc, t in zip(tsimg_row, tsimg_col, c):
r, c = draw.circle(rr, cc, radius = 2.5)
tsimg[r,c]= t
return tsimg
⒃ A function that determines the embossing and intaglio of an image: If the return value (-1 to 1) is positive, it is embossing; otherwise, it is intaglio.
def is_embossing(image):
l_1 = []
l_2 = []
row_cm = image.shape[0]/2
col_cm = image.shape[1]/2
def distance(x:int, y:int):
import numpy as np
return np.sqrt(x*x + y*y)
def my_sqrt(x:int, y:int, z:int):
import numpy as np
return np.sqrt(x*x + y*y + z*z)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
l_1.append( distance(i - row_cm, j - col_cm ))
if len(image.shape) == 2: # grayscale
l_2.append( image[i:i+1, j:j+1].item() )
elif len(image.shape) == 3: # 3-channel color image
l_2.append(
my_sqrt( image[i:i+1, j:j+1, 0:1].item(),
image[i:i+1, j:j+1, 1:2].item(),
image[i:i+1, j:j+1, 2:3].item()
)
)
print("Distance from Center")
print(np.mean(l_1))
print("Pixel Intensity")
print(np.mean(l_2))
plt.scatter(l_1, l_2, alpha = 0.01)
plt.ylim(0, 255)
plt.xlabel('Distance from Center')
plt.ylabel('Pixel Intensity')
return scipy.stats.pearsonr(l_1, l_2)[0] * (-1)
⒄ A useful code that combines multiple images to represent one image
fig, axes = plt.subplots(2,2,figsize=(6,20))
sns.barplot(df1[0:20], x='Gene', y ='Enrichment', ax = axes[0][0])
axes[0][0].tick_params(axis='x', rotation=90)
axes[0][0].set_title('DataFrame 1')
sns.barplot(df2[0:20], x='Gene', y ='Enrichment', ax = axes[0][1])
axes[0][1].tick_params(axis='x', rotation=90)
axes[0][1].set_title('DataFrame 2')
sns.barplot(df3[0:20], x='Gene', y ='Enrichment', ax = axes[1][0])
axes[1][0].tick_params(axis='x', rotation=90)
axes[1][0].set_title('DataFrame 3')
sns.barplot(df4[0:20], x='Gene', y ='Enrichment', ax = axes[1][1])
axes[1][1].tick_params(axis='x', rotation=90)
axes[1][1].set_title('DataFrame 4')
plt.tight_layout()
plt.show()
⒅ Code for decrypting when the base64 code of an image is truncated.
import base64
from PIL import Image, ImageFile
import io
# if the data is <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+0AA..."
data = "iVBORw0KGgoAAAANSUhEUgAAA+0AA..." # you need to modify this part
# If the length of the data is 'num' more than a multiple of 4, trim the last character(s)
num = len(data) % 4
data = data[:-num]
# Add padding to ensure the length is a multiple of 4
padding = '=' * ((4 - len(data) % 4) % 4)
data = data + padding
try:
decoded_data = base64.b64decode(data)
# Process the decoded data as needed
except Exception as e:
print("Error in decoding base64:", e)
image = Image.open(io.BytesIO(decoded_data))
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
image = Image.open(io.BytesIO(decoded_data))
image.show()
except IOError:
print("Cannot open the image.")
⒆ chart-to-text (ref)
⒇ Create a random image of the same size as the given image
import numpy as np
import cv2
# Load the image using OpenCV
tsimg = cv2.imread(imgfile)
# Get the dimensions of the original image
height, width, channels = tsimg.shape
# Create a random image with the same dimensions
# Random values are generated in the range 0-255, which is the range for pixel values in an 8-bit image
random_img = np.random.randint(0, 256, (height, width, channels), dtype=np.uint8)
# Optionally, you can save or display the random image using OpenCV
cv2.imwrite('random_image.png', random_img) # Save the random image
def otsu_thresholding(image_path):
import cv2
import matplotlib.pyplot as plt
# Load the image from the specified path
image = cv2.imread(image_path)
# Convert the image to grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply Gaussian blur to the grayscale image
blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
# Perform Otsu's thresholding to obtain the initial thresholded image
_, initial_otsu_thresholded = cv2.threshold(blurred_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Modify the threshold value if needed
threshold_adjustment = 5
modified_threshold_value = _ + threshold_adjustment
_, modified_otsu_thresholded = cv2.threshold(blurred_image, modified_threshold_value, 255, cv2.THRESH_BINARY)
# Display the original grayscale, initial Otsu thresholded, and modified Otsu thresholded images
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(gray_image, cmap='gray')
plt.title('Grayscale Image')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(initial_otsu_thresholded, cmap='gray')
plt.title('Initial Otsu Thresholded Image')
plt.axis('off')
plt.subplot(1, 3, 3)
plt.imshow(modified_otsu_thresholded, cmap='gray')
plt.title('Modified Otsu Thresholded Image')
plt.axis('off')
plt.show()
# Return the modified Otsu thresholded image
return modified_otsu_thresholded
⒇ Visualize images on the Internet
import matplotlib.pyplot as plt
import requests
from PIL import Image
from io import BytesIO
# URL of the image
image_url = "https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmxJpC%2FbtsrErXwO2Q%2FCMhkpoHTn0Ht65uhdwkeSk%2Fimg.png"
# Loading the image
response = requests.get(image_url)
img = Image.open(BytesIO(response.content))
# Visualization of the image
plt.figure(figsize=(8, 8))
plt.imshow(img)
plt.axis('off') # Removal of axis
plt.show()
7. Data Science
⑴ K means clustering
from sklearn.cluster import KMeans
X = [[1, 2, 3],[1, 2, 3.1],[2, 2, 4],[2, 2, 4.1]]
kmeans = KMeans(n_clusters=2, random_state=0)
kmeans.fit(X)
cluster_labels = kmeans.labels_
print(cluster_labels)
# [1 1 0 0]
⑵ Calculating the Gini Coefficient from a Sequence
def gini_coefficient(values):
# If the list of values is empty or all values are the same, the Gini coefficient is 0.
if not values or all(x == values[0] for x in values):
return 0.0
n = len(values)
mean_value = sum(values) / n
sum_of_differences = sum(abs(x - y) for x in values for y in values)
# Calculate the Gini coefficient
gini = sum_of_differences / (2 * n**2 * mean_value)
return gini
# Example data
income = [15, 20, 35, 40, 50]
# Calculating the Gini coefficient
gini_index = gini_coefficient(income)
print(f"The Gini coefficient is {gini_index:.2f}")
⑶ Calculate Shannon entry when given a sequence
import numpy as np
def shannon_index(data):
# Count unique values and their occurrences in the data
values, counts = np.unique(data, return_counts=True)
# Calculate proportions using the counts
proportions = counts / sum(counts)
# Calculate Shannon index, considering only non-zero proportions
return -np.sum(proportions * np.log(proportions))
# Example data, where '1' appears 3 times, '2' appears 2 times, and '3' appears 1 time
data = [1, 1, 1, 2, 2, 3]
# Calculate the Shannon index
index = shannon_index(data)
print(f"Shannon index: {index}")
8. Deep Learning Function
⑴ Deep learning example: Applying a deep learning model to the MNIST (i.e., handwritten digits) dataset.
import tensorflow as tf
from tensorflow.keras import layers, models
# Load the MNIST dataset
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# Normalize the pixel values of the images to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0
# Define a simple sequential model
def create_model():
model = models.Sequential([
layers.Flatten(input_shape=(28, 28)), # Flatten the 2D image to a 1D array
layers.Dense(128, activation='relu'), # First hidden layer with 128 neurons and ReLU activation
layers.Dropout(0.2), # Dropout layer to reduce overfitting
layers.Dense(10, activation='softmax') # Output layer with 10 neurons for 10 classes and softmax activation
])
return model
# Create the model
model = create_model()
# Compile the model
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Train the model
model.fit(train_images, train_labels, epochs=5)
# Evaluate the model
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(f'Test accuracy: {test_acc}')
⑵ Algorithm to classify 10,000 Xte as KNN when 60,000 data Xtrs and 60,000 label Ytrs are present
import tensorflow as tf
(Xtr, Ytr), (Xte, Yte) = tf.keras.datasets.mnist.load_data()
print(Xtr.shape) # (60000, 28, 28)
print(Ytr.shape) # (60000,)
print(Xte.shape) # (10000, 28, 28)
print(Yte.shape) # (10000,)
Xtr_rows = Xtr.reshape(Xtr.shape[0], 28*28)
Xte_rows = Xte.reshape(Xte.shape[0], 28*28)
print(Xtr_rows.shape) # (60000, 784)
print(Xte_rows.shape) # (10000, 784)
def KNN_predict(Xtr_rows, Ytr, Xte_rows, dist_metric='L2'):
import numpy as np
class NearestNeighbor(object):
def __init__(self):
pass
def train(self, X, Y):
self.Xtr = X
self.Ytr = Y
def predict(self, X, dist_metric=dist_metric):
num_test = X.shape[0]
Ypred = np.zeros(num_test, dtype = self.Ytr.dtype)
for i in range(num_test):
if dist_metric=='L1': ## L1 distance
distances = np.sum(np.abs(self.Xtr - X[i, :]), axis = 1)
elif dist_metric=='L2': ## L2 distance
distances = np.sum(np.square(self.Xtr - X[i, :]), axis = 1)
elif dist_metric=='dot': ## dot distance
distances = np.dot(self.Xtr, X[i, :])
min_index = np.argmin(distances)
Ypred[i] = self.Ytr[min_index]
if i%100 == 0:
print(i)
return Ypred
nn = NearestNeighbor()
nn.train(Xtr_rows, Ytr)
Yte_predict = nn.predict(Xte_rows, dist_metric)
return Yte_predict
def KNN_evaluate(Xtr_rows, Ytr, Xte_rows, Yte, dist_metric='L2'):
Yte_predict = KNN_predict(Xtr_rows, Ytr, Xte_rows, dist_metric)
print ('accuracy: %f' + str(np.mean(Yte_predict == Yte)) )
# L1 : accuracy = 47.29%
# L2 : accuracy = 27.24%
# dot : accuracy = 9.9%
KNN_evaluate(Xtr_rows, Ytr, Xte_rows, Yte)
⑶ Binary classifier function implemented by 1D CNN
# reference : https://wikidocs.net/80783
def binary_predict_by_1D_CNN (Xtr_rows, Ytr, Xte_rows, Yte):
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Dropout, Conv1D, GlobalMaxPooling1D, Dense
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras.models import load_model
vocab_size = 10000
embedding_dim = 256 # 임베딩 벡터의 차원
dropout_ratio = 0.3 # 드롭아웃 비율
num_filters = 256 # 커널의 수
kernel_size = 3 # 커널의 크기
hidden_units = 128 # 뉴런의 수
model = Sequential()
model.add(Embedding(vocab_size, embedding_dim))
model.add(Dropout(dropout_ratio))
model.add(Conv1D(num_filters, kernel_size, padding='valid', activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(hidden_units, activation='relu'))
model.add(Dropout(dropout_ratio))
model.add(Dense(1, activation='sigmoid'))
model.summary()
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=3)
mc = ModelCheckpoint('best_model.h5', monitor='val_acc', mode='max', verbose=1, save_best_only=True)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
history = model.fit(Xtr_rows, Ytr, epochs=20, validation_data=(Xte_rows, Yte), callbacks=[es, mc])
def binary_evaluate_by_1D_CNN(Xtr_rows, Ytr, Xte_rows, Yte):
from tensorflow.keras.models import load_model
binary_predict_by_1D_CNN(Xtr_rows, Ytr, Xte_rows, Yte)
loaded_model = load_model('best_model.h5')
print("\n 테스트 정확도: %.4f" % (loaded_model.evaluate(Xte_rows, Yte)[1]))
##################
# Example 1. Mnist
import tensorflow as tf
(Xtr, Ytr), (Xte, Yte) = tf.keras.datasets.mnist.load_data()
Xtr_rows = Xtr.reshape(Xtr.shape[0], 28*28)
Xte_rows = Xte.reshape(Xte.shape[0], 28*28)
print(Xtr_rows.shape) # (60000, 784)
print(Ytr.shape) # (60000,)
print(Xte_rows.shape) # (10000, 784)
print(Yte.shape) # (10000,)
binary_evaluate_by_1D_CNN(Xtr_rows, Ytr > 5, Xte_rows, Yte > 5)
# 1D CNN accuracy : 7.82%
##################
# Example 2. IMDB
from tensorflow.keras import datasets
from tensorflow.keras.preprocessing.sequence import pad_sequences
vocab_size = 10000
(X_train, y_train), (X_test, y_test) = datasets.imdb.load_data(num_words=vocab_size)
max_len = 200
X_train = pad_sequences(X_train, maxlen=max_len)
X_test = pad_sequences(X_test, maxlen=max_len)
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
binary_evaluate_by_1D_CNN(X_train, y_train, X_test, y_test)
# 1D CNN accuracy : 88.92%
⑷ A function that extracts 512-dimensional features from any image via pre-trained CNN
# reference
## https://github.com/mexchy1000/spade/blob/master/spade_spatial_marker_by_deeplearning.py
import os
import numpy as np
import matplotlib.pyplot as plt
from skimage import draw
import pandas as pd
import argparse
from keras import backend as K
from keras.applications import vgg16, resnet50, inception_v3
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
K.set_image_data_format='channels_last'
os.environ['KERAS_BACKEND'] = 'tensorflow'
def features_512D_from_image_by_CNN (img, model_name = 'VGG16'):
# Image Patch
img_re = cv2.resize(img, dsize = (32, 32))
tspatches = []
tspatches.append(img_re)
tspatches.append(img_re) # intentional duplicate
tspatches = np.asarray(tspatches)
# Pretrained model
if model_name == 'VGG16':
pretrained_model = vgg16.VGG16(weights='imagenet', include_top = False, pooling='avg', input_shape = (32,32,3))
X_in = tspatches.copy()
X_in = vgg16.preprocess_input(X_in)
elif model_name == 'ResNet50':
pretrained_model = resnet50.ResNet50(weights='imagenet', include_top = False, pooling='avg', input_shape = (32,32,3))
X_in = tspatches.copy()
X_in = resnet50.preprocess_input(X_in)
elif model_name == 'InceptionV3':
pretrained_model = inception_v3.InceptionV3(weights='imagenet', include_top = False, pooling='avg', input_shape = (32,32,3))
X_in = tspatches.copy()
X_in = inception_v3.preprocess_input(X_in)
pretrained_model.trainable = False
pretrained_model.summary()
# Get the features
ts_features = pretrained_model.predict(X_in)
return ts_features[0]
⑸ A function that fetches BERT or BioBERT from the Hugging Face to create an attention matrix for the given sentence
import torch
from transformers import BertTokenizer, BertModel
import matplotlib.pyplot as plt
import seaborn as sns
# Load BERT model and tokenizer (OPTION 1)
'''
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name, output_attentions=True)
'''
# Load BioBERT model and tokenizer (OPTION 2)
model_name = 'dmis-lab/biobert-base-cased-v1.1'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name, output_attentions=True)
# Input sentence
sentence = "Find diseases associated with glucose"
# Tokenization
inputs = tokenizer(sentence, return_tensors='pt')
# Calculate output values and attention weights through the model
outputs = model(**inputs)
attentions = outputs.attentions # This value is the attention weight of each layer
# Visualization of the attention weight of the first head of the first layer
attention = attentions[0][0][0].detach().numpy()
# List of tokens
tokens = tokenizer.convert_ids_to_tokens(inputs['input_ids'][0])
# Visualization of Attention Weights
plt.figure(figsize=(10, 10))
sns.heatmap(attention, xticklabels=tokens, yticklabels=tokens, cmap='viridis')
plt.title('Attention Weights')
plt.show()
⑹ A function that converts arbitrary variable-length natural language sentences into 384 dimensions while considering their meanings. (cf. CeLLaMA)
from langchain.embeddings.sentence_transformer import SentenceTransformerEmbeddings
import numpy as np
from scipy.sparse import csr_matrix
import pandas as pd
from sklearn.neighbors import NearestNeighbors
import torch
from torch.utils.data import DataLoader, TensorDataset
from xgboost import XGBClassifier
def sentences_to_embedding(sentences):
embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
db = embedding_function.embed_documents(sentences)
emb_res = np.asarray(db)
return emb_res
sentences = []
sentences.append("What is the meaning of: obsolete")
sentences.append("What is the meaning of: old-fashioned")
sentences.append("What is the meaning of: demagogue")
emb_res = sentences_to_embedding(sentences)
⑺ Collection of Natural Language Processing and LLM Useful Functions
9. Exception Handling
⑴ Basic exception handling syntax
try:
raise KeyError("Error")
except:
print("An exception occurred")
# An exception occurred
⑵ print error message (ref.)
try:
print(1/0)
except Exception as e:
print(e)
10. Bioinformatics
⑴ Code for acquiring highly variable genes
import scanpy as sc
tissue_dir = './outs'
adata1 = sc.read_visium(tissue_dir)
sc.set_figure_params(facecolor="white", figsize=(8, 8))
sc.settings.verbosity = 3
adata1.var_names_make_unique()
sc.pp.normalize_total(adata1, inplace=True)
sc.pp.log1p(adata1)
sc.pp.highly_variable_genes(adata1, flavor="seurat", n_top_genes=200)
gene_list=adata1.var.loc[adata1.var.highly_variable==True,:].index
⑵ Code for acquiring highest expressing genes
import scanpy as sc
import numpy as np
import pandas as pd
pbmc = sc.read_h5ad("Tabula_Sapiens.h5ad")
# normalize counts matrix so that each 'cell' (barcode) has counts summing to 1
pbmc.X_norm = sc.pp.normalize_total(pbmc, target_sum=1, inplace=False)['X']
# create new adata.var column contaning mean of each column of adata.X_norm above
# this is total normalized counts per gene a.k.a. 'mean_total_expression'
pbmc.var['mean_expression'] = np.ravel(pbmc.X_norm.mean(0))
# return pd.DataFrame of n top-ranked genes by mean expression
x = pd.DataFrame(pbmc.var.nlargest(200, 'mean_expression')['mean_expression'])
⑶ GO plot (ver. 1) (not recommended
)
# Reference
## https://github.com/mousepixels/sanbomics_scripts/blob/main/GO_in_python.ipynb
## https://snyk.io/advisor/python/goatools/functions/goatools.anno.genetogo_reader.Gene2GoReader
def GO(markers, max_terms = 6):
# type(markers) = numpy.ndarray
# dtype = object
if len(markers) == 0:
return
from genes_ncbi_mus_musculus_proteincoding import GENEID2NT as GeneID2nt_mus
from genes_ncbi_homo_sapiens_proteincoding import GENEID2NT as GeneID2nt_homo
from goatools.base import download_go_basic_obo
from goatools.base import download_ncbi_associations
from goatools.obo_parser import GODag
from goatools.anno.genetogo_reader import Gene2GoReader
from goatools.goea.go_enrichment_ns import GOEnrichmentStudyNS
obo_fname = download_go_basic_obo()
fin_gene2go = download_ncbi_associations()
obodag = GODag("go-basic.obo")
#run one time to initialize
mapper = {}
if markers[0] == markers[0].upper(): # Homo sapiens
for key in GeneID2nt_homo:
mapper[GeneID2nt_homo[key].Symbol] = GeneID2nt_homo[key].GeneID
else: # Mus musculus
for key in GeneID2nt_mus:
mapper[GeneID2nt_mus[key].Symbol] = GeneID2nt_mus[key].GeneID
inv_map = {v: k for k, v in mapper.items()}
if markers[0] == markers[0].upper():
objanno = Gene2GoReader(fin_gene2go, taxids=[9606])
else:
objanno = Gene2GoReader(fin_gene2go, taxids=[10090])
ns2assoc = objanno.get_ns2assc()
goeaobj = ''
if markers[0] == markers[0].upper():
goeaobj = GOEnrichmentStudyNS(
GeneID2nt_homo.keys(), # List of human protein-coding genes
ns2assoc, # geneid/GO associations
obodag, # Ontologies
propagate_counts = False,
alpha = 0.05, # default significance cut-off
methods = ['fdr_bh']) # defult multipletest correction method
else:
goeaobj = GOEnrichmentStudyNS(
GeneID2nt_mus.keys(), # List of mouse protein-coding genes
ns2assoc, # geneid/GO associations
obodag, # Ontologies
propagate_counts = False,
alpha = 0.05, # default significance cut-off
methods = ['fdr_bh']) # defult multipletest correction method
GO_items = []
temp = goeaobj.ns2objgoea['BP'].assoc
for item in temp:
GO_items += temp[item]
temp = goeaobj.ns2objgoea['CC'].assoc
for item in temp:
GO_items += temp[item]
temp = goeaobj.ns2objgoea['MF'].assoc
for item in temp:
GO_items += temp[item]
def go_it(test_genes):
print(f'input genes: {len(test_genes)}')
mapped_genes = []
for gene in test_genes:
try:
mapped_genes.append(mapper[gene])
except:
pass
print(f'mapped genes: {len(mapped_genes)}')
goea_results_all = goeaobj.run_study(mapped_genes)
goea_results_sig = [r for r in goea_results_all if r.p_fdr_bh < 0.05]
GO = pd.DataFrame(list(map(lambda x: [x.GO, x.goterm.name, x.goterm.namespace, x.p_uncorrected, x.p_fdr_bh,\
x.ratio_in_study[0], x.ratio_in_study[1], GO_items.count(x.GO), list(map(lambda y: inv_map[y], x.study_items)),\
], goea_results_sig)), columns = ['GO', 'term', 'class', 'p', 'p_corr', 'n_genes',\
'n_study', 'n_go', 'study_genes'])
GO = GO[GO.n_genes > 1]
return GO
df = go_it(markers)
df['per'] = df.n_genes/df.n_go
if df.shape[0] > 0:
df = df.sort_values(by=['p_corr'], axis=0, ascending=True)
if df.shape[0] > max_terms:
df = df[0:max_terms]
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import cm
import seaborn as sns
import textwrap
fig, ax = plt.subplots(figsize = (0.5, 2.75))
cmap = mpl.cm.bwr_r
norm = mpl.colors.Normalize(vmin = df.p_corr.min(), vmax = df.p_corr.max())
mapper = cm.ScalarMappable(norm = norm, cmap = cm.bwr_r)
cbl = mpl.colorbar.ColorbarBase(ax, cmap = cmap, norm = norm, orientation = 'vertical')
plt.figure(figsize = (2,4))
ax = sns.barplot(data = df, x = 'per', y = 'term', palette = mapper.to_rgba(df.p_corr.values))
ax.set_yticklabels([textwrap.fill(e, 22) for e in df['term']])
plt.show()
⑷ GO plot (ver. 2) (recommended
)
def GO(gene_list):
# reference : https://gseapy.readthedocs.io/en/latest/gseapy_example.html
import gseapy
from gseapy import barplot, dotplot
if gene_list[0] == gene_list[0].upper():
enr = gseapy.enrichr(gene_list=gene_list, # or "./tests/data/gene_list.txt",
gene_sets=['GO_Biological_Process_2018','GO_Cellular_Component_2018', 'GO_Molecular_Function_2018'],
organism='human', # don't forget to set organism to the one you desired! e.g. Yeast
outdir=None, # don't write to disk
)
else:
enr = gseapy.enrichr(gene_list=gene_list, # or "./tests/data/gene_list.txt",
gene_sets=['GO_Biological_Process_2018','GO_Cellular_Component_2018', 'GO_Molecular_Function_2018'],
organism='mouse', # don't forget to set organism to the one you desired! e.g. Yeast
outdir=None, # don't write to disk
)
try:
ax = dotplot(enr.results,
column="Adjusted P-value",
x='Gene_set', # set x axis, so you could do a multi-sample/library comparsion
size=10,
top_term=5,
figsize=(3,5),
title = "GO plot",
xticklabels_rot=45, # rotate xtick labels
show_ring=True, # set to False to revmove outer ring
marker='o',
)
except:
print("ValueError: Warning: No enrich terms when cutoff = 0.05")
① gseapy appears incompatible with plt.subplot.
⑸ convert from ensembl.gene to gene.symbol using a table
def ensembl_to_gene(ensembl_list):
ar = []
human = pd.read_csv("https://blog.kakaocdn.net/dn/29YTj/btrS5iG9QOH/Di6RQKxHOPDii7EjkdHN30/human_genes_36601.tsv?attach=1&knm=tfile.tsv", sep = '\t', header = None)
mouse = pd.read_csv("https://blog.kakaocdn.net/dn/wkjwJ/btrS1QSgrpD/VS8ELANCQyeZAA3vL8JQP0/mouse_genes_32285.tsv?attach=1&knm=tfile.tsv", sep = '\t', header = None)
for i in range(len(ensembl_list)):
if 'ENSG' in ensembl_list[i]: # human gene
index = human[0].tolist().index(ensembl_list[i])
ar.append(human[1][index])
elif 'ENSMUSG' in ensembl_list[i]: # mouse gene
index = mouse[0].tolist().index(ensembl_list[i])
ar.append(mouse[1][index])
return(ar)
⑹ convert from gene.symbol to ensembl.gene using a table
def gene_to_ensembl(gene_list):
ar = []
human = pd.read_csv("https://blog.kakaocdn.net/dn/29YTj/btrS5iG9QOH/Di6RQKxHOPDii7EjkdHN30/human_genes_36601.tsv?attach=1&knm=tfile.tsv", sep = '\t', header = None)
mouse = pd.read_csv("https://blog.kakaocdn.net/dn/wkjwJ/btrS1QSgrpD/VS8ELANCQyeZAA3vL8JQP0/mouse_genes_32285.tsv?attach=1&knm=tfile.tsv", sep = '\t', header = None)
for i in range(len(gene_list)):
if gene_list[i] == gene_list[i].upper(): # human gene
index = human[1].tolist().index(gene_list[i])
ar.append(human[0][index])
else: # mouse gene
index = mouse[1].tolist().index(gene_list[i])
ar.append(mouse[0][index])
return(ar)
⑺ Human genes, mouse genes interconversion
import pandas as pd
import numpy as np
def find_idx(my_list, e):
for i in range(len(my_list)):
if my_list[i] == e:
return i
return -1
def human_to_mouse(human_gene:list):
hom = pd.read_csv("https://blog.kakaocdn.net/dn/cVeqsA/btrS1JMnxyX/HtVhPmqtxdgt7LQlGkeql0/HOM_MouseHumanSequence.csv?attach=1&knm=tfile.csv")
mouse_gene = []
for i in range(len(human_gene)):
index = find_idx(hom['Symbol'], human_gene[i])
DB_Class_Key = hom['DB Class Key'][index]
hom_ = hom[hom['DB Class Key'] == DB_Class_Key]
hom__ = hom_[hom_['Common Organism Name'] == 'mouse, laboratory']
mouse_gene.append(np.array(hom__['Symbol'])[0])
return mouse_gene
def mouse_to_human(mouse_gene:list):
hom <- pd.read_csv("https://blog.kakaocdn.net/dn/cVeqsA/btrS1JMnxyX/HtVhPmqtxdgt7LQlGkeql0/HOM_MouseHumanSequence.csv?attach=1&knm=tfile.csv")
human_gene = []
for i in range(len(mouse_gene)):
index = find_idx(hom['Symbol'], mouse_gene[i])
DB_Class_Key = hom['DB Class Key'][index]
hom_ = hom[hom['DB Class Key'] == DB_Class_Key]
hom__ = hom_[hom_['Common Organism Name'] == 'human']
mouse_gene.append(np.array(hom__['Symbol'])[0])
return human_gene
⑻ When there is a directory tissue_dir containing matrix.mtx, barcodes.tsv, features.tsv, and the spatial folder, the code to read Visium data in Python.
import scanpy as sc
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.image import imread
import numpy as np
import cv2
import math
from pathlib import Path, PurePath
from typing import Union, Dict, Optional, Tuple, BinaryIO
import json
def to_spatial(adata, path, library_id = 'TNBC1'):
adata.uns["spatial"][library_id] = dict()
path = Path(path)
files = dict(
tissue_positions_file=path / 'spatial/tissue_positions_list.csv',
scalefactors_json_file=path / 'spatial/scalefactors_json.json',
hires_image=path / 'spatial/tissue_hires_image.png',
lowres_image=path / 'spatial/tissue_lowres_image.png',
)
# check if files exists, continue if images are missing
for f in files.values():
if not f.exists():
if any(x in str(f) for x in ["hires_image", "lowres_image"]):
logg.warning(
f"You seem to be missing an image file.\n"
f"Could not find '{f}'."
)
else:
raise OSError(f"Could not find '{f}'")
adata.uns["spatial"][library_id]['images'] = dict()
for res in ['hires', 'lowres']:
try:
adata.uns["spatial"][library_id]['images'][res] = imread(
str(files[f'{res}_image'])
)
except Exception:
raise OSError(f"Could not find '{res}_image'")
# read json scalefactors
adata.uns["spatial"][library_id]['scalefactors'] = json.loads(
files['scalefactors_json_file'].read_bytes()
)
#adata.uns["spatial"][library_id]["metadata"] = {
# k: (str(attrs[k], "utf-8") if isinstance(attrs[k], bytes) else attrs[k])
# for k in ("chemistry_description", "software_version")
# if k in attrs
#}
# read coordinates
positions = pd.read_csv(files['tissue_positions_file'], header=None)
positions.columns = [
'barcode',
'in_tissue',
'array_row',
'array_col',
'pxl_col_in_fullres',
'pxl_row_in_fullres',
]
positions.index = positions['barcode']
adata.obs = adata.obs.join(positions, how="left")
adata.obsm['spatial'] = adata.obs[
['pxl_row_in_fullres', 'pxl_col_in_fullres']
].to_numpy()
adata.obs.drop(
columns=['barcode', 'pxl_row_in_fullres', 'pxl_col_in_fullres'],
inplace=True,
)
return adata
def load_adata(tissue_dir):
adata1 = sc.read_mtx(tissue_dir + 'matrix.mtx')
adata1 = adata1.transpose()
cellname = pd.read_csv(tissue_dir + 'barcodes.tsv', sep="\t", header=None, index_col=1, names=['idx', 'barcode'])
cellname.index = cellname['idx']
featurename = pd.read_csv(tissue_dir + 'features.tsv', sep='\t', header=None, index_col=1, names=['gene_ids', 'feature_types'])
adata1.var = featurename
adata1.obs = cellname
adata1.uns["spatial"] = dict()
adata1 = to_spatial(adata1, tissue_dir, library_id='Library_1')
adata1 = adata1[adata1.obs.in_tissue == 1,:]
adata1.var_names_make_unique()
adata1.obs['unnormalized_counts'] = adata1.X.sum(axis=1).A1
sc.pp.normalize_total(adata1, inplace=True)
adata1.obs['normalized_counts'] = adata1.X.sum(axis=1).A1
sc.pp.log1p(adata1)
sc.pp.highly_variable_genes(adata1, flavor="seurat", n_top_genes=2000)
return adata1
⑼ A collection of Python functions related to organic chemistry
⑽ Acquire the human and mouse gene sequences (but only human genes are required)
from Bio import Entrez
from Bio import SeqIO
from Bio.Blast import NCBIWWW
from Bio.Blast import NCBIXML
import pandas as pd
def human_mouse_gene_sequence(input_gene_name):
# Entrez email setup (required by NCBI)
Entrez.email = "nate9389@gmail.com"
# Function to fetch the sequence using gene ID
def fetch_sequence(gene_id):
handle = Entrez.efetch(db="nucleotide", id=gene_id, rettype="fasta", retmode="text")
record = SeqIO.read(handle, "fasta")
handle.close()
return record.seq
def get_gene_ids(input_gene, file_path="https://blog.kakaocdn.net/dn/cVeqsA/btrS1JMnxyX/HtVhPmqtxdgt7LQlGkeql0/HOM_MouseHumanSequence.csv?attach=1&knm=tfile.csv"):
# Read the CSV file into a DataFrame
df = pd.read_csv(file_path)
# Normalize the input gene name to uppercase to match the 'Symbol' column
input_gene = input_gene.upper()
# Find the row with the human gene symbol
human_row = df[(df['Common Organism Name'] == 'human') & (df['Symbol'].str.upper() == input_gene)]
# If the human gene is not found, return an error message
if human_row.empty:
return "Error: Human gene not found.", None
# Find the corresponding mouse gene using the DB Class Key
db_class_key = human_row['DB Class Key'].values[0]
mouse_row = df[(df['Common Organism Name'] == 'mouse, laboratory') & (df['DB Class Key'] == db_class_key)]
# If the mouse gene is not found, return an error message
if mouse_row.empty:
return None, "Error: Corresponding mouse gene not found."
# Retrieve the gene IDs
human_gene_id = human_row['Nucleotide RefSeq IDs'].values[0].split(',')[0] # Taking the first RefSeq ID if multiple are present
mouse_gene_id = mouse_row['Nucleotide RefSeq IDs'].values[0].split(',')[0] # Taking the first RefSeq ID if multiple are present
return human_gene_id, mouse_gene_id
# Get the human and mouse gene IDs
human_gene_id, mouse_gene_id = get_gene_ids(input_gene_name)
# Fetch the sequences
human_sequence = fetch_sequence(human_gene_id)
mouse_sequence = fetch_sequence(mouse_gene_id)
return human_sequence, mouse_sequence
### Example
human, mouse = human_mouse_gene_sequence("COL1A1")
⑾ Python code to put an image into Visium anndata obs.
import scanpy as sc
import cv2
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import scipy
tissue_dir1 = './outs/'
adata1 = sc.read_visium(tissue_dir1)
img1 = cv2.imread(tissue_dir1 + 'spatial/tissue_hires_image.png')
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
hires = adata1.uns['spatial']['Parent_Visium_Human_OvarianCancer']['images']['hires']
tissue_hires_scalef = adata1.uns['spatial']['Parent_Visium_Human_OvarianCancer']['scalefactors']['tissue_hires_scalef']
coords = adata1.obsm['spatial'] * tissue_hires_scalef
adata1.obs['img'] = adata1.obs['in_tissue'] # just making a variable
for i in range(adata1.shape[0]):
x_coord = int(np.round(coords[i][0]))
y_coord = int(np.round(coords[i][1]))
# Ensure the coordinates are within the bounds of the image
x_coord = max(0, min(x_coord, hires.shape[1] - 1))
y_coord = max(0, min(y_coord, hires.shape[0] - 1))
# Extract the intensity of the pixel (for simplicity, using the red channel)
intensity = hires[y_coord, x_coord, 0] # Red channel
adata1.obs['img'][i] = intensity
sc.pl.spatial(adata1, color = 'img', img_key=None, spot_size=300)
⑿ Code for reading Visium ST data as AnnData and then performing data QC (Quality Control) operations
def QC(tissue_dir):
metafile = None
adata1 = sc.read_visium(tissue_dir)
### alternatively ###
# adata1 = sc.read_10x_mtx(tissue_dir)
adata1.var_names_make_unique()
sc.pp.normalize_total(adata1, inplace=True)
sc.pp.log1p(adata1)
# sc.pp.highly_variable_genes(adata1, flavor="seurat", n_top_genes=17189)
adata1.obs['n_counts'] = adata1.X.sum(axis=1).A1
sc.pl.spatial(adata1, img_key="hires", color='n_counts', alpha=0.7, cmap='jet')
return adata1
⒀ Enlarge sc.pl.spatial
size.
fig, ax = plt.subplots(figsize=(10,10))
sc.pl.spatial(adata, color = 'total_counts', ax=ax, show=False)
plt.show()
⒁ Remove color bar from sc.pl.spatial
import matplotlib.pyplot as plt
import scanpy as sc
sc.pl.spatial(adata, img_key="hires", color='score', alpha=1.0, cmap='viridis', show=False)
fig = plt.gcf()
ax = fig.axes
# Find and remove the colorbar. The colorbar is usually the last axis in the figure.
if len(ax) > 1: # If there's more than one axis (i.e., the colorbar is present)
fig.delaxes(ax[-1]) # Remove the last axis (the colorbar)
plt.show()
⒂ Transpose adata: swap gene name and barcode name
import scanpy as sc
import pandas as pd
# Assuming 'data' is your AnnData object
# Load your AnnData object if it's not already in memory
# data = sc.read_h5ad('/path/to/your/data.h5ad')
# Transpose the data matrix and swap the 'obs' and 'var' DataFrames
adata_transposed = sc.AnnData(X=data.X.T, obs=data.var, var=data.obs)
# If 'obs_names' and 'var_names' need to be retained, you might want to transfer them as well
adata_transposed.obs_names = data.var_names
adata_transposed.var_names = data.obs_names
# Now 'adata_transposed' is the transposed version of ‘data'
⒃ Creating an h5ad file when you have matrix.mtx, barcodes.tsv, and features.tsv (or genes.tsv): Assume that all three files have the same prefix.
import os
import glob
from scipy.io import mmread
import pandas as pd
import scanpy as sc
# Set the target directory here
target_directory = '/path/to/your/directory'
# Iterate over all .mtx files in the target directory
for mtx_file in glob.glob(os.path.join(target_directory, '*matrix.mtx')):
prefix = mtx_file[:-10] # Remove 'matrix.mtx' to get the prefix
# Construct file names for barcodes and genes
barcodes_file = prefix + 'barcodes.tsv'
features_file = prefix + 'features.tsv'
genes_file = prefix + 'features.tsv' if os.path.exists(prefix + 'features.tsv') else prefix + 'genes.tsv'
# Check if all files exist
if os.path.exists(mtx_file) and os.path.exists(barcodes_file) and os.path.exists(genes_file):
# Load the data
matrix = mmread(mtx_file).T.tocsr() # Transpose to have genes as columns
genes = pd.read_csv(genes_file, header=None, sep='\t')
barcodes = pd.read_csv(barcodes_file, header=None, sep='\t')
# Create an AnnData object
adata = sc.AnnData(X=matrix, obs={'barcodes': barcodes[0].values}, var={'gene_ids': genes[0].values, 'gene_symbols': genes[1].values})
# Output file name
h5ad_file = prefix + '.h5ad'
# Save the AnnData object
adata.write(h5ad_file)
# Delete the original files
os.remove(mtx_file)
os.remove(barcodes_file)
os.remove(genes_file)
print("Conversion complete. Original files have been deleted.")
⒄ Code to concatenate a list of adata objects into a single adata
# Note that adatas = [adata1, adata2, ...]
adata_concat = sc.concat(adatas, keys="sample1 sample2 sample3 sample4 sample5 sample6".split(" "), index_unique='_', label='sample')
⒅ Code for providing the number of reads per barcode from an H5 file.
def get_mapped_reads(h5_file):
with h5py.File(h5_file, 'r') as f:
# Access the matrix group in the HDF5 file
matrix_group = f['matrix']
# Read the barcode, gene, and data datasets
barcodes = np.array(matrix_group['barcodes']).astype(str)
genes = np.array(matrix_group['features/name']).astype(str)
data = np.array(matrix_group['data'])
# Sum the data for each barcode to get the number of mapped reads per barcode
barcode_read_counts = np.array(matrix_group['indptr'][1:] - matrix_group['indptr'][:-1])
return barcodes, genes, barcode_read_counts
⒆ Code for providing the features (genes) from an h5 file.
import h5py
# Path to your HDF5 file
file_path = f'./{datas[0]}/filtered_feature_bc_matrix.h5' # Replace with your actual file path
# Open the HDF5 file and inspect its contents
with h5py.File(file_path, 'r') as f:
# List all groups in the file
print("Keys in HDF5 file:")
print(list(f.keys()))
# Access the 'matrix/features/name' to check what features are present
features = f['matrix/features/name'][:]
# Convert byte strings to normal strings (if necessary)
features = [feature.decode('utf-8') for feature in features]
print("\nFeatures in the HDF5 file:")
for feature in features:
print(feature)
Input: 2022.05.07 00:43