【问题标题】:Live Graphics Using Matplotlib Not Showing the Plot使用 Matplotlib 的实时图形不显示绘图
【发布时间】:2020-06-23 06:19:02
【问题描述】:

我正在研究一个物理问题,并试图通过在每 4 个计算步骤之后进行绘图来“实时”观看模拟。如果相关,我正在使用 Runge-Kutta(4 阶)方法进行区分。

当我运行代码时(应该运行代码大约 10/4 秒,但我想加快速度,虽然我不知道除了只显示一些帧之外如何),我可以看到轴在移动,但情节中没有显示任何内容。

我已将我的代码简化为只生成随机数而不是实际的函数,这样我就可以共享尽可能接近我实际拥有的代码。

import numpy as np
import matplotlib.pyplot as plt
 
# Parameters
time = 10  # maximum time for the simulation
h = 0.1  # step size
steps = int(time/h)  # number of steps
order = 4  # two second order equations
 
ICs = [0, 0, 0, 0.25, 0]  # intial conditions; t0, x1, x1dot, x2, x2dot
 
# Initializing vars array
vars = np.empty(shape=(order,steps))  # each row is another var, i.e. x1,x2,...
 
# Set initial conditions for each var
for i in range(order):
    vars[i][0] = ICs[i+1]

t = np.empty(steps)
t[0] = ICs[0]

K = np.zeros(shape=(4,len(vars))) # Each row is k1, k2, k3, k4 for each var


# ODE function
def ODE():
    dx1dt = np.random.randint(-1000,1000)
    dv1dt = np.random.randint(-1000,1000)
    dx2dt = np.random.randint(-1000,1000)
    dv2dt = np.random.randint(-1000,1000)
    
    return(np.array([dx1dt, dv1dt, dx2dt, dv2dt]))

# Loop calculates each var value using RK 4th order method
for i in range(steps-1):
    K[0] = ODE()
    K[1] = ODE()
    K[2] = ODE()
    K[3] = ODE()
    
    vars[:,i+1] = vars[:,i] + 1/6 * (K[0] + 2 * K[1] + 2 * K[2] + K[3])
    
    t[i+1] = t[i] + h
    
    # Plotting every fourth calculation
    if (i%4 == 0):
        plt.cla()
        plt.plot(t[i], vars[0,i], label='x1')
        
        plt.title(f'Title (stepsize: {h})')
        plt.xlabel('time [s]')
        plt.ylabel('position [m]')
        
        plt.legend(loc=1)
        plt.tight_layout()
        plt.pause(0.01)
 
plt.tight_layout()
 
plt.show()

感谢您的帮助。

【问题讨论】:

  • 乍一看,您在每次迭代中都绘制了一个点,也许您可​​以改为绘制数组?
  • 什么时候做plt.plot(t, vars[0], label='x1'),尽管还没有值,但似乎有一些初始情节。如果我将 vars 初始化为 vars = np.zeros(shape=(order,steps)),我会看到值在缓慢更新,但如果有意义的话,我希望看到图形正在发展。

标签: python numpy matplotlib


【解决方案1】:

您可以使用matplotlib's 交互模式plt.ion() 来启动交互绘图。然后调用plt.show()显示窗口,并使用plt.gcf().canvas.draw更新它,如下所示:

import numpy as np
import matplotlib.pyplot as plt
  
# Parameters
time = 10  # maximum time for the simulation
h = 0.1  # step size
steps = int(time/h)  # number of steps
order = 4  # two second order equations
 
ICs = [0, 0, 0, 0.25, 0]  # intial conditions; t0, x1, x1dot, x2, x2dot
 
# Initializing vars array
vars = np.empty(shape=(order,steps))  # each row is another var, i.e. x1,x2,...
 
# Set initial conditions for each var
for i in range(order):
    vars[i][0] = ICs[i+1]

t = np.empty(steps)
t[0] = ICs[0]

K = np.zeros(shape=(4,len(vars))) # Each row is k1, k2, k3, k4 for each var
fig,ax=plt.subplots()
plt.ion() # set interactive mode on 
plt.show() # open display window

# ODE function
def ODE():
    dx1dt = np.random.randint(-1000,1000)
    dv1dt = np.random.randint(-1000,1000)
    dx2dt = np.random.randint(-1000,1000)
    dv2dt = np.random.randint(-1000,1000)
    
    return(np.array([dx1dt, dv1dt, dx2dt, dv2dt]))

# Loop calculates each var value using RK 4th order method
for i in range(steps-1):
    K[0] = ODE()
    K[1] = ODE()
    K[2] = ODE()
    K[3] = ODE()
    
    vars[:,i+1] = vars[:,i] + 1/6 * (K[0] + 2 * K[1] + 2 * K[2] + K[3])
    
    t[i+1] = t[i] + h
    
    # Plotting every fourth calculation
    if (i%4 == 0):
        #plt.cla()
        plt.plot(t[:i], vars[0,:i],color='black')
        
        plt.title(f'Title (stepsize: {h})')
        plt.xlabel('time [s]')
        plt.ylabel('position [m]')
        

        plt.tight_layout()
        plt.gcf().canvas.draw() #update display window
        plt.pause(0.01)
        
plt.tight_layout()

【讨论】:

  • 这很棒。我想我现在必须研究这种交互模式。谢谢!
  • 你是如何保存这个 gif 的?我总是很难创建图表的 gif...
  • 将它们保存为单独的帧并将它们堆叠以创建 gif。你会发现这个SO 很有帮助。
【解决方案2】:

它可能不起作用,因为您的 plt.show() 不在 if 子句中。

【讨论】:

  • plt.show() 添加到if 语句似乎没有效果。
猜你喜欢
  • 2016-04-03
  • 2020-07-16
  • 2023-02-09
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 2015-06-20
  • 2017-05-11
  • 1970-01-01
相关资源
最近更新 更多