Python matplotlib - 更新图形而不关闭窗口

时间:2015-04-03 08:44:25

标签: python numpy matplotlib

这是我的代码到目前为止(使用Anaconda Python 3.4发行版,Spyder IDE):

import numpy as np
import pylab as pl
import cmath
from fractions import Fraction
import matplotlib.offsetbox as offsetbox 

#Gravity
g = 9.8

#Function to solve quadratic
def solver(k,b,m):
    #Solutions
    alpha = (-b/(2*m))
    sol1 = (alpha + (cmath.sqrt(((b/(2*m))**2)-(k/m))))
    sol2 = (alpha - (cmath.sqrt(((b/(2*m))**2)-(k/m))))
    #Only 2 decimal places
    alpha = "%.2f" % alpha.real
    alpha = float(alpha)
    sol1 = "%.2f" % sol1.real
    sol1 = float(sol1)
    sol2 = "%.2f" % sol2.real
    sol2 = float(sol1)
    #Particular solution
    yp = (g*m)/k
    yp = "%.2f" % yp
    yp = float(yp)
    #Calculating the discriminant
    if ((b/2*m)**2) > (k/m):
        print("y = C1*(e^%s*t) + C2*(e^%s*t) + %s"%(sol1, sol2, yp))
        t = np.linspace(0, 50, 10000)           
        yc = np.exp(sol1*t) + np.exp(sol2*t)
        y = yc + yp
        pl.plot(t,y, '-g', label="y = C1*(e^%s*t) + C2*(e^%s*t) + %s"%(sol1, sol2, yp), linewidth=2)
        a = pl.legend(loc='upper right',prop={'size':14})
        #Extra text
        txt=offsetbox.TextArea("Sobre amortiguado") 
        box = a._legend_box 
        box.get_children().append(txt) 
        box.set_figure(box.figure) 
        #Show plot
        pl.show()

    elif ((b/2*m)**2) == (k/m):
        print("y = C1*(e^%s*t) + C2*t*(e^%s*t) + %s"%(sol1, sol2, yp))
        t = np.linspace(0, 50, 10000)           
        yc = np.exp(sol1*t) + t*np.exp(sol2*t)
        y = yc + yp
        pl.plot(t,y, '-g', label="y = C1*(e^%s*t) + C2*t*(e^%s*t) + %s"%(sol1, sol2, yp), linewidth=2)
        a = pl.legend(loc='upper right',prop={'size':14})
        #Extra text
        txt=offsetbox.TextArea("Criticamente amortiguado") 
        box = a._legend_box 
        box.get_children().append(txt) 
        box.set_figure(box.figure) 
        #Show plot
        pl.show()

    elif ((b/2*m)**2) < (k/m):
        beta = (cmath.sqrt((k/m)-((b/(2*m))**2)))
        beta = "%.2f" % beta.real
        beta = float(beta)
        print("y = e^(%s*t)*[C1*cos(%s*t) + C2*sen(%s*t)] + %s"%(alpha, beta, beta, yp))
        t = np.linspace(0, 50, 10000)         
        yc = (np.exp(alpha*t))*(np.cos(beta*t) + np.sin(beta*t))
        y = yc + yp
        pl.plot(t,y, '-g', label="y = e^(%s*t)*[C1*cos(%s*t) + C2*sen(%s*t)] + %s"%(alpha, beta, beta, yp), linewidth=2)
        a = pl.legend(loc='upper right',prop={'size':14})
        #Extra text
        txt=offsetbox.TextArea("Sub amortiguado") 
        box = a._legend_box 
        box.get_children().append(txt) 
        box.set_figure(box.figure) 
        #Show plot
        pl.show()

#End function definition


#Execution
k = float(Fraction(input("k: ")))
b = float(Fraction(input("b: ")))
m = float(Fraction(input("m: ")))       
solver(k,b,m)

我要做的是首先询问用户输入,然后用解决方案绘制图表;但之后我希望用户能够更改他们的输入,以便图表更新(不关闭绘图窗口)并查看新输入的新解决方案。我尝试将所有内容放在while循环中,但是调出图形的pl.show()会阻止进一步执行,直到窗口关闭。

我已经阅读了一些关于使用pl.draw()和pl.ion()的内容但是在尝试了几个小时之后无法完成任何工作,不确定我做错了什么

提前感谢您的帮助!

编辑:我一整天都在努力,所以我可能不会马上检查答案,但是我会在睡觉之后;希望以后能找到一些好的答案!

1 个答案:

答案 0 :(得分:0)

我认为@Repiklis是对的。要更新绘图,最有效的方法是使用set_ydata方法作为轴对象,如How to update a plot in matplotlib?中所述。 在程序开始时(进口后),您还需要pl.ion()

但关键是你必须定义一个允许用户输入更多数据的循环。类似的东西:

while True:
    k = float(Fraction(input("k: ")))
    b = float(Fraction(input("b: ")))
    m = float(Fraction(input("m: ")))       
    solver(k,b,m)

更简单的方法是clear并每次绘制数据(否则你必须手动重置轴范围)。