Можно ли построить неявные уравнения с помощью Matplotlib?
Я хотел бы построить неявные уравнения (вида f(x, y)=g (x, y), например. X^y=y^x) в Matplotlib. Возможно ли это?
7 ответов
Я не верю, что для этого есть очень хорошая поддержка, но вы можете попробовать что-то вроде
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 docs на contour
: если четвертый аргумент является последовательностью, он указывает, какие контурные линии следует построить. Но сюжет будет так же хорош, как разрешение ваших диапазонов, и есть определенные функции, которые он может никогда не получить правильно, часто в точках пересечения.
поскольку вы пометили этот вопрос с симпатией, я приведу такой пример.
из документации: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()
существует неявное уравнение (и неравенство) плоттера в sympy. Он создается как часть GSoC и создает графики как экземпляры фигур matplotlib.
документы на http://docs.sympy.org/latest/modules/plotting.html#sympy.plotting.plot_implicit.plot_implicit
начиная с версии sympy 0.7.2-это:
>>> 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
Если вы хотите использовать что-то другое, кроме matplotlib (но все же python), есть sage:
пример:http://sagenb.org/home/pub/1806
большое спасибо Стив, Майк, Алекс. Я согласился с решением Стива (см. код ниже). Моя единственная оставшаяся проблема заключается в том, что контурный график появляется за моими линиями сетки, в отличие от обычного графика, который я могу заставить спереди с помощью zorder. Еще один халп очень признателен.
Ура, Геддес!--2-->
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()
Примеры (с использованием контурного подхода) для всех конических сечений доступны вhttp://blog.mmast.net/conics-matplotlib