Как вывести на экран одну и ту же функцию с множеством разных значений в подсюжетах в numpy / matplotlib python? - PullRequest
0 голосов
/ 27 апреля 2018

У меня следующий код Python, и я хотел бы:

  1. Нарисуйте одну и ту же функцию на 1 (только одной) фигуре со множеством различных (скажем, 4) значений 'v0' и 'theta', каждая траектория которых имеет свой цвет.
  2. Создайте 4 графика на 4 разных фигурах, чтобы он выглядел как квадрат с 4 графиками с 4 разными значениями 'v0' и 'theta'
  3. Создайте виджет для изменения значений v0 и theta, как пользователь хочет с помощью мыши.

import numpy as np 
import scipy.integrate as integrate 
import matplotlib.pyplot as plt 
%matplotlib inline


theta = 45.                   
theta = theta * np.pi/180.   
v0 = 20.0

g = 9.81         
R = 0.035             
m = 0.057         
rho = 1.2041           
C = 0.5                


k = (0.5*np.pi*R**2*C*rho)/m    


x0=0                 
y0=10     
vx0 = v0*np.sin(theta)      
vy0 =
v0*np.cos(theta)     
print(vx0) 
print(vy0)

def f_func(X_vek,time):
f = np.zeros(4)    
f[0] = X_vek[2]    
f[1] = X_vek[3]    
f[2] = - k*(f[0]**2 + f[1]**2)**(0.5)*f[0]         
f[3] = -g - k*(f[0]**2 + f[1]**2)**(0.5)*f[1]      
return f

X0 = [ x0, y0, vx0, vy0]         
t0 = 0. tf = 10  
tau = 0.05    

t = np.arange(t0,tf,tau)   

X = integrate.odeint(f_func,X0,t)    

x = X[:,0]      
y = X[:,1]  
vx = X[:,2]  
vy = X[:,3]

mask = y >= 0    

plt.scatter(x[mask],y[mask]) 
plt.scatter(x[mask],y[mask])
plt.xlabel('x') plt.ylabel('y') plt.show()

Я мог бы выполнить пункт 1 и 2 моего вопроса, изменив значения после построения графика, затем снова вычислить vx0 и vy0, а затем вызвать функцию интегрирования и, наконец, построить график снова, но это немного странно и не чисто. Есть ли лучший способ сделать это? как массив различных значений V0 и тета или что-то?

Спасибо!

1 Ответ

0 голосов
/ 27 апреля 2018

Создайте свой код как функцию:

def func(theta=45, v0=20):
    theta = theta * np.pi/180.   

    g = 9.81         
    R = 0.035             
    m = 0.057         
    rho = 1.2041           
    C = 0.5                

    k = (0.5*np.pi*R**2*C*rho)/m    

    x0=0                 
    y0=10     
    vx0 = v0*np.sin(theta)      
    vy0 = v0*np.cos(theta)     

    def f_func(X_vek,time):
        f0, f1 = X_vek[2:4].tolist()
        f2 = - k*(f0**2 + f1**2)**(0.5)*f0         
        f3 = -g - k*(f0**2 + f1**2)**(0.5)*f1      
        return [f0, f1, f2, f3]

    X0 = [ x0, y0, vx0, vy0]         
    t0 = 0. 
    tf = 10  
    tau = 0.05    

    t = np.arange(t0,tf,tau)   
    X = integrate.odeint(f_func,X0,t)    

    x = X[:,0]      
    y = X[:,1]  
    vx = X[:,2]  
    vy = X[:,3]
    mask = y >= 0    
    return x[mask], y[mask]

тогда вы можете построить его с другими параметрами:

plt.plot(*func()) 
plt.plot(*func(theta=30)) 

plt.xlabel('x')
plt.ylabel('y')
plt.show()

Я предлагаю вам использовать Holoviews для создания динамического графика:

import holoviews as hv
hv.extension("bokeh")

hv.DynamicMap(
    lambda theta, v0:hv.Curve(func(theta, v0)).redim.range(x=(0, 50), y=(0, 50)), 
    kdims=[hv.Dimension("theta", range=(0, 80), default=40), 
           hv.Dimension("v0", range=(1, 40), default=20)])

Вот результат:

enter image description here

...