我不认为有很好的支持,但你可以尝试类似这样的东西
import matplotlib.pyplot
from numpy import arange
from numpy import meshgrid
delta = 0.025
xrange = arange(-5.0, 20.0, delta)
yrange = arange(-5.0, 20.0, delta)
X, Y = meshgrid(xrange,yrange)
# F is one side of the equation, G is the other
F = Y**X
G = X**Y
matplotlib.pyplot.contour(X, Y, (F - G), [0])
matplotlib.pyplot.show()
请参考API文档中的contour
部分:如果第四个参数是一个序列,则指定需要绘制哪些等高线。但是,绘图的质量取决于范围的分辨率,并且有些特征可能永远无法正确显示,通常会在自交点处发生。
既然您在问题中打了sympy标签,我将给出一个示例。
来自文档:http://docs.sympy.org/latest/modules/plotting.html。
from sympy import var, plot_implicit
var('x y')
plot_implicit(x*y**3 - y*x**3)
Matplotlib无法绘制方程,它只能绘制一系列点。您可以使用scipy.optimize
等工具从隐式方程中数值计算y值和x值(或反之亦然),或者使用其他适当的工具。
例如,这里是一个示例,我在某个区域绘制了隐式方程x ** 2 + x * y + y ** 2 = 10
。
from functools import partial
import numpy
import scipy.optimize
import matplotlib.pyplot as pp
def z(x, y):
return x ** 2 + x * y + y ** 2 - 10
x_window = 0, 5
y_window = 0, 5
xs = []
ys = []
for x in numpy.linspace(*x_window, num=200):
try:
# A more efficient technique would use the last-found-y-value as a
# starting point
y = scipy.optimize.brentq(partial(z, x), *y_window)
except ValueError:
# Should we not be able to find a solution in this window.
pass
else:
xs.append(x)
ys.append(y)
pp.plot(xs, ys)
pp.xlim(*x_window)
pp.ylim(*y_window)
pp.show()
f(x, y) = x
和 g(x, y) = a
这样微不足道的东西将完全失败。(确切的失败模式取决于插值点是否碰到该线或未碰到。) - KeithWM>>> from sympy.plotting import plot_implicit
>>> p = plot_implicit(x < sin(x)) # also creates a window with the plot
>>> the_matplotlib_axes_instance = p._backend._ax
the_matplotlib_axes_instance
是从哪里来的? - theV0IDp
是您创建的图表。p._backend._ax
将是轴实例,如果您希望,可以将其引用到一个新变量中,并将其用于任何您想使用 matplotlib 轴实例的地方。 - Krastanov编辑: 如果使用plt.plot()绘制双曲线,则会得到不期望的分支效果。可使用plt.scatter()代替,这仍然有效。然后就没有必要颠倒负值或正值的顺序了,但如果您因某种原因想要使用此代码(而不是使用来自scipy的轮廓图),则使用plt.scatter()仍将起作用
在二维中的隐式函数通常可以写成:
f(x,y)=0
由于我们无法将其写成f(x) = y的形式,因此我们无法从易于编程的离散x集合计算y。但是,可以看出从网格生成的点与真实函数相差多远。
因此,将x和y的网格映射到自定义点密度,并查看每个点满足方程的接近程度。
换句话说,如果我们无法获得f(x,y) = 0,则可以接近0。不是寻找f(x,y) = 0而是寻找f(x,y)>-\epsilon和f(x,y)<\epsilon。
\epsilon 是您的容差,如果此条件符合您的0容差并适当调整网格,则可以绘制函数。
以下代码对于半径为1的圆(f(x,y)= x^2 + y^2 -1 = 0)就是那样做的。我使用符号dr表示\epsilon。
此外,为了确保plt.plot函数按正确顺序连接线条,我对负y值的x值使用了反转版本。这样,f(x,y)的计算将在顺时针循环中完成,以便最近的值一个接一个地出现。否则,来自函数相反两侧的线条将连接在一起,并且看起来稍微填充。
import numpy as np
import matplotlib.pyplot as plt
r = 1 #arbitrary radius to set up the span of points
points = 250
dr = r/points #epsilon window
x=list(np.linspace(-5*r,5*r,5*points+1)) #setting up the x,y grid
y=x
xreversed = reversed(x) #reversing the array
x_0=[] #placeholder arrays
y_0=[]
for i in x:
for j in y:
if i**2 + j**2 -1 < dr and i**2+j**2 -1 > -dr and j >= 0: #positive values of y
x_0.append(i)
y_0.append(j)
for i in xreversed:
for j in y:
if i**2+j**2 -1 < dr and i**2+j**2 -1 > -dr and j < 0: #negative values of y, using x reversed
x_0.append(i)
y_0.append(j)
plt.plot(x_0,y_0)
plt.show()
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
import numpy as np
fig = plt.figure(1)
ax = fig.add_subplot(111)
# set up axis
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# setup x and y ranges and precision
x = np.arange(-0.5,5.5,0.01)
y = np.arange(-0.5,5.5,0.01)
# draw a curve
line, = ax.plot(x, x**2,zorder=100)
# draw a contour
X,Y=np.meshgrid(x,y)
F=X**Y
G=Y**X
ax.contour(X,Y,(F-G),[0],zorder=100)
#set bounds
ax.set_xbound(-1,7)
ax.set_ybound(-1,7)
#produce gridlines of different colors/widths
ax.xaxis.set_minor_locator(MultipleLocator(0.2))
ax.yaxis.set_minor_locator(MultipleLocator(0.2))
ax.xaxis.grid(True,'minor',linestyle='-')
ax.yaxis.grid(True,'minor',linestyle='-')
minor_grid_lines = [tick.gridline for tick in ax.xaxis.get_minor_ticks()]
for idx,loc in enumerate(ax.xaxis.get_minorticklocs()):
if loc % 2.0 == 0:
minor_grid_lines[idx].set_color('0.3')
minor_grid_lines[idx].set_linewidth(2)
elif loc % 1.0 == 0:
minor_grid_lines[idx].set_c('0.5')
minor_grid_lines[idx].set_linewidth(1)
else:
minor_grid_lines[idx].set_c('0.7')
minor_grid_lines[idx].set_linewidth(1)
minor_grid_lines = [tick.gridline for tick in ax.yaxis.get_minor_ticks()]
for idx,loc in enumerate(ax.yaxis.get_minorticklocs()):
if loc % 2.0 == 0:
minor_grid_lines[idx].set_color('0.3')
minor_grid_lines[idx].set_linewidth(2)
elif loc % 1.0 == 0:
minor_grid_lines[idx].set_c('0.5')
minor_grid_lines[idx].set_linewidth(1)
else:
minor_grid_lines[idx].set_c('0.7')
minor_grid_lines[idx].set_linewidth(1)
plt.show()