Skip to content

Instantly share code, notes, and snippets.

@padix-key
Created April 28, 2022 14:11
Show Gist options
  • Save padix-key/51ce1123ab46e968a41971eaf4d6f3fb to your computer and use it in GitHub Desktop.
Save padix-key/51ce1123ab46e968a41971eaf4d6f3fb to your computer and use it in GitHub Desktop.
Example script that demonstrates how to combine different multi-row plots
# Code source: Patrick Kunzmann
# License: BSD 3 clause
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import biotite
import biotite.sequence as seq
import biotite.sequence.graphics as graphics
import biotite.sequence.io.genbank as gb
import biotite.sequence.align as align
import biotite.database.entrez as entrez
LENGTH_PER_ROW = 100
# Create 'FeaturePlotter' subclasses
# for drawing the scondary structure features
class HelixPlotter(graphics.FeaturePlotter):
def __init__(self):
pass
# Check whether this class is applicable for drawing a feature
def matches(self, feature):
if feature.key == "SecStr":
if "sec_str_type" in feature.qual:
if feature.qual["sec_str_type"] == "helix":
return True
return False
# The drawing function itself
def draw(self, axes, feature, bbox, loc, style_param):
# Approx. 1 turn per 3.6 residues to resemble natural helix
n_turns = np.ceil((loc.last - loc.first + 1) / 3.6)
x_val = np.linspace(0, n_turns * 2*np.pi, 100)
# Curve ranges from 0.3 to 0.7
y_val = (-0.4*np.sin(x_val) + 1) / 2
# Transform values for correct location in feature map
x_val *= bbox.width / (n_turns * 2*np.pi)
x_val += bbox.x0
y_val *= bbox.height
y_val += bbox.y0
# Draw white background to overlay the guiding line
background = Rectangle(
bbox.p0, bbox.width, bbox.height, color="white", linewidth=0
)
axes.add_patch(background)
axes.plot(
x_val, y_val, linewidth=2, color=biotite.colors["dimgreen"]
)
class SheetPlotter(graphics.FeaturePlotter):
def __init__(self, head_width=0.8, tail_width=0.5):
self._head_width = head_width
self._tail_width = tail_width
def matches(self, feature):
if feature.key == "SecStr":
if "sec_str_type" in feature.qual:
if feature.qual["sec_str_type"] == "sheet":
return True
return False
def draw(self, axes, feature, bbox, loc, style_param):
x = bbox.x0
y = bbox.y0 + bbox.height/2
dx = bbox.width
dy = 0
if loc.defect & seq.Location.Defect.MISS_RIGHT:
# If the feature extends into the prevoius or next line
# do not draw an arrow head
draw_head = False
else:
draw_head = True
axes.add_patch(biotite.AdaptiveFancyArrow(
x, y, dx, dy,
self._tail_width*bbox.height, self._head_width*bbox.height,
# Create head with 90 degrees tip
# -> head width/length ratio = 1/2
head_ratio=0.5, draw_head=draw_head,
color=biotite.colors["orange"], linewidth=0
))
# Fetch GenBank files of the TK's first chain and extract annotatation
gb_file = gb.GenBankFile.read(
entrez.fetch("1QGD_A", None, "gb", "protein", "gb")
)
annotation = gb.get_annotation(gb_file, include_only=["SecStr"])
sequence = gb.get_sequence(gb_file, "gp")
# Length of the sequence
_, length, _, _, _, _ = gb.get_locus(gb_file)
# Toy alignment of the sequence with itself
matrix = align.SubstitutionMatrix.std_protein_matrix()
alignment = align.align_ungapped(sequence, sequence, matrix)
fig, axes = plt.subplots(
nrows=2 * int(np.ceil(length/LENGTH_PER_ROW)),
figsize=(8.0, 12.0)
)
for i, start in enumerate(np.arange(0, length+1, LENGTH_PER_ROW)):
graphics.plot_feature_map(
axes[2*i], annotation,
symbols_per_line=LENGTH_PER_ROW, show_numbers=True,
# 'loc_range' takes exclusive stop -> length+1 is required
loc_range=(start+1, start+LENGTH_PER_ROW+1),
feature_plotters=[HelixPlotter(), SheetPlotter()]
)
graphics.plot_alignment_similarity_based(
axes[2*i+1], alignment[start:start+LENGTH_PER_ROW], matrix=matrix,
symbols_per_line=LENGTH_PER_ROW, show_numbers=True,
)
fig.tight_layout()
plt.savefig("combined_plots.png")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment