子类化matplotlib文本:操纵子艺术家的属性

时间:2015-11-27 15:41:16

标签: python python-2.7 matplotlib

我正在开发一个用于行对象内联标记的类的实现。为此,我创建了Text类的子类,它作为Line2D对象作为属性。我previous post中的代码可能有点冗长,所以我在这里解决了这个问题:

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 个答案:

答案 0 :(得分:4)

问题是你没有更新行,直到重绘,我认为这应该有用:

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)