I'm trying to add to an animated plot of a random variable the dates in the x axes. I've tried different things but the code is working just with a static x-axes array..
I made a small function to update the dates array T
and random var array y
the I called shift().
- To see how the basic code (no dates) is behaving you need to uncomment every line that is followed by "# uncomment 1". Viceversa uncomment every line that has "# uncomment 0".
I don't know why I can't plot the dates in the x-axes.
This below is the code:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import pandas as pd
import time
import datetime
plt.rcParams.update({'axes.facecolor':'lightgray'})
plt.rcParams.update({'figure.facecolor':'gray'})
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
# ax = plt.axes()
ax = plt.axes(xlim=(0, 2), ylim=(-8, 8))
line, = ax.plot([], [], lw=2)
def shift(y_arr,y_i,cont_cascata):
print("cont_cascata:",cont_cascata)
if type(y_arr)==list:
y_arr.pop(0)
y_arr = y_arr [y_i]
if type(y_arr) is np.ndarray:
print("np.array..")
y_arr = np.delete(y_arr, 0) # togliamo primo
y_arr = np.append(y_arr, y_i) # aggiungiamo ultimo
return y_arr
# initialization function: plot the background of each frame
def init():
line.set_data([], [])
return line,
# animation function. This is called sequentially
# pd._libs.tslibs.timestamps.Timestamp
def ts_array(n):
t0 = pd.Timestamp(2018,1,1,12,30)
T = []
for i in range(n):
t_i = t0 pd.Timedelta(minutes=i)
T = T [t_i]
return T
# tarr = ts_array(n=100)
def animate(i):
global y,x,T
n = 100
if i==0:
y = np.round(np.random.normal(loc=0, scale=2, size=n), decimals=2)
x = np.linspace(0, 2, n) # uncomment 0
T = ts_array(n) # uncomment 1
y_i = np.round(np.random.normal(loc=0,scale=2),decimals=2)
t_i = T[-1] pd.Timedelta(minutes=1) # uncomment1
y = shift(y_arr=y,y_i=y_i, cont_cascata=i)
T = shift(y_arr=T,y_i=t_i,cont_cascata=i) # uncomment 1
T = pd.DatetimeIndex(T) # uncomment 1
T = T.to_pydatetime() # uncomment 1
# line.set_data(x, y) # uncomment 0
line.set_data(T,y) # uncomment 1
time.sleep(0.5)
return line,
print("animate")
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=20, blit=True)
plt.show()
What should I do to make this code work properly? Thanks
CodePudding user response:
You need to adjust the xlim
of the axes to account for date time. Inside animate
, just after line.set_data(T,y)
, try adding this:
ax.set_xlim(T.min(), T.max())
CodePudding user response:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import matplotlib.dates as mdates
import pandas as pd
import time
import datetime
plt.rcParams.update({'axes.facecolor': 'lightgray'})
plt.rcParams.update({'figure.facecolor': 'gray'})
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure() # include
ax = plt.axes() # include
# ax = plt.axes(xlim=(0, 2), ylim=(-8, 8))
line, = ax.plot([], [], lw=2)
## tilt dates
plt.setp(ax.xaxis.get_majorticklabels(), rotation=35)
def shift(y_arr, y_i, cont_cascata):
# print("cont_cascata:",cont_cascata)
if type(y_arr) == list:
y_arr.pop(0)
y_arr = y_arr [y_i]
if type(y_arr) is np.ndarray:
# print("np.array..")
y_arr = np.delete(y_arr, 0) # togliamo primo
y_arr = np.append(y_arr, y_i) # aggiungiamo ultimo
return y_arr
# initialization function: plot the background of each frame
def init():
line.set_data([], [])
line.axes.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M")) # "%Y-%m-%d %H:%M:%S"
return line,
# animation function. This is called sequentially
# pd._libs.tslibs.timestamps.Timestamp
def ts_array(n):
t0 = pd.Timestamp(2018, 1, 1, 12, 00)
T = []
for i in range(n):
t_i = t0 pd.Timedelta(minutes=i)
T = T [t_i]
return T
def animate(i):
global y, x, T
print("i:", i)
n = 10
if i == 0:
y = np.round(np.random.normal(loc=0, scale=2, size=n), decimals=2)
x = np.linspace(6, 2, n) # uncomment 0
T = ts_array(n) # uncomment 1
y_i = np.round(np.random.normal(loc=6, scale=2), decimals=2)
t_i = T[-1] pd.Timedelta(minutes=1) # uncomment1
y = shift(y_arr=y, y_i=y_i, cont_cascata=i)
T = shift(y_arr=T, y_i=t_i, cont_cascata=i) # uncomment 1
T = pd.DatetimeIndex(T) # uncomment 1
T = T.to_pydatetime() # uncomment 1
# line.set_data(x, y) # uncomment 0
line.set_data(T, y) # uncomment 1
ax.relim(visible_only=True)
ax.autoscale()
# ax.autoscale_view(True,True,True)
# time.sleep(0.5)
return line,
print("animate")
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=500) # blit = True
plt.show()