如何在时间上重新生成滚动窗口的动画?

huangapple go评论129阅读模式
英文:

How can reproduce animation for rolling window over time?

问题

I'm here to help with the Chinese translation. Here is the translated content:

我正在尝试使用一维时间序列数据,并尝试通过GoogleColab笔记本上的自己的数据复现以下方法的动画效果。

这是关于复现STS转换的动画(由series_to_supervised()函数实现,具有回溯步骤到过去时间n_in=9)等于使用重新拟合和固定训练大小(滚动起源)进行回测动画方法,由[tag:SkForecast]包引入。更多关于traintest选择的内容,是关于实际时间序列数据y的。可视化固定的训练大小,重新拟合并预测下一步。

如何在时间上重新生成滚动窗口的动画?

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. from matplotlib.patches import Rectangle
  5. from matplotlib.animation import FuncAnimation
  6. from IPython.display import HTML
  7. print(pd.__version__)
  8. # 生成一维时间序列数据到pandas DataFrame
  9. import numpy as np
  10. np.random.seed(123) # 为了可重复性和获得可重复的结果
  11. df = pd.DataFrame({
  12. "TS_24hrs": np.arange(0, 274),
  13. "count": np.abs(np.sin(2 * np.pi * np.arange(0, 274) / 7) + np.random.normal(0, 100.1, size=274)) # 生成季节性数据
  14. })
  15. # df = pd.read_csv('/content/U2996_24hrs_.csv', header=0, index_col=0).values
  16. print(f"原始数据 {df.shape}")
  17. # 可视化数据
  18. import matplotlib.pyplot as plt
  19. fig, ax = plt.subplots( figsize=(10,4))
  20. # 绘制数据
  21. df['count'].plot(label=f'数据或y', c='red')
  22. plt.xticks([0, 50, 100, 150, 200, 250, df['TS_24hrs'].iloc[-1]], visible=True, rotation="horizontal")
  23. plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left")
  24. plt.title('数据图')
  25. plt.ylabel('count', fontsize=15)
  26. plt.xlabel('时间戳 [24小时]', fontsize=15)
  27. plt.grid()
  28. plt.show()
  29. # 使用series_to_supervised (STS)选择训练/测试数据
  30. from pandas import DataFrame, concat
  31. def series_to_supervised( data, n_in, n_out=1, dropnan=True):
  32. """
  33. 将时间序列构建成监督学习数据集。
  34. 参数:
  35. data: 观测序列的序列,可以是列表或NumPy数组。
  36. n_in: 输入的滞后观测数量 (X)。
  37. n_out: 输出的观测数量 (y)。
  38. dropnan: 是否删除包含NaN值的行。
  39. 返回:
  40. 用于监督学习的Pandas DataFrame。
  41. """
  42. n_vars = 1 if type(data) is list else data.shape[1]
  43. df = pd.DataFrame(data)
  44. cols = list()
  45. # 输入序列 (t-n, ... t-1)
  46. for i in range(n_in, 0, -1):
  47. cols.append(df.shift(i))
  48. # 预测序列 (t, t+1, ... t+n)
  49. for i in range(0, n_out):
  50. cols.append(df.shift(-i))
  51. # 组合在一起
  52. agg = concat(cols, axis=1)
  53. # 删除包含NaN值的行
  54. if dropnan:
  55. agg.dropna(inplace=True)
  56. return agg.values
  57. values = series_to_supervised(df, n_in=9)
  58. data_x, data_y = values[:, :-1], values[:, -1]
  59. print(data_x.shape)
  60. print(data_y.shape)
  61. # 定义动画函数
  62. import matplotlib.pyplot as plt
  63. import pandas as pd
  64. from matplotlib.animation import FuncAnimation
  65. fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(40, 8))
  66. plt.subplots_adjust(bottom=0.25)
  67. plt.xticks(fontsize=12)
  68. ax.set_xticks(range(0, len(data_y), 9))
  69. ax.set_yticks(range(0, 2500, 200))
  70. data_y = pd.Series(data_y)
  71. data_y.plot(color='r', linestyle='-', label="y")
  72. ax.set_title('时间序列')
  73. ax.set_xlabel('时间')
  74. ax.set_ylabel('数值')
  75. ax.legend(loc="upper left")
  76. ax.grid(True, which='both', linestyle='-', linewidth=3)
  77. ax.set_facecolor('gainsboro')
  78. ax.spines['bottom'].set_position('zero')
  79. ax.spines['left'].set_position('zero')
  80. ax.spines['right'].set_color('none')
  81. ax.spines['top'].set_color('none')
  82. nested_list = list(trainX_tss)
  83. lines = [ax.plot([], [], color='g', linestyle='-')[0] for _ in range(len(trainX_tss))]
  84. def init():
  85. for line in lines:
  86. line.set_data([], [])
  87. return lines
  88. def update(frame):
  89. for i, line in enumerate(lines):
  90. data = pd.Series(nested_list[i], index=range(frame + i, frame + i + 9))
  91. line.set_data([], [])
  92. line.set_data(data.index, data)
  93. return lines
  94. # 定义动画设置
  95. anim = FuncAnimation(fig, update,
  96. frames=len(nested_list) - 9,
  97. init_func=init,
  98. interval=500,
  99. blit=True,
  100. repeat=False)
  101. # 保存动画 (.gif)
  102. anim.save('BrowniamMotion.gif', writer="pillow", fps=10 )
  103. # 在GoogleColab笔记本中可视化动画
  104. # 抑制最终输出
  105. plt.close(0)
  106. HTML(anim.to_html5_video())

STS转换:

多步骤或序列预测
一种不同类型的预测问题是使用过去的观测来预测一系列未来的观测。这可能被称为序列预测或多步骤预测。

到目前为止,我能够得到如下的输出,但它非常丑陋

英文:

I'm experimenting with 1D time-series data and trying to reproduce the following approach via animation over my own data in GoogleColab notebook.

It's about reproducing the animation of STS transformation (implemented by series_to_supervised() function with Lookback steps to past time n_in=9) equal to Backtesting with refit and fixed training size (rolling origin) animation approach introduced [tag:SkForecast] package. It's more about train and test selection over actual time-series data y. Visualize fixed train size and refit and predict next step(s).

如何在时间上重新生成滚动窗口的动画?

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. from matplotlib.patches import Rectangle
  5. from matplotlib.animation import FuncAnimation
  6. from IPython.display import HTML
  7. print(pd.__version__)
  8. # Generate univariate (1D) time-series data into pandas DataFrame
  9. import numpy as np
  10. np.random.seed(123) # for reproducibility and get reproducible results
  11. df = pd.DataFrame({
  12. "TS_24hrs": np.arange(0, 274),
  13. "count" : np.abs(np.sin(2 * np.pi * np.arange(0, 274) / 7) + np.random.normal(0, 100.1, size=274)) # generate sesonality
  14. })
  15. #df = pd.read_csv('/content/U2996_24hrs_.csv', header=0, index_col=0).values
  16. print(f"The raw data {df.shape}")
  17. #print(f"The raw data columns {df.columns}")
  18. # visulize data
  19. import matplotlib.pyplot as plt
  20. fig, ax = plt.subplots( figsize=(10,4))
  21. # plot data
  22. df['count'].plot(label=f'data or y', c='red' )
  23. #df['count'].plot(label=f'data', linestyle='--')
  24. plt.xticks([0, 50, 100, 150, 200, 250, df['TS_24hrs'].iloc[-1]], visible=True, rotation="horizontal")
  25. plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left")
  26. plt.title('Plot of data')
  27. plt.ylabel('count', fontsize=15)
  28. plt.xlabel('Timestamp [24hrs]', fontsize=15)
  29. plt.grid()
  30. plt.show()
  31. # slecet train/test data using series_to_supervised (STS)
  32. from pandas import DataFrame, concat
  33. def series_to_supervised( data, n_in, n_out=1, dropnan=True):
  34. """
  35. Frame a time series as a supervised learning dataset.
  36. Arguments:
  37. data: Sequence of observations as a list or NumPy array.
  38. n_in: Number of lag observations as input (X).
  39. n_out: Number of observations as output (y).
  40. dropnan: Boolean whether or not to drop rows with NaN values.
  41. Returns:
  42. Pandas DataFrame of series framed for supervised learning.
  43. """
  44. n_vars = 1 if type(data) is list else data.shape[1]
  45. df = pd.DataFrame(data)
  46. cols = list()
  47. # input sequence (t-n, ... t-1)
  48. for i in range(n_in, 0, -1):
  49. cols.append(df.shift(i))
  50. # forecast sequence (t, t+1, ... t+n)
  51. for i in range(0, n_out):
  52. cols.append(df.shift(-i))
  53. # put it all together
  54. agg = concat(cols, axis=1)
  55. # drop rows with NaN values
  56. if dropnan:
  57. agg.dropna(inplace=True)
  58. return agg.values
  59. values=series_to_supervised(df, n_in=9)
  60. data_x,data_y =values[:, :-1], values[:, -1]
  61. print(data_x.shape)
  62. print(data_y.shape)
  63. # define animation function
  64. import matplotlib.pyplot as plt
  65. import pandas as pd
  66. from matplotlib.animation import FuncAnimation
  67. fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(40, 8))
  68. plt.subplots_adjust(bottom=0.25)
  69. plt.xticks(fontsize=12)
  70. ax.set_xticks(range(0, len(data_y), 9))
  71. ax.set_yticks(range(0, 2500, 200))
  72. data_y = pd.Series(data_y)
  73. data_y.plot(color='r', linestyle='-', label="y")
  74. ax.set_title('Time Series')
  75. ax.set_xlabel('Time')
  76. ax.set_ylabel('Value')
  77. ax.legend(loc="upper left")
  78. ax.grid(True, which='both', linestyle='-', linewidth=3)
  79. ax.set_facecolor('gainsboro')
  80. ax.spines['bottom'].set_position('zero')
  81. ax.spines['left'].set_position('zero')
  82. ax.spines['right'].set_color('none')
  83. ax.spines['top'].set_color('none')
  84. nested_list = list(trainX_tss)
  85. lines = [ax.plot([], [], color='g', linestyle='-')[0] for _ in range(len(trainX_tss))]
  86. def init():
  87. for line in lines:
  88. line.set_data([], [])
  89. return lines
  90. def update(frame):
  91. for i, line in enumerate(lines):
  92. data = pd.Series(nested_list[i], index=range(frame + i, frame + i + 9))
  93. line.set_data([], [])
  94. line.set_data(data.index, data)
  95. return lines
  96. # define animation setup
  97. anim = FuncAnimation(fig, update,
  98. frames=len(nested_list) - 9,
  99. init_func=init,
  100. interval=500,
  101. blit=True,
  102. repeat=False)
  103. # Save animation (.gif))
  104. anim.save('BrowniamMotion.gif', writer = "pillow", fps=10 )
  105. # visulize animation in GoogleColab Notebook
  106. # suppress final output
  107. plt.close(0)
  108. HTML(anim.to_html5_video())

STS transformation:
> Multi-Step or Sequence Forecasting
A different type of forecasting problem is using past observations to forecast a sequence of future observations. This may be called sequence forecasting or multi-step forecasting.

So far, I could reach this output which is so ugly and incorrect.

如何在时间上重新生成滚动窗口的动画?

如何在时间上重新生成滚动窗口的动画?

答案1

得分: 0

在您想要的动画中,只有绿色和蓝色的矩形在移动,数据保持不变。因此,您的 update() 函数应该反映这一点。

所以您需要设置初始图形以您期望的方式,创建您想要动画的部分(使用 init()),然后使用 update() 创建帧:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from matplotlib.animation import FuncAnimation
  4. from matplotlib.patches import Rectangle
  5. import pandas as pd
  6. from IPython.display import HTML
  7. # 创建数据
  8. df = pd.DataFrame({
  9. "TS_24hrs": np.arange(0, 274),
  10. "count": np.abs(np.sin(2 * np.pi * np.arange(0, 274) / 7) + np.random.normal(0, 100.1, size=274)) # 生成季节性数据
  11. })
  12. # 创建绘图
  13. plt.style.use("ggplot") # <-- 设置整体外观
  14. fig, ax = plt.subplots(figsize=(10, 4))
  15. # 绘制数据
  16. plt.plot(df['TS_24hrs'], df['count'], 'r-', linewidth=0.5, label='data or y')
  17. # 使图形更美观
  18. plt.plot([], [], 'g-', label="Train", linewidth=8, alpha=0.3) # <-- 虚拟图例项
  19. plt.plot([], [], 'b-', label="Test", linewidth=8, alpha=0.3) # <-- 虚拟图例项
  20. plt.xticks([0, 50, 100, 150, 200, 250, df['TS_24hrs'].iloc[-1]], visible=True, rotation="horizontal")
  21. plt.title('数据绘图')
  22. plt.ylabel('count', fontsize=15)
  23. plt.xlabel('时间戳 [24小时]', fontsize=15)
  24. plt.grid(True)
  25. plt.legend(loc="upper left")
  26. fig.tight_layout(pad=1.2)
  27. Y_LIM = 280
  28. TRAIN_WIDTH = 25
  29. TEST_WIDTH = 10
  30. def init():
  31. rects = [Rectangle((0, 0), TRAIN_WIDTH, Y_LIM, alpha=0.3, facecolor='green'),
  32. Rectangle((0 + TRAIN_WIDTH, 0), TEST_WIDTH, Y_LIM, alpha=0.3, facecolor='blue')]
  33. patches = []
  34. for rect in rects:
  35. patches.append(ax.add_patch(rect))
  36. return patches
  37. def update(x_start):
  38. patches[0].xy = (x_start, 0)
  39. patches[1].xy = (x_start + TRAIN_WIDTH, 0)
  40. return patches
  41. # 创建 "Train" 和 "Test" 区域
  42. patches = init()
  43. ani = FuncAnimation(
  44. fig,
  45. update,
  46. frames=np.linspace(0, 230, 40), # 所有起始点
  47. interval=500,
  48. blit=True)
  49. HTML(ani.to_html5_video())

如何在时间上重新生成滚动窗口的动画?

英文:

In the animation you want, only the green and blue rectangles move and the data is constant. So your update() function should reflect it.

So what you need is to set up initial graph the way you desire, create the parts you want to animate (with init()) and then create frames using update():

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from matplotlib.animation import FuncAnimation
  4. from matplotlib.patches import Rectangle
  5. import pandas as pd
  6. from IPython.display import HTML
  7. # create data
  8. df = pd.DataFrame({
  9. &quot;TS_24hrs&quot;: np.arange(0, 274),
  10. &quot;count&quot; : np.abs(np.sin(2 * np.pi * np.arange(0, 274) / 7) + np.random.normal(0, 100.1, size=274)) # generate sesonality
  11. })
  12. # create plot
  13. plt.style.use(&quot;ggplot&quot;) # &lt;-- set overall look
  14. fig, ax = plt.subplots( figsize=(10,4))
  15. # plot data
  16. plt.plot(df[&#39;TS_24hrs&#39;], df[&#39;count&#39;], &#39;r-&#39;, linewidth=0.5, label=&#39;data or y&#39;)
  17. # make graph beautiful
  18. plt.plot([], [], &#39;g-&#39;, label=&quot;Train&quot;, linewidth=8, alpha=0.3) # &lt;-- dummy legend entry
  19. plt.plot([], [], &#39;b-&#39;, label=&quot;Test&quot;, linewidth=8, alpha=0.3) # &lt;-- dummy legend entry
  20. plt.xticks([0, 50, 100, 150, 200, 250, df[&#39;TS_24hrs&#39;].iloc[-1]], visible=True, rotation=&quot;horizontal&quot;)
  21. plt.title(&#39;Plot of data&#39;)
  22. plt.ylabel(&#39;count&#39;, fontsize=15)
  23. plt.xlabel(&#39;Timestamp [24hrs]&#39;, fontsize=15)
  24. plt.grid(True)
  25. plt.legend(loc=&quot;upper left&quot;)
  26. fig.tight_layout(pad=1.2)
  27. Y_LIM = 280
  28. TRAIN_WIDTH = 25
  29. TEST_WIDTH = 10
  30. def init():
  31. rects = [Rectangle((0, 0), TRAIN_WIDTH, Y_LIM, alpha=0.3, facecolor=&#39;green&#39;),
  32. Rectangle((0 + TRAIN_WIDTH, 0), TEST_WIDTH, Y_LIM, alpha=0.3, facecolor=&#39;blue&#39;)]
  33. patches = []
  34. for rect in rects:
  35. patches.append(ax.add_patch(rect))
  36. return patches
  37. def update(x_start):
  38. patches[0].xy = (x_start, 0)
  39. patches[1].xy = (x_start + TRAIN_WIDTH, 0)
  40. return patches
  41. # create &quot;Train&quot; and &quot;Test&quot; areas
  42. patches = init()
  43. ani = FuncAnimation(
  44. fig,
  45. update,
  46. frames=np.linspace(0, 230, 40), # all starting points
  47. interval=500,
  48. blit=True)
  49. HTML(ani.to_html5_video())

如何在时间上重新生成滚动窗口的动画?

huangapple
  • 本文由 发表于 2023年8月4日 21:42:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76836503.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定