python - real - ¿Es posible trazar ecuaciones implícitas usando Matplotlib?
matplotlib python (7)
Me gustaría trazar ecuaciones implícitas (de la forma f (x, y) = g (x, y), por ejemplo, X ^ y = y ^ x) en Matplotlib. es posible?
Como has etiquetado esta pregunta con sympy, daré un ejemplo.
De la documentación: 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)
Ejemplos (utilizando el enfoque de contorno) para todas las secciones cónicas están disponibles en http://blog.mmast.net/conics-matplotlib
Hay un trazador de ecuación implícita (y desigualdad) en sympy. Se crea como parte de GSoC y produce las representaciones como instancias de figuras matplotlib.
Documentos en http://docs.sympy.org/latest/modules/plotting.html#sympy.plotting.plot_implicit.plot_implicit
Dado que la versión de sympy 0.7.2 está disponible como:
>>> 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
Muchas gracias Steve, Mike, Alex. He seguido la solución de Steve (ver el código a continuación). Mi único problema restante es que la trama de contorno aparece detrás de mis líneas de cuadrícula, a diferencia de una trama regular, que puedo forzar al frente con zorder. Cualquier halp más apreciado.
Saludos, Geddes
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()
No creo que haya un buen soporte para esto, pero podrías intentar algo como
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()
Ver los documentos API para el contour
: si el cuarto argumento es una secuencia, entonces especifica qué líneas de contorno trazar. Pero la trama solo será tan buena como la resolución de tus rangos, y hay ciertas características que pueden no ser correctas, a menudo en los puntos de autointersección.
Si está dispuesto a usar algo que no sea matplotlib (pero aún python), hay sabio:
Un ejemplo: http://sagenb.org/home/pub/1806
matplotlib no grafica ecuaciones; traza series de puntos. Puede usar una herramienta como scipy.optimize
para calcular numéricamente y puntos a partir de x valores (o viceversa) de ecuaciones implícitas numéricamente o cualquier cantidad de otras herramientas, según corresponda.
Por ejemplo, he aquí un ejemplo en el que trazo la ecuación implícita x ** 2 + x * y + y ** 2 = 10
en una región determinada.
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()