Search code examples
pythonmatplotlib

Matplotlib imshow and dna_features_viewer: Align X axis


I can't find a solution to align on the X-axis a matplotlib imshow with a dna features viewer plot.

The python3 code I used is:

from dna_features_viewer import GraphicFeature, GraphicRecord
import matplotlib
from matplotlib import rcParams
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd


rcParams["figure.figsize"] = 15, 12
fig, (ax0, ax1) = plt.subplots(2, 1, height_ratios=[5, 1], sharex=True)

# ax0
data_heatmap = np.random.rand(850, 850)
heatmap = ax0.imshow(data_heatmap, cmap="bone")
fig.colorbar(heatmap, ax=ax0)
ax0.set_xlabel("Scored Residue")
ax0.set_ylabel("Aligned Residue")
ax0.set_ylim(len(data_heatmap) + 1, 1)

# ax1
domains = pd.DataFrame({"domain": ["dom1", "dom2", "dom3"],
                        "start": [9, 516, 714],
                        "end": [459, 689, 850],
                        "color": ["#0000b6", "#02eded", "#ab0000"]})
features = []
for _, row in domains.iterrows():
    features.append(GraphicFeature(start=row["start"], end=row["end"], strand=+1, color=row["color"],
                                   label=row["domain"]))
record = GraphicRecord(sequence_length=row["end"] + 1, features=features, plots_indexing="genbank")
record.plot(ax=ax1)


plt.tight_layout()
plt.show()

Which produces the following plot:

enter image description here

But I would like the X axis of ax0 and ax1 to be on the same physical scale (same length).

enter image description here

Any idea?


Solution

  • To shrink ax1 to the width of ax0, add the following lines after plt.tight_layout():

    ax0p, ax1p = ax0.get_position(), ax1.get_position()
    ax1.set_position([ax0p.x0, ax1p.y0, ax0p.width, ax1p.height]) 
    

    enter image description here