Created
April 28, 2022 14:11
-
-
Save padix-key/51ce1123ab46e968a41971eaf4d6f3fb to your computer and use it in GitHub Desktop.
Example script that demonstrates how to combine different multi-row plots
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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