{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Oscilloscope\n\nEmulates an oscilloscope.\n\nOutput generated via `matplotlib.animation.Animation.to_jshtml`.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\n\nimport matplotlib.animation as animation\nfrom matplotlib.lines import Line2D\n\n\nclass Scope:\n    def __init__(self, ax, maxt=2, dt=0.02):\n        self.ax = ax\n        self.dt = dt\n        self.maxt = maxt\n        self.tdata = [0]\n        self.ydata = [0]\n        self.line = Line2D(self.tdata, self.ydata)\n        self.ax.add_line(self.line)\n        self.ax.set_ylim(-.1, 1.1)\n        self.ax.set_xlim(0, self.maxt)\n\n    def update(self, y):\n        lastt = self.tdata[-1]\n        if lastt >= self.tdata[0] + self.maxt:  # reset the arrays\n            self.tdata = [self.tdata[-1]]\n            self.ydata = [self.ydata[-1]]\n            self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt)\n            self.ax.figure.canvas.draw()\n\n        # This slightly more complex calculation avoids floating-point issues\n        # from just repeatedly adding `self.dt` to the previous value.\n        t = self.tdata[0] + len(self.tdata) * self.dt\n\n        self.tdata.append(t)\n        self.ydata.append(y)\n        self.line.set_data(self.tdata, self.ydata)\n        return self.line,\n\n\ndef emitter(p=0.1):\n    \"\"\"Return a random value in [0, 1) with probability p, else 0.\"\"\"\n    while True:\n        v = np.random.rand()\n        if v > p:\n            yield 0.\n        else:\n            yield np.random.rand()\n\n\n# Fixing random state for reproducibility\nnp.random.seed(19680801 // 10)\n\n\nfig, ax = plt.subplots()\nscope = Scope(ax)\n\n# pass a generator in \"emitter\" to produce data for the update func\nani = animation.FuncAnimation(fig, scope.update, emitter, interval=50,\n                              blit=True, save_count=100)\n\nplt.show()\n\n# ..tags:: animation, plot-type: line"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.14.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}