2015-11-27 15 views
11

Sto lavorando a un'implementazione di una classe per l'etichettatura in linea di oggetti linea. A tale scopo ho creato una sottoclasse della classe Text che come oggetto Line2D come attributo. Il codice nel mio previous post era forse un po 'lungo, così ho isolato il problema qui:Sottoclasse Matlotlib Testo: manipolazione proprietà dell'artista figlio

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() 

La classe prende il manico di un Line2D come restituito dalla funzione plot e nel metodo .draw, fa alcune modifiche alla linea. A scopo illustrativo, ho semplicemente cercato di cambiare colore.

Dopo aver modificato il colore della linea, chiamo le linee draw. Questo tuttavia non ha l'effetto previsto. Quando viene disegnata la figura, sembra che ci sia una sovrapposizione di una linea rossa e una nera. Non appena la figura viene ridimensionata o obbligata in altro modo a ridisegnare, la linea cambia colore come previsto. L'unico modo che ho trovato finora per forzare la figura a essere disegnata correttamente all'apertura era aggiungere plt.draw() prima dello show(). Questo tuttavia si sente goffo.

Posso forzare in qualche modo solo l'oggetto linea da ridisegnare? O sto sbagliando completamente?

Grazie in anticipo.

risposta

4

Il problema è che non si è l'aggiornamento della linea di fino a quando non viene ridisegnato, credo che questo dovrebbe funzionare:

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) 
+0

Grazie per la risposta. Non è esattamente quello che sto cercando però. Prendo l'handle per l'oggetto line da 'plt.plot' quindi è già stato aggiunto agli assi. Inoltre, non voglio aggiungere il testo stesso agli assi nel proprio '__init__' poiché questo non sembra essere il modo in cui gli artisti si comportano in matplotlib ... – thomas

Problemi correlati