2017-10-18 1 views
2

Dieser CodeAnzeige zwei Sympy Plots als zwei Matplotlib Nebenhandlungen

from sympy import * 
x=Symbol('x') 
p1 = plot(x**2,(x,-2,2)) 
p2 = plot(x**3,(x,-2,2)) 

Ergebnisse in zwei getrennten Parzellen.

Anstelle von zwei separaten Grundstücken, ich möchte, dass sie als Nebenhandlungen mit matplotlib anzuzeigen:

import matplotlib.pyplot as plt 
fig = plt.figure() 
ax1 = fig.add_subplot(121) 
ax2 = fig.add_subplot(122) 
plt.show() 

Wie kann ich p1 und p2, hinzufügen, so dass sie als Nebenhandlungen innerhalb der matplotlib Figur dargestellt?

+1

ich könnte falsch sein. Aber die Handlung von sympy scheint nicht "ax''' Argumente zu enthalten und alles scheint figurenbasiert zu sein. Ich denke, der Stand von matplotlib ist immer noch: mehrere Zahlen zu verschmelzen ist zumindest hacky, nicht zu empfehlen. (Für dieses Beispiel macht es auch nicht viel Sinn, mpl nicht direkt zu verwenden; aber vielleicht wird es für Ihre eigentliche Aufgabe anders sein). – sascha

Antwort

4

Das Problem ist, dass sympy Plot seine eigene Figur und Achsen erstellt. Es ist nicht beabsichtigt, auf eine bestehende Achse zu zeichnen.

Sie können jedoch die Achsen, auf denen das Diagramm gezeichnet wird, durch vorhandene Achsen ersetzen, bevor Sie das Symplekeil zeigen.

from sympy import Symbol,plot 
import matplotlib.pyplot as plt 

def move_sympyplot_to_axes(p, ax): 
    backend = p.backend(p) 
    backend.ax = ax 
    backend.process_series() 
    backend.ax.spines['right'].set_color('none') 
    backend.ax.spines['bottom'].set_position('zero') 
    backend.ax.spines['top'].set_color('none') 
    plt.close(backend.fig) 


x=Symbol('x') 
p1 = plot(x**2,(x,-2,2), show=False) 
p2 = plot(x**3,(x,-2,2), show=False) 


fig, (ax,ax2) = plt.subplots(ncols=2) 
move_sympyplot_to_axes(p1, ax) 
move_sympyplot_to_axes(p2, ax2) 

plt.show() 

enter image description here

+0

Das ist etwas, an das ich mich für die Zukunft erinnern muss. Ich habe diese Backend-Attribute bereits ausgecheckt, konnte sie aber nicht verwenden. Was ist deine Definition von * hacky * hier? Nicht-netter Code oder Angst vor anstehenden Matplotlib-Änderungen? – sascha

+1

@sascha Nein, das ist gut von der Matplotlib-Seite. Mit Hacky meine ich, dass es wirklich keine API gibt, die man verwenden kann. Die Lösung verhindert zunächst, dass das sympy "backend" etwas plottet, dann künstlich eines seiner Attribute ersetzt und dann manuell einen Teil dessen nennt, was seine "show" -Methode tun würde. Also, es ist hacky in der Art, dass Affepatching auch hacky wäre. – ImportanceOfBeingErnest

3

Meine Lösung nicht hinzufügen p1, p2 die direkt Nebenhandlungen. Aber (x, y) Koordinaten von ihnen werden erfasst und stattdessen verwendet.

import matplotlib.pyplot as plt 
from sympy import symbols 
import numpy as np 

from sympy import symbols 
from sympy.plotting import plot 

# part 1 
# uses symbolic plot of functions 
x = symbols('x') 

#p1, p2 = plot(x**2, x**3, (x, -2, 2)) 

# this plot will not show ... 
# only produce 2 curves 
p1, p2 = plot((x**2, (x, -2, 2)), \ 
       (x**3, (x, -2, 2)), \ 
       show=False) 

# collect (x,y)'s of the unseen curves 
x1y1 = p1.get_points() # array of 2D 
x2y2 = p2.get_points() 

# part 2 
# uses regular matplotlib to plot the data 

fig = plt.figure(figsize=(8, 5)) 
ax1 = fig.add_subplot(121) 
ax2 = fig.add_subplot(122) 

# do subplot 1 
ax1.plot(x1y1[0], x1y1[1], 'g') # plot x**2 in green 
ax1.set_xlim([-2, 2]) 
ax1.set_xlabel('X1') 
ax1.set_ylabel('Y1') 
ax1.set_title('Line1') # destroyed by another .title(); axis metho1 

# do subplot 2 
ax2.plot(x2y2[0], x2y2[1], 'r') # plot x**3 in red 
ax2.set_xlim([-2, 2]) 
ax2.set_xlabel('X2') 
ax2.set_ylabel('Y2') 
ax2.set_title('Line2') 

fig.subplots_adjust(wspace=0.4) # set space between subplots 

plt.show() 

Das resultierende Grundstück:

output

+1

Während weniger allgemein und vielleicht nicht was OP gefragt, ich sehe das als eine echte Alternative in einigen Fällen! – sascha

Verwandte Themen