2010-03-20 22 views

Antwort

18

Ich glaube nicht, dass es für diese sehr gute Unterstützung ist, aber Sie so etwas wie

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() 

Siehe API docs für contour versuchen könnte: Wenn das vierte Argument es gibt eine Folge ist dann, welche Konturlinien zu zeichnen . Aber die Handlung wird nur so gut sein wie die Auflösung Ihrer Bereiche, und es gibt bestimmte Eigenschaften, die es nie richtig machen wird, oft an Selbstschnittpunkten.

+0

Dies ist eine gute Lösung. Meine Lösung ist eine manuellere Methode, dieselbe Information mit demselben zugrunde liegenden Konzept zu erhalten: die implizite Gleichung als f (x, y) aufzustellen, so dass f (x, y) = 0 der ursprünglichen impliziten Gleichung entspricht und Isolieren seiner Nullkontur. –

6

Matplotlib berechnet keine Gleichungen; es zeichnet Punkte auf. Sie können ein Werkzeug wie scipy​.optimize verwenden, um Y-Punkte numerisch aus x-Werten (oder umgekehrt) von impliziten Gleichungen oder beliebig vielen anderen Werkzeugen zu berechnen.


Zum Beispiel, hier ist ein Beispiel, wo ich die implizite Gleichung x ** 2 + x * y + y ** 2 = 10 in einer bestimmten Region zeichnen.

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() 
1

Viele Danke Steve, Mike, Alex. Ich bin mit Steves Lösung gegangen (siehe Code unten). Mein einziges Problem ist, dass das Konturplot hinter meinen Gitternetzlinien erscheint, im Gegensatz zu einem normalen Plot, das ich mit Zorder nach vorne zwingen kann. Noch mehr Half sehr geschätzt.

Cheers, 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() 
+0

@Geddes, es sieht so aus, als ob die Unterstützung für die Kontur, die ZOrder respektiert, erst kürzlich der Matplotlib-Quelle hinzugefügt wurde. Von ihrem SVN Stamm: http://matplotlib.svn.sourceforge.net/viewvc/matplotlib?view = rev & revision = 8098 – Mark

14

Da Sie diese Frage mit sympy Tags versehen haben, werde ich so ein Beispiel.

Aus der Dokumentation: http://docs.sympy.org/modules/plotting.html.

+1

Es sieht so aus, als ob die neue Syntax 'plot_implicit (Eq (x ** 5 + y ** 5, 1))' 'ist und der neue Doc Link [ist hier] (http: //docs.sympy .org/neueste/module/plotting.html). –

4

Es gibt eine implizite Gleichung (und Ungleichheit) Plotter in sympy. Es wird als Teil von GSoC erstellt und erzeugt die Plots als Matplotlib-Figurinstanzen.

Docs bei http://docs.sympy.org/latest/modules/plotting.html#sympy.plotting.plot_implicit.plot_implicit

Seit sympy Version 0.7.2 ist es erhältlich als:

>>> 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 
+0

Es scheint, dass es jetzt veröffentlicht wird. :) –

+0

Woher kommt deine 'the_matplotlib_axes_instance'? – theV0ID

+0

'p' ist das von Ihnen erstellte Diagramm. 'p._backend._ax' wäre eine Achseninstanz und wenn Sie möchten, können Sie sie in einer neuen Variablen referenzieren und für jede beliebige Instanz der matplotlib-Achse verwenden. – Krastanov

Verwandte Themen