"""Manage a moving plot window for displaying very long time series."""
import time
[docs]class MovingPlotWindow:
'''
Make a plot window that follows the tip (end) of a very long
time series.
Example::
def demo(I, k, dt, T, mode='continuous movement'):
"""
Solve u' = -k**2*u, u(0)=I, u'(0)=0 by a finite difference
method with time steps dt, from t=0 to t=T.
"""
if dt > 2./k:
print 'Unstable scheme'
N = int(round(T/float(dt)))
u = zeros(N+1)
t = linspace(0, T, N+1)
umin = -1.2*I
umax = -umin
period = 2*pi/k # period of the oscillations
window_width =
plot_manager = MovingPlotWindow(
window_width, dt, yaxis=[umin, umax],
mode=mode)
u[0] = I
u[1] = u[0] - 0.5*dt**2*k**2*u[0]
for n in range(1,N):
u[n+1] = 2*u[n] - u[n-1] - dt**2*k**2*u[n]
if plot_manager.plot(n):
s = plot_manager.first_index_in_plot
plot(t[s:n+2], u[s:n+2], 'r-',
t[s:n+2], I*cos(k*t)[s:n+2], 'b-',
axis=plot_manager.axis(),
title="Solution of u'' + k^2 u = 0 for t=%6.3f (mode: %s)" % (t[n+1], mode))
plot_manager.update(n)
'''
[docs] def __init__(self, window_width, dt, yaxis=[-1,1],
mode='continuous movement',
pause=1.5):
"""
==================== ====================================
Argument Description
==================== ====================================
window_width tmax-tmin in a plot window
dt time step (constant)
yaxis extent of y axis
mode method for moving the plot window,
see below.
==================== ====================================
The mode parameter has three values:
* ``'continuous movement'``:
the plot window moves one time step for each plot.
* ``'continuous drawing'``: the curves are drawn from left
to right, one step at a time, and plot window jumps
when the curve reaches the end.
* ``'jumps'``: the curves are shown in a window for a time
equal to the pause argument, then the axis jumps
to a new time window of the same length
See also the test block of the module for
testing out the three different modes of this class.
"""
self.taxis_length_in_steps = int(round(window_width/float(dt)))
self.dt = dt
self.mode = mode
self.taxis_length = self.taxis_length_in_steps*self.dt
self.first_index_in_plot = 0
self.taxis_min = 0
self.yaxis = yaxis
self.pause = pause
self.n_prev = 0
[docs] def axis(self):
"""Return the axis limits as a list ``[xmin, xmax, ymin, ymax]``."""
return [self.taxis_min, self.taxis_min + self.taxis_length,
self.yaxis[0], self.yaxis[1]]
[docs] def plot(self, n):
"""
Return True if a plot is to be drawn at time step number ``n``,
otherwise return False.
"""
if self.mode == 'continuous movement':
return True
elif self.mode == 'continuous drawing':
# Update self.first_index_in_plot and self.taxis_min
# every self.taxis_length_in_steps time step
if n % self.taxis_length_in_steps == 0:
self.taxis_min += self.taxis_length
self.first_index_in_plot += self.taxis_length_in_steps
# Always plot the curves in continuous drawing
return True
else:
# Plot every self.taxis_length_in_steps time step only
if (n+1) % self.taxis_length_in_steps == 0:
return True
else:
return False
[docs] def update(self, n):
"""Update the plot manager (``MovingPlotWindow``) at time step ``n``."""
if self.mode == 'continuous movement':
if n > self.taxis_length_in_steps:
self.taxis_min += self.dt
self.first_index_in_plot += n - self.n_prev
self.n_prev = n
elif self.mode == 'jumps' and \
(n+1) % self.taxis_length_in_steps == 0:
# After plot is shown, sleep and then update plot
# window parameters
time.sleep(self.pause)
self.taxis_min += self.taxis_length
self.first_index_in_plot += self.taxis_length_in_steps
def _demo(I, k, dt, T, mode='continuous movement'):
"""
Solve u' = -k**2*u, u(0)=I, u'(0)=0 by a finite difference
method with time steps dt, from t=0 to t=T.
"""
if dt > 2./k:
print 'Unstable scheme'
N = int(round(T/float(dt)))
u = zeros(N+1)
t = linspace(0, T, N+1)
umin = -1.2*I
umax = -umin
period = 2*pi/k # period of the oscillations
plot_manager = MovingPlotWindow(8*period, dt, yaxis=[umin, umax],
mode=mode)
u[0] = I
u[1] = u[0] - 0.5*dt**2*k**2*u[0]
for n in range(1,N):
u[n+1] = 2*u[n] - u[n-1] - dt**2*k**2*u[n]
if plot_manager.plot(n):
s = plot_manager.first_index_in_plot
plot(t[s:n+2], u[s:n+2], 'r-',
t[s:n+2], I*cos(k*t)[s:n+2], 'b-',
axis=plot_manager.axis(),
title="Solution of u'' + k^2 u = 0 for t=%6.3f (mode: %s)" \
% (t[n+1], mode))
plot_manager.update(n)
if __name__ == '__main__':
from scitools.std import *
T = 40
_demo(1, pi, 0.1, T, mode='continuous movement')
time.sleep(10)
figure()
_demo(1, pi, 0.1, T, mode='continuous drawing')
time.sleep(10)
figure()
_demo(1, pi, 0.1, T, mode='jumps')
time.sleep(10)