在下面的例子中,我使用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
正如你所看到的,传说被放置在线上而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
属性更改绘图,并将更改保留在已保存的图像文件中?
答案 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()
。