python - pyplot - Trazando ecuaciones implícitas en 3d
plot python 3 (6)
¿Has mirado a mplot3d en matplotlib?
Me gustaría trazar la ecuación implícita F (x, y, z) = 0 en 3D. ¿Es posible en Matplotlib?
Finalmente, lo hice (actualicé mi matplotlib a 1.0.1). Aquí está el código:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
def hyp_part1(x,y,z):
return -(x**2) - (y**2) + (z**2) - 1
fig = plt.figure()
ax = fig.add_subplot(111, projection=''3d'')
x_range = np.arange(-100,100,10)
y_range = np.arange(-100,100,10)
X,Y = np.meshgrid(x_range,y_range)
A = np.linspace(-100, 100, 15)
A1,A2 = np.meshgrid(A,A)
for z in A:
X,Y = A1, A2
Z = hyp_part1(X,Y,z)
ax.contour(X, Y, Z+z, [z], zdir=''z'')
for y in A:
X,Z= A1, A2
Y = hyp_part1(X,y,Z)
ax.contour(X, Y+y, Z, [y], zdir=''y'')
for x in A:
Y,Z = A1, A2
X = hyp_part1(x,Y,Z)
ax.contour(X+x, Y, Z, [x], zdir=''x'')
ax.set_zlim3d(-100,100)
ax.set_xlim3d(-100,100)
ax.set_ylim3d(-100,100)
Aquí está el resultado:
Gracias, Paul!
Hasta donde yo sé, no es posible. Tienes que resolver esta ecuación numéricamente por ti mismo. Usar scipy.optimize es una buena idea. El caso más simple es que conoces el rango de la superficie que deseas trazar, y solo haces una cuadrícula regular en xey, e intentas resolver la ecuación F (xi, yi, z) = 0 para z, dando un inicio punto de z. El siguiente es un código muy sucio que podría ayudarte
from scipy import *
from scipy import optimize
xrange = (0,1)
yrange = (0,1)
density = 100
startz = 1
def F(x,y,z):
return x**2+y**2+z**2-10
x = linspace(xrange[0],xrange[1],density)
y = linspace(yrange[0],yrange[1],density)
points = []
for xi in x:
for yi in y:
g = lambda z:F(xi,yi,z)
res = optimize.fsolve(g, startz, full_output=1)
if res[2] == 1:
zi = res[0]
points.append([xi,yi,zi])
points = array(points)
Matplotlib espera una serie de puntos; Hará el trazado si puedes descubrir cómo renderizar tu ecuación.
¿Es posible trazar ecuaciones implícitas usando Matplotlib? La respuesta de Mike Graham sugiere usar scipy.optimize para explorar numéricamente la función implícita.
Hay una galería interesante en http://xrt.wikidot.com/gallery:implicit muestra una variedad de funciones implícitas con raytraced: si su ecuación coincide con una de estas, podría darle una mejor idea de lo que está mirando.
De lo contrario, si le interesa compartir la ecuación real, tal vez alguien pueda sugerir un enfoque más fácil.
Puede engañar a matplotlib para trazar ecuaciones implícitas en 3D. Simplemente haga un diagrama de contorno de un nivel de la ecuación para cada valor de z dentro de los límites deseados. Puede repetir el proceso a lo largo de los ejes yy z para obtener una forma más sólida.
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
def plot_implicit(fn, bbox=(-2.5,2.5)):
'''''' create a plot of an implicit function
fn ...implicit function (plot where fn==0)
bbox ..the x,y,and z limits of plotted interval''''''
xmin, xmax, ymin, ymax, zmin, zmax = bbox*3
fig = plt.figure()
ax = fig.add_subplot(111, projection=''3d'')
A = np.linspace(xmin, xmax, 100) # resolution of the contour
B = np.linspace(xmin, xmax, 15) # number of slices
A1,A2 = np.meshgrid(A,A) # grid on which the contour is plotted
for z in B: # plot contours in the XY plane
X,Y = A1,A2
Z = fn(X,Y,z)
cset = ax.contour(X, Y, Z+z, [z], zdir=''z'')
# [z] defines the only level to plot for this contour for this value of z
for y in B: # plot contours in the XZ plane
X,Z = A1,A2
Y = fn(X,y,Z)
cset = ax.contour(X, Y+y, Z, [y], zdir=''y'')
for x in B: # plot contours in the YZ plane
Y,Z = A1,A2
X = fn(x,Y,Z)
cset = ax.contour(X+x, Y, Z, [x], zdir=''x'')
# must set plot limits because the contour will likely extend
# way beyond the displayed level. Otherwise matplotlib extends the plot limits
# to encompass all values in the contour.
ax.set_zlim3d(zmin,zmax)
ax.set_xlim3d(xmin,xmax)
ax.set_ylim3d(ymin,ymax)
plt.show()
Aquí está la trama del Goursat Tangle:
def goursat_tangle(x,y,z):
a,b,c = 0.0,-5.0,11.8
return x**4+y**4+z**4+a*(x**2+y**2+z**2)**2+b*(x**2+y**2+z**2)+c
plot_implicit(goursat_tangle)
Puede facilitar la visualización agregando señales de profundidad con el mapa de color creativo:
Así es como se ve el argumento de OP:
def hyp_part1(x,y,z):
return -(x**2) - (y**2) + (z**2) - 1
plot_implicit(hyp_part1, bbox=(-100.,100.))
Bonificación: puede usar Python para combinar funcionalmente estas funciones implícitas:
def sphere(x,y,z):
return x**2 + y**2 + z**2 - 2.0**2
def translate(fn,x,y,z):
return lambda a,b,c: fn(x-a,y-b,z-c)
def union(*fns):
return lambda x,y,z: np.min(
[fn(x,y,z) for fn in fns], 0)
def intersect(*fns):
return lambda x,y,z: np.max(
[fn(x,y,z) for fn in fns], 0)
def subtract(fn1, fn2):
return intersect(fn1, lambda *args:-fn2(*args))
plot_implicit(union(sphere,translate(sphere, 1.,1.,1.)), (-2.,3.))