Edinburgh-Genome-Foundry / DnaFeaturesViewer

:eye: Python library to plot DNA sequence features (e.g. from Genbank files)
https://edinburgh-genome-foundry.github.io/DnaFeaturesViewer/
MIT License
585 stars 90 forks source link

Aligning two sequences #90

Open cmfield opened 5 days ago

cmfield commented 5 days ago

If I am using subplots to plot multiple sequences, is it possible to offset the plot in the x-axis? Then I can align parts of the plot that belong together.

I've tried changing first_index, modifying the xlims of individual axes, but I think I'm missing something obvious.

veghp commented 2 days ago

Hi thanks for trying this package. I'm not aware of an easy or built-in way of doing this. A workaround hack would be to add (random) bases to the beginning of the shorter sequence to align it up with the longer one. Another option is to try and do this through matplotlib: https://stackoverflow.com/questions/37241029/can-i-move-about-the-axes-in-a-matplotilb-subplot

cmfield commented 2 days ago

I found a hack in the end. After making the graphic records, I located the feature I wanted to line up in each record and its position and orientation. I flipped every sequence record that was the wrong way around and remade the graphic records. Then the longest sequence gave me an anchor position, and I shifted every other graphic record feature by the difference between the anchor and its feature-of-interest position, then changed .first_index to this offset.

Then in matplotlib subplots, I use sharex=False, and fix the xlimits to be the same for every plot. It worked.. though I'm not sure how robustly :)

veghp commented 2 days ago

Thank you for describing this, it will be a good reference for the future.

Zulko commented 2 days ago

You can use Matplotlib's fig.add_gridspec(number_of_sequences, number_of_columns) to create shifted subplots. It will require some math to position the plots but the result is neat and it lets you plot whatever dna_features_viewer can plot without changing your records.

import matplotlib.pyplot as plt
from dna_features_viewer import GraphicFeature, GraphicRecord

fig = plt.figure(figsize=(12, 2))  # Set a large width to allow for shifting
grid = fig.add_gridspec(2, 200)  # Two rows, 200 column or as many as necessary

# PLOT 1

features1 = [
    GraphicFeature(start=0, end=50, strand=+1, color="#ffcccc", label="Feature 1"),
    GraphicFeature(start=100, end=150, strand=-1, color="#ccccff", label="Feature 2"),
]
record1 = GraphicRecord(sequence_length=200, features=features1)
ax1 = fig.add_subplot(grid[0, 0:150])
record1.plot(ax=ax1, with_ruler=True)

# PLOT 2

features2 = [
    GraphicFeature(start=10, end=60, strand=+1, color="#ccffcc", label="Feature 3"),
    GraphicFeature(start=120, end=180, strand=-1, color="#ffcc99", label="Feature 4"),
]
record2 = GraphicRecord(sequence_length=200, features=features2)
ax2 = fig.add_subplot(grid[1, 50:200])
record2.plot(ax=ax2, with_ruler=True)

image