如何使用 Sympy `plot` 的 `_backend` 属性 [英] How do I use the `_backend` attribute of a Sympy `plot`

查看:77
本文介绍了如何使用 Sympy `plot` 的 `_backend` 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的例子中,我使用 Sympy 来绘制一个图:

In the following example I use Sympy to make a plot:

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

如您所见,图例放置在线条上而 Sympy 没有提供改变图例位置的直接方法.

As you can see, the legend is placed over the lines and Sympy doesn't offer a direct way to change the position of the legend.

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

After some research I found, directly in the source code of */sympy/plotting/plot.py, this comment:

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

Especially if you need publication ready graphs and this module is not enough for you - just get the _backend attribute and add whatever you want directly to it. In the case of matplotlib (the common way to graph data in python) just copy _backend.fig which is the figure and _backend.ax which is the axis and work on them as you would on any other matplotlib object.

因此我尝试了

be = p._backend 

但我得到的是:

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

我应该怎么做才能移动图例或以其他方式调整情节使用这个 ._backend 属性?

What should I do to move the legend or to otherwise tweak the plot using this ._backend attribute?

▶ U P D A T E ◀

再次访问源代码后,我意识到._backend属性仅在绘图提交到屏幕后实例化,如p.show().

After another trip to the source code I realized that the ._backend attribute is instantiated only after the plot is committed to the screen, as in p.show().

有了这些新知识,总是在交互式解释器中,我试过

With this new knowledge, always in the interactive interpreter, I tried

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

并且用正确"位置的图例位置更新了情节.

and the plot was updated with the legend location in the "correct" place.

我的问题解决了吗?恐怕我没有,因为这适用于一个 IPython 会话,当您发出 IPython 的魔法时%matplotlib(能够与实时情节交互)以及,事实上,仅在这些条件下.

Have I solved my problem? I'm afraid I've not, because this works in an IPython session, when you have issued the IPython's magic %matplotlib (that enables to interact with a live plot) and, afaict, only under these conditions.

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

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

保存绘图,图例位于右上角,在绘制的线条上.

所以这是我的更新版本

问题

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

Is it possible to change the plot, using its .backend attribute, and have the changes persisted in a saved image file?

推荐答案

快速回答:

使用 p._backend.fig.savefig('plot_with_legend_OK.png') 而不是 p.save('..').

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

This uses the savefig command from matplotlib as far as I know (if you want to know other options you can use).

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

The long(er) story of why it doesn't work. We can look at the code for self.save(path) which is called when you do 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() 命令.

As you can see, if a _backend is established it will be closed, a new backend will be called and then it will save the figure using this backend. This will effectively undo all changes you did to the backend before then. That is why you cannot use the sympy show() and save() commands on plots that you have altered using the matplotlib backend.

这样做的原因很简单,正如 sympy 的开发人员给出的那样 此处:

The reason for this is simplicity, as given by the developers of sympy here:

代码的简单性比性能更重要.不要使用它如果您完全关心性能.一个新的后端实例被初始化每次调用 show() 时,旧的都会留给垃圾收集器.

Simplicity of code takes much greater importance than performance. Don't use it if you care at all about performance. A new backend instance is initialized every time you call show() and the old one is left to the garbage collector.

这也适用于 save().

这篇关于如何使用 Sympy `plot` 的 `_backend` 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆