Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotate/extend label radius to prevent overlaps #459

Open
bhagesh-codebeast opened this issue Feb 8, 2023 · 5 comments
Open

Rotate/extend label radius to prevent overlaps #459

bhagesh-codebeast opened this issue Feb 8, 2023 · 5 comments

Comments

@bhagesh-codebeast
Copy link

bhagesh-codebeast commented Feb 8, 2023

Hi,
Thank you for this amazing module, It helped me a lot in learning about plasmids.
I am trying to plot a plasmid map, and have a query regarding the same.

Is there any parameter to rotate or increase the radius of labels to prevent overlaps as seen in the figure?
I tried almost all matplotlib parameters nothing seems to affect the alignment:

image

I know there is a switch omit_oversized_labels to hide the oversized ones, but I need all labels to be visible.

Thanks in advance.

@padix-key
Copy link
Member

padix-key commented Feb 9, 2023

I fear this is not easily possible. The rotation of the labels is fixed by plot_plasmid_map(). Could you specifiy, what you mean by radius of labels? The only flexible parameter to influence all labels in the same way is label_properties.

Alternatively you can obtain the underlying Matplotlib Text objects via something like

labels = [artist for artist in ax.get_children() if isinstance(artist, Text)]

Note that this list will also contain the label for the plasmid name and that each feature label is separated into multiple Text objects to achieve the appearance of rotated text.

@bhagesh-codebeast
Copy link
Author

bhagesh-codebeast commented Feb 13, 2023

Thank you for the quick response @padix-key
by radius of labels, I was referring to moving the overlapping labels inwards or outwards.

image

I found a package to adjust labels: https://github.com/Phlya/adjustText
but this will only space the labels accordingly and it might misplace them.

@padix-key
Copy link
Member

You could play with the horizontalalignment and verticalalignment parameters of the Text instances, but again, I think it will not be easy, as each label comprises multiple Text instances. I fear, in the moment there is no really satisfactory solution to this problem and I also see no easy algorithmic approach to solve this problem.

@tfenne
Copy link

tfenne commented Apr 7, 2023

I'm also running into this issue, and have a couple of suggestions, at least one of which I hope might be feasible.

plot_plasmid_map already automatically determines where there are overlapping features, and pushes features to extra layers so as to avoid overlap. And it would seem it also can compute the width of the text (to determine if it exceeds the shape). Could there be an option to use the maximum of the feature length or the label length, when deciding whether or not to push features to another layer/track?

Alternatively, what I've seen elsewhere for features that are too small to support labeling directly is to produce callouts with labels. I'm not sufficiently expert in matplotlib to do that myself, but it seems tractable.

@padix-key
Copy link
Member

Could there be an option to use the maximum of the feature length or the label length, when deciding whether or not to push features to another layer/track?

The length of a feature is proportional to the angle the feature indicator comprises. However, the angle, the feature label requires, depends on the radius from the center, i.e. on the track itself. For example, if you push a feature indicator onto a more central track, the label angle increases and hence might now overlap with another feature. So this unfortunately becomes a non-trivial optimization problem, if I am not wrong. As alternative we could push an indicator onto higher tracks until the label fits, but this might lead to highly suboptimal feature placements, as much more tracks may be occupied. Would this be a viable solution?

Alternatively, what I've seen elsewhere for features that are too small to support labeling directly is to produce callouts with labels. I'm not sufficiently expert in matplotlib to do that myself, but it seems tractable.

I think this might be a doable solution, although the placement might be a problem in this case. The positions of annotations in Matploltlib cannot be automized, as the attempt of implemeting this were fruitless (matplotlib/matplotlib#1313). However, if we would find dedicated positions for such labels this could work. Another possibility would be some kind of footnote for oversized labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants