最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - No new plot after interacting with matplotlib slider - Stack Overflow

programmeradmin2浏览0评论

So first, here is my code:

%matplotlib ipympl
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button


def ODE_r(x, t, params):
    r, d1t_r = x
    q, m, U_0, w, r_0 = params
    derivs = [d1t_r,
             -1 * (q / m) * U_0 * np.sin(w * t) * (r / r_0)]
    return derivs

def ODE_z(y, t, params):
    z, d1t_z = y
    q, m, U_0, w, r_0 = params
    derivs = [d1t_z,
             (q / m) * U_0 * np.sin(w * t) * 2 * (z / r_0)]
    return derivs


q = 1                     # Mass of particle
q_u = sp.constants.e      # Unit in e (C)

m = 1836                  # Mass of particle
m_u = sp.constants.m_e    # Unit in electron mass (kg)

U_0 = 10                  # Amplitude of AC voltage
U_0_u = 1                 # Unit in V

w = 4000                  # Frequency of AC voltage
w_u = 1                   # Unit in Hz

r_0 = 1000                # Geometrical factor
r_0_u = 1                 # Unit?

# Initial values in m und m/s
r0     = 2e-6
d1t_r0 = 1e-3

z0     = -1e-6
d1t_z0 = 1e-3


# Define parameters for ODE solver and slider
def params(q, m, U_0, w, r_0):
    func = [q*q_u, m*m_u, U_0*U_0_u, w*w_u, r_0]
    return func

# Initial values for ODE solver
x0 = [r0, d1t_r0]
y0 = [z0, d1t_z0]

# Time array for solution (in s)
tStop = 0.1
tInc = 0.00005
Zeit = np.arange(0, tStop, tInc)

# Define numeric solution
def r_n(f, v0, t, parameters):
    func = sp.integrate.odeint(f, v0, t, args=(parameters,))
    return func[:,0]

def z_n(f, v0, t, parameters):
    func = sp.integrate.odeint(f, v0, t, args=(parameters,))
    return func[:,0]


fig = plt.figure(figsize=(8, 11), dpi=100)
ax = fig.add_subplot(111)

# Adjust the subplots region to leave some space for the sliders and buttons
fig.subplots_adjust(left=0.15, bottom=0.4)

# Draw the initial plot
# The 'line' variable is used for modifying the line later
[line] = ax.plot(r_n(ODE_r, x0, Zeit, params(q, m, U_0, w, r_0)), z_n(ODE_z, y0, Zeit, params(q, m, U_0, w, r_0)),
         marker=',',
         linestyle='-',
         color='#008080',
         label='trajectory')
#ax.set_xlim([0, 1])
#ax.set_ylim([-10, 10])
plt.xlabel('r / m')
plt.ylabel('z / m')
plt.title('Particle trajectory in the r - z plane of a Paul trap',
          fontsize=12)
# plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid(True)

# Sliders for tweaking the parameters
axis_color = 'lightgoldenrodyellow'

q_slider_ax  = fig.add_axes([0.25, 0.3, 0.65, 0.03], facecolor=axis_color)
q_slider = Slider(q_slider_ax, 'q / e', -1, 10, valinit=q, valfmt='%0.0f')

m_slider_ax = fig.add_axes([0.25, 0.25, 0.65, 0.03], facecolor=axis_color)
m_slider = Slider(m_slider_ax, 'm / m_e', 1, 2000, valinit=m, valfmt='%0.0f')

U_slider_ax = fig.add_axes([0.25, 0.2, 0.65, 0.03], facecolor=axis_color)
U_slider = Slider(U_slider_ax, 'U_0 / V', 1, 100, valinit=U_0, valfmt='%0.0f')

w_slider_ax = fig.add_axes([0.25, 0.15, 0.65, 0.03], facecolor=axis_color)
w_slider = Slider(w_slider_ax, 'Freq / Hz', 1, 10000, valinit=w, valfmt='%0.0f')

r_slider_ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], facecolor=axis_color)
r_slider = Slider(r_slider_ax, 'r_0', 1, 10000, valinit=r_0, valfmt='%0.0f')

# Define an action for modifying the line when any slider's value changes
def sliders_on_changed(val):
    line.set_xdata(r_n(ODE_r, x0, Zeit, params(q.val, m.val, U_0.val, w.val, r_0.val)))
    line.set_ydata(z_n(ODE_z, y0, Zeit, params(q.val, m.val, U_0.val, w.val, r_0.val)))
    fig.canvas.draw_idle()
q_slider.on_changed(sliders_on_changed)
m_slider.on_changed(sliders_on_changed)
U_slider.on_changed(sliders_on_changed)
w_slider.on_changed(sliders_on_changed)
r_slider.on_changed(sliders_on_changed)

# Add a button for resetting the parameters
reset_button_ax = fig.add_axes([0.8, 0.05, 0.1, 0.04])
reset_button = Button(reset_button_ax, 'Reset', color=axis_color, hovercolor='0.975')
def reset_button_on_clicked(mouse_event):
    q_slider.reset()
    w_slider.reset()
reset_button.on_clicked(reset_button_on_clicked)

plt.show()

Background:
I need to plot a particle trajectory in a paul trap by numerically integrating two second order ODEs.

Problem:
Most part of the code is working as intended. The problem occurs by the slider.
I can interact with slider, but plot will not be updated, at least seems like that.
The most possible problems in my opinions are:

  1. Either the sliders are working, but new plot are out of range. The scale also need to be changed. Is it possible to add an autoscale button just like reset?
  2. Or the sliders are not working. I am not sure why. Maybe it is related to the numeric integration? Then how may I fix it?

Or the problem is elsewhere? May anyone help me?

发布评论

评论列表(0)

  1. 暂无评论