biotite icon indicating copy to clipboard operation
biotite copied to clipboard

Rotate/extend label radius to prevent overlaps

Open bhagesh-h opened this issue 2 years ago • 5 comments
trafficstars

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.

bhagesh-h avatar Feb 08 '23 15:02 bhagesh-h

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.

padix-key avatar Feb 09 '23 11:02 padix-key

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.

bhagesh-h avatar Feb 13 '23 08:02 bhagesh-h

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.

padix-key avatar Feb 13 '23 13:02 padix-key

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.

tfenne avatar Apr 07 '23 19:04 tfenne

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 (https://github.com/matplotlib/matplotlib/issues/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.

padix-key avatar Apr 09 '23 14:04 padix-key