如何使用Sympy` plot`的`_backend`属性

时间:2017-05-09 12:07:07

标签: python plot sympy

在下面的例子中,我使用Sympy制作一个情节:

from sympy import symbols, plot
x = symbols('x')
p = plot(x*x, x**3, (x, -2, 2), show=False)
for n, line in enumerate(p, 2): 
    line.label='$x^{%d}$'%n
    line.line_color = ['k', 'r'][n-2]
p.legend = True

x2x3.png

正如你所看到的,传说被放置在线上而Sympy没有 提供改变传奇位置的直接方式。

经过一些研究,我发现,直接在源代码中 */sympy/plotting/plot.py,此评论:

  

特别是如果您需要发布就绪图并且此模块是   对你来说还不够 - 只需获取_backend属性并添加即可   无论你想要什么直接。在matplotlib的情况下(   在python中绘制数据的常用方法)只需复制_backend.fig即可   是数字和_backend.ax,它是轴并对它们起作用   就像你在任何其他matplotlib对象上一样。

因此我尝试了

be = p._backend 

但我得到的是:

AttributeError: 'Plot' object has no attribute '_backend'

如何移动图例或以其他方式调整图表 使用此._backend属性?

▶P u,d甲T E◀

又一次访问源代码后,我意识到._backend 只有在将绘图提交到屏幕后才会实例化属性, 与p.show()中一样。

有了这些新知识,我总是在交互式翻译中 试图

...
p.show()
p._backend.ax.legend(loc='4') # bottom right

并使用"更正"中的图例位置更新了情节。的地方。

我解决了我的问题吗?我害怕我没有,因为这适用于 一个IPython会话,当你发布了IPython的魔力 %matplotlib(可以与现场情节互动),并且,afaict, 只有在这些条件下。

特别是。 以下代码,作为脚本执行,

from sympy import symbols, plot 
x = symbols('x')
p = plot(x*x, x**3, (x, -2, 2), show=False)
for n, line in enumerate(p, 2): 
    line.label='$x^{%d}$'%n
    line.line_color = ['k', 'r'][n-2]
p.legend = True
p.show()
p._backend.ax.legend(loc=4) # bottom-right
p.save('plot_with_legend_OK_maybe.png')

将带有图例的图表保存在右上角的绘制线上。

所以这是我的

的更新版本

Q U E S T I O N

是否可以使用其.backend属性更改绘图,并将更改保留在已保存的图像文件中?

1 个答案:

答案 0 :(得分:1)

快速回答:

使用p._backend.fig.savefig('plot_with_legend_OK.png')代替p.save('..')

据我所知,这使用了来自matplotlib的savefig命令(如果你想知道可以使用的其他选项)。

为什么它不起作用的长(呃)故事。我们可以查看self.save(path)时调用的p.save('plot_with_legend_OK_maybe.png')代码。

    def save(self, path):
    if hasattr(self, '_backend'):
        self._backend.close()
    self._backend = self.backend(self)
    self._backend.save(path)

如您所见,如果_backend已建立,则会关闭,将调用新的backend,然后使用此后端保存数字。这将有效地撤消您在此之前对后端所做的所有更改。这就是为什么你不能在使用matplotlib后端改变的图上使用sympy show()save()命令。

原因是简单性,正如sympy here的开发人员所给出的那样:

  

简单的代码比性能更重要。   不要使用它   如果你完全关心表现。初始化新的后端实例   每次你打电话给show(),旧的都留给垃圾收集器。

也适用于save()