Closed OuYaozhong closed 8 months ago
Difficult problem... Have you tried increasing force_text
?
Strange that the line1
text isn't moving in the first animation...
I have tried some ablation experiments, force_text
does not make sense.
Only increase force_points
makes a difference.
Noted:
I modify add the kwargs
to let the parameter be able to show in the picture:
force_text = [0.5, 0.5]
force_points = None
kwargs = {}
if force_text is not None:
kwargs.update({'force_text': force_text})
if force_points is not None:
kwargs.update({'force_points': force_points})
adjust_text(text_list, x=xy_repls[:, 0], y=xy_repls[:, 1], save_steps=True, avoid_self=True, avoid_text=True, **kwargs)
The whole test code is:
from adjustText import adjust_text
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from utils import get_line_repl_loc
import random
force_text = [0.5, 0.5]
force_points = None
fig = plt.figure(dpi=300)
ax = plt.subplot(111)
line1 = ax.plot([0, 1, 2], [1, 2, 3])[0]
line2 = ax.plot([0, 1, 2], [1, 2, 3])[0]
text_list = []
text_list.append(ax.text(x=0, y=1, s='line1', color=line1.get_color(), va='center', ha='center'))
text_list.append(ax.text(x=0, y=1, s='line2', color=line2.get_color(), va='center', ha='center'))
string = f'force_text = {force_text}, force_points = {force_points}'
fig.text(x=0.5, y=0, va='bottom', ha='center', s=string, color='k', transform=fig.transFigure)
# text_list.append(ax.annotate(xy=(0, 1), text='line1', color=line1.get_color(), va='center', ha='center', arrowprops=dict(arrowstyle='->', color='black')))
# text_list.append(ax.annotate(xy=(0, 1), text='line2', color=line2.get_color(), va='center', ha='center', arrowprops=dict(arrowstyle='->', color='black')))
xy_repls = get_line_repl_loc(line1)
fig.savefig('./test0.png')
scatter = ax.scatter(x=xy_repls[:, 0], y=xy_repls[:, 1], color='r', alpha=0.1)
fig.savefig('./test1.png')
kwargs = {}
if force_text is not None:
kwargs.update({'force_text': force_text})
if force_points is not None:
kwargs.update({'force_points': force_points})
adjust_text(text_list, x=xy_repls[:, 0], y=xy_repls[:, 1], save_steps=True, avoid_self=True, avoid_text=True, **kwargs)
fig.savefig('./test2.png')
force_text
1.1 increase to force_text=[0.5, 0.5]
adjust_text(text_list, x=xy_repls[:, 0], y=xy_repls[:, 1], save_steps=True, force_text=[0.5, 0.5], avoid_self=True, avoid_text=True)
1.2 increase to force_text = [2.0, 2.0]
force_points=[0.5, 0.5]
, only this one make a difference
It seems strange that force_points
makes sense instead of force_text
And when I add and arrow into the adjust_text, adjust_text(text_list, x=xy_repls[:, 0], y=xy_repls[:, 1], save_steps=True,
avoid_self=True, avoid_text=True, arrowprops=dict(arrowstyle='->', color='black')
, **kwargs)
, it shows that the arrowprops is conflict with the avoid_self
and avoid_text
Traceback (most recent call last):
File "***/test1.py", line 38, in <module>
adjust_text(text_list, x=xy_repls[:, 0], y=xy_repls[:, 1], save_steps=True, avoid_self=True, avoid_text=True, arrowprops=dict(arrowstyle='->', color='black'), **kwargs)
File "***/.conda/envs/py39torch110cu113/lib/python3.9/site-packages/adjustText/__init__.py", line 571, in adjust_text
ax.annotate("", # Add an arrow from the text to the point
File "***/.conda/envs/py39torch110cu113/lib/python3.9/site-packages/matplotlib/axes/_axes.py", line 666, in annotate
a = mtext.Annotation(text, xy, *args, **kwargs)
File "***/.conda/envs/py39torch110cu113/lib/python3.9/site-packages/matplotlib/text.py", line 1825, in __init__
Text.__init__(self, x, y, text, **kwargs)
File "***/.conda/envs/py39torch110cu113/lib/python3.9/site-packages/matplotlib/text.py", line 160, in __init__
self.update(kwargs)
File "***/.conda/envs/py39torch110cu113/lib/python3.9/site-packages/matplotlib/text.py", line 172, in update
super().update(kwargs)
File "***/.conda/envs/py39torch110cu113/lib/python3.9/site-packages/matplotlib/artist.py", line 1064, in update
raise AttributeError(f"{type(self).__name__!r} object "
AttributeError: 'Annotation' object has no property 'avoid_self'
The reason is the adjust_text use an empty matplotlib.text.Annotation
object to add an arrow into the text. And in the code of adjust_text
, the avoid_self
and avoid_text
is incompatible with the arrow objects which is matplotlib.text.Annotation
class. I don't know if relative to the problem.
It's been so long everything has changed now and hopefully works now? Feel free to reopen.
In many times, when we use matplotlib twinx to create two line in two axes but they share same x-axis, the first point and the last point may in the same position in figure coordinate.
If I want to annotate the start point and the end point, the annotation text will fully overlap. And the text should be repelled from the line to avoid overlap with the line too.
I found that in this situation, the adjust_text is unable to let the text separate.
Here is a simple demo. Very easy.
I have a repel function
get_line_repl_loc
to generate the interpolation point to repel text away from the lines.Here, first, we see the original plot:
Then, I plot the
xy_repls
by functionscatter
, we can see thexy_repls
are correct.Finally, use the
adjust_text
to move the text objects, with the limitation to be away from the line with dense point, avoid text itself and each otheravoid_self=True
andavoid_text=True
It seem the
adjust_text
did nothing.I visualise the operation of the
adjust_text
bysave_steps=True
. Here is the gifAutoalign separate the text each other, but the algorithm moves them closer and closer. Why? Or how to solve it?
If disable point repelling, it work well but just will overlap with the line instead of text each other.
adjust_text(text_list, avoid_self=True, avoid_text=True, save_steps=True)
I have try
expand_text
orforce_point
, both of them is useless, except that I add the text itself into theadd_objects
, but this kind of solution is meaningless.adjust_text(text_list, avoid_self=True, avoid_text=True, save_steps=True, add_objects=text_list)
This problem I have mention in #124 also.
So can owner gives some explanation or it just a bug?
Environment: numpy version 1.21.2 matplotlib version 3.5.1
$ conda list | grep adjust adjusttext 0.7.3.1 py_1 conda-forge