Subclassing matplotlib Текст: манипулировать свойствами дочернего исполнителя
Я работаю над реализацией класса для встроенной маркировки объектов линии. Для этого я создал подкласс класса Text
, который как объект Line2D
как атрибут. Код в предыдущем сообщении был, возможно, немного длинным, поэтому я выделил проблему здесь:
from matplotlib.text import Text
from matplotlib import pyplot as plt
import numpy as np
class LineText(Text):
def __init__(self,line,*args,**kwargs):
x_pos = line.get_xdata().mean()
y_pos = line.get_ydata().mean()
Text.__init__(self,x=x_pos,y=y_pos,*args,**kwargs)
self.line = line
def draw(self,renderer):
self.line.set_color(self.get_color())
self.line.draw(renderer = renderer)
Text.draw(self,renderer)
if __name__ == '__main__':
x = np.linspace(0,1,20)
y = np.linspace(0,1,20)
ax = plt.subplot(1,1,1)
line = plt.plot(x,y,color = 'r')[0]
linetext = LineText(line,text = 'abc')
ax.add_artist(linetext)
plt.show()
Класс берет дескриптор Line2D
как возвращаемый функцией plot
и в методе .draw
, он вносит некоторые изменения в строку. В целях иллюстрации я здесь просто попытался изменить свой цвет.
После изменения цвета строки я вызываю строки draw
. Однако это не имеет ожидаемого эффекта. Когда рисунок сначала рисуется, кажется, что наложение красной и черной линий. Как только размер будет изменен или будет принудительно перерисован, линия изменит свой цвет, как ожидалось. Единственный способ, который я нашел до сих пор, чтобы заставить рисунок правильно рисовать при открытии, заключался в том, чтобы добавить plt.draw()
до show()
. Это, однако, кажется неуклюжим.
Могу ли я каким-то образом изменить только объект линии, который нужно перерисовать? Или я делаю это совершенно неправильно?
Спасибо заранее.
Ответы
Ответ 1
Проблема в том, что вы не обновляете строку до ее перерисовывания, я думаю, что это должно работать:
class LineText(Text):
def __init__(self,line,*args,**kwargs):
x_pos = line.get_xdata().mean()
y_pos = line.get_ydata().mean()
Text.__init__(self,x=x_pos,y=y_pos,*args,**kwargs)
self.line = line
self.line.set_color(self.get_color())
plt.gca().add_artist(self.line) # You could also pass `ax` instead of calling `plt.gca()`
plt.gca().add_artist(self)
if __name__ == '__main__':
x = np.linspace(0,1,20)
y = np.linspace(0,1,20)
ax = plt.subplot(1,1,1)
line = plt.plot(x,y, 'r--', alpha=0.5)[0]
linetext = LineText(line,text = 'abc')
# ax.add_artist(linetext) # Artist is being added in `__init__` instead
plt.show(block=False)