脚本中的以下代码按预期工作,
from sympy import *
x = symbols('x')
p = plot(x, x*(1-x), (x, 0, 1))
ax = p._backend.ax[0]
ax.set_yticks((0, .05, .25))
p._backend.fig.savefig('Figure_1.png')
但是当我将上面的代码复制到笔记本单元中时,这就是我得到的
如果在 Jupyter 笔记本中工作时可以操纵 Sympy
plot
的(隐藏)属性,该怎么做?
p.backend(p)
。sympy.plotting.plot.plot(*args, show=True, **kwargs)
创建自己的图形和轴并且plots.show()
立即显示绘图。
ax.set_yticks((0, .05, .25))
实施更改之前显示的。python v3.12.0
、matplotlib v3.8.1
、sympy v1.11.1
进行测试。from sympy import symbols, plot
import matplotlib.pyplot as plt
x = symbols('x')
# note show=False, the default is True
p = plot(x, x*(1-x), (x, 0, 1), show=False)
fig, ax = plt.subplots()
backend = p.backend(p)
backend.ax = ax
backend._process_series(backend.parent._series, ax, backend.parent)
backend.ax.set_yticks((0, .05, .25))
plt.close(backend.fig)
plt.show()
%matplotlib qt
,OP中的代码工作正常。from sympy import symbols, plot
import matplotlib.pyplot as plt
%matplotlib qt # %matplotlib inline - to revert to inline
x = symbols('x')
p = plot(x, x*(1-x), (x, 0, 1))
ax = p._backend.ax[0]
ax.set_yticks((0, .05, .25))
这样做的优点是
matplotlib
不应显式导入。
人们应该知道你在做什么:
sympy
提供了一个随时可用的界面来动态绘制函数,而无需担心(无聊的)数学技术细节,例如域/范围。相反,如果您尝试违反此类默认设置,则需要返回源代码并进行一些逆向工程。
在 OP 中,需要自定义 ticks,但默认情况下,
MatplotlibBackend
从 linear
对象
sympy.plotting.plot.Plot
获取 xscale='linear', yscale='linear'
的 x 和 y 刻度,这会干扰 matplotlib.axes.Axes.set_yticks
方法。
来自源代码
1467 if parent.yscale and not isinstance(ax, Axes3D):
1468 ax.set_yscale(parent.yscale)
很明显,通过将
parent.yscale
设置为 False
(或 None
、''
),条件将永远不会满足。这是一个最小的解决方案。
from sympy.plotting.plot import MatplotlibBackend
from sympy import symbols
class JupyterPlotter(MatplotlibBackend):
def _process_series(self, series, ax, parent):
parent.yscale = False
ax.set_yticks((0, .05, .25)) # custom yticks
super()._process_series(series, ax, parent)
x = symbols('x')
p = plot(x, x*(1-x), (x, 0, 1), backend=JupyterPlotter)
有特殊需求的地块可能需要特殊的实现,这里是一个不同的例子。
文档表明下面正在使用matplotlib。使用此方法进行调整的示例位于 “如何更改 sympy 图线型?”的答案中:
“您可以使用 .... sympy 绘图对象的 _backend 属性来访问相应 matplotlib 绘图对象的所有属性”