DnaFeaturesViewer icon indicating copy to clipboard operation
DnaFeaturesViewer copied to clipboard

Feature annotation below track

Open erica-pathos opened this issue 6 months ago • 7 comments

Added an option to place label below track.

erica-pathos avatar Jun 12 '25 03:06 erica-pathos

Thank you for this contribution. I agree it would be useful (cf. https://github.com/Edinburgh-Genome-Foundry/DnaFeaturesViewer/issues/47), for example to show features relevant for the negative strand. I'll have to review this in detail as it's a very important package for us, which will take some time, but please keep this PR open.

veghp avatar Jun 25 '25 16:06 veghp

Note that if you want all features to appear below the track, the simplest is to use ax.invert_yaxis(). This could be added to the examples.

from dna_features_viewer import GraphicFeature, GraphicRecord

features=[
    GraphicFeature(start=0, end=20, strand=+1, label="Small feature"),
    GraphicFeature(start=20, end=500, strand=+1, color="#ffcccc",
                   label="Gene 1 with a very long name"),
]
record = GraphicRecord(sequence_length=600, features=features)
ax, _ = record.plot(figure_width=4)

# Put the labels below the tracks
ax.invert_yaxis()
ax.xaxis.set_ticks_position('top')

image

If the goal is to have labels both above and below the track, then we must be careful with compute_feature_levels(), which should probably be called separately to compute the levels of the features above the plot and those below the plot.

Zulko avatar Jun 30 '25 14:06 Zulko

Thank you for this, yes all features wanted below the track, at least for this issue. I'll add this as an example, perhaps mention in the main readme as well.

veghp avatar Jun 30 '25 15:06 veghp

Thanks for the response, the reason why I would want the label to be on the bottom (also the axis, tick labels etc), is that I want to be able to add other features on top (like lollipop plots etc.)

I guess I could add lollipop bars by adding a negative to the y axis numbers, but it would be nice to have that flexible option. and more intuitive in adding other features?

erica-pathos avatar Jun 30 '25 15:06 erica-pathos

Hmm yes that's a good use case, but in that case the parameter should be something like graphic_record.plot(features_below_track=True) to apply to all features at once, rather than at the feature level in GraphicFeature() which will be problematic if compute_feature_levels() isn't called twice on the two groups of features.

Zulko avatar Jun 30 '25 18:06 Zulko

I guess that works too? For my use case, the lollipops were added to the ax using generic plotting functions, in addition to the genome features, so I guess your way should work too.

Then I guess in other cases to plot two group of labels, one on top and other on the bottom, we can just do graphic_record.plot(features_below_track=True) and graphic_record.plot(features_below_track=False) on the same ax, and we can have both group labels on both side? Instead of defining each GraphicFeature to be below or above track?

Btw, I would still prefer that the features_below_track=True doesn't just invert the y axis though, when I add additional features like lollipop, the exact Y axis and the values do matter, I would like to have the option to still add those numbers as positive values.

erica-pathos avatar Jun 30 '25 19:06 erica-pathos

Yes to clarify what I meant was features_below_track=True that causes the plotter to transform y to -y before plotting the features, and hopefully this is enough to get them plotted in "negative" while keeping the general layout, and without needing to invert the axis. I won't have time to make an MR but that would be my preference for implementation.

Zulko avatar Jun 30 '25 19:06 Zulko