Подтвердить что ты не робот

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(). Это, однако, кажется неуклюжим.

Могу ли я каким-то образом изменить только объект линии, который нужно перерисовать? Или я делаю это совершенно неправильно?

Спасибо заранее.

4b9b3361

Ответ 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)