{ "cells": [ { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "2e399b29-d227-4a3a-9667-e7a38677ed1c" }, "slideshow": { "slide_type": "-" } }, "source": [ "# Basic Data Processing with NumPy and Matplotlib\n", "\n", "## Overview, Objectives, and Key Terms\n", " \n", "In this lesson, we'll explore some core features of NumPy and Matplotlib and extend our Python based \"calculator\" to include processing of *arrays* of data. [NumPy](http://www.numpy.org/) is the basic numerical package for Python. A lot of its utility comes from its numerical, multidimensional array type, `ndarray`. Use of these arrays in a *vectorized* way often leads to significantly faster (and much more compact) code. Moreover, the array-valued results of numerical computations are easily visualized using Matplotlib, which was originally developed to provide MATLAB-like graphics in the Python environment. \n", "\n", "I think it's so important that students can create, process, and display data that I highlight it early in the course and revisit it throughtout. NumPy and Matplotlib together provide about the easiest way to work with data.\n", "\n", "### Objectives\n", "\n", "By the end of this lesson, you should be able to\n", "\n", "- *define and manipulate one-dimensional NumPy arrays*\n", "- *produce plots of data following best practices*\n", "- *load data from text files*\n", "- *save data to text files*\n", "\n", "\n", "### Key Terms\n", "\n", "- `numpy`\n", "- `ndarray` \n", "- `np.array`\n", "- `np.ones`\n", "- `np.zeros`\n", "- `np.linspace`\n", "- `np.sin`\n", "- `np.mean` (or `v.mean` where `v` is of type `ndarray`)\n", "- `max` (or `np.max` or `v.max`)\n", "- `sum` (or `np.sum` or `v.sum`) \n", "- `matplotlib.pyplot`\n", "- `np.loadtxt`\n", "- `np.savetxt`\n", "- `v.T`, where `v` is a two-dimensional `ndarray`\n", "- `str` formats" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from IPython.core.interactiveshell import InteractiveShell \n", "InteractiveShell.ast_node_interactivity = \"all\"" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "d944635a-8fcb-4dd8-9fd8-3d951df43601" }, "slideshow": { "slide_type": "slide" } }, "source": [ "## NumPy and One-Dimensional Arrays\n", "\n", "NumPy is not part of Python, but it is a well-supported package. It comes by default in the Anaconda distribution, so you should already have it. Like all packages, we can import NumPy via " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "nbpresent": { "id": "c7d6c030-605a-4284-a69a-fb09dc69061e" }, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import numpy" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "40df7c21-ec21-4697-a6ce-56b1c8c0d2dd" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "However, it is far more common to use " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "nbpresent": { "id": "b749b600-3e7f-4f3e-b82e-2d90dda169d6" }, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "f353b376-e74b-49d1-89d4-155658283c9d" }, "slideshow": { "slide_type": "subslide" } }, "source": [ "The difference between these approaches is in how we use the `numpy` module. Built in to `numpy` are a number of same functions we saw in `math`, e.g., `sin`. Hence, we could use `numpy.sin(1.0)`, but if we import `numpy` as `np`, we would use `np.sin(1.0)`. I recommend the latter because (1) it is shorter and (2) most online documentation uses the `np` abbreviation.\n", "\n", "> **Note**: Use `import numpy as np` instead of `import numpy`." ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c3ac8b3e-c8af-4d04-a74a-2f99222fec62" } }, "source": [ "### A Motivating Example\n", "\n", "Here's a common task easily solved using NumPy: evaluate a\n", "mathematical function `f(x)` at discrete\n", "points. Why discrete data? Perhaps because that's all the input data \n", "we have, e.g., from measurements, or perhaps we're trying to plot that \n", "function. In any case, this is where NumPy excels. Consider the specific\n", "case for which we want to evaluate $f(x) = \\sin(x)$\n", "for $x \\in [0, 1]$, where `x` is to limited to 10 evenly-spaced\n", "points. \n", "\n", "Here's what we need to do. First, always make sure NumPy is imported; in this \n", "notebook, we did that above, but here it is again for completeness." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "nbpresent": { "id": "2bf16a59-f0e4-4b84-a224-3499f4be6ca2" } }, "outputs": [], "source": [ "import numpy as np " ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "2910ae3c-511b-4e00-aebb-072a601ee9c8" } }, "source": [ "Now, we create an array `x` with 10, evenly-spaced points from 0 to 1\n", "using the function `np.linspace` as follows:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "nbpresent": { "id": "5d34201c-814d-4eb0-a6df-2b3d8ab41684" } }, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,\n", " 0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.linspace(0, 1, 10)\n", "x # remember, a variable all by itself as input prints its value as output" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ef9c28a3-5bdb-46b6-a78b-431fd1d30805" } }, "source": [ "Finally, we evaluate the function `np.sin` at these points." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "nbpresent": { "id": "0d77e572-b4c3-4e48-8097-adcef183ee44" } }, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.11088263, 0.22039774, 0.3271947 , 0.42995636,\n", " 0.52741539, 0.6183698 , 0.70169788, 0.77637192, 0.84147098])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = np.sin(x)\n", "y" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "047813b2-f745-4719-9494-24c0cd9bffe6" } }, "source": [ "Note that `np.sin(x)` is used and not `math.sin(x)`. That's because `x` in this case is a `ndarray`, to which the\n", "base Python `math` functions do not apply. \n", "\n", "The function `np.linspace(a, b, n)` gives `n` evenly-spaced points starting with `a` and ending with `b`. Writing the equivalent C++ or Fortran to define such an `x` is a royal pain; that's why Python+NumPy (or MATLAB/Octave) is so nice for this type of problem." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "nbpresent": { "id": "34091a11-965e-410c-8301-7a1478106486" } }, "source": [ "### Creating and Manipulating 1-D Arrays" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "843efd91-8f2e-4abc-b7af-3deb9f003eb4" } }, "source": [ "We already saw one way to create a one-dimensional array, i.e., `np.linspace`. There are many other ways to create these arrays. Suppose we have a list of numbers, e.g., 1.5, 2.7, and 3.1, and we'd like to make an array filled with these numbers. That's easy:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "nbpresent": { "id": "d1338d3b-74f3-45ae-b49c-e9bbc3d499c9" } }, "outputs": [ { "data": { "text/plain": [ "array([1.5, 2.7, 3.1])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.array([1.5, 2.7, 3.1])\n", "a" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "32fff475-8295-4b72-b660-d4dad320bb25" } }, "source": [ "(It turns out that `[1.5, 2.7, 3.1]` is actually a Python `list`, but we'll cover those later on when we need them; for now, we'll stick with NumPy arrays exclusively.)\n", "\n", "The common ways to make 1-D arrays are listed in the table below.\n", "\n", "| function | example use | what it creates creates | \n", "|---------------|---------------------------------|-----------------------------|\n", "| `np.array(sequence)` | `np.array([1.5, 2.7, 3.1])` | `array([ 1.5, 2.7, 3.1])` |\n", "| `np.linspace(start, stop, num)` | `np.linspace(0, 1, 3)` | `array([ 0. , 0.5, 1. ])` |\n", "| `np.ones(shape)` | `np.ones(3)` | `array([ 1., 1., 1.])` |\n", "| `np.zeros(shape)` | `np.zeros(3)` | `array([ 0., 0., 0.])` |\n", "| `np.arange(start, end, step)` | `np.arange(1, 7, 2)` | ` array([1, 3, 5])` |\n", "\n", "The table does not tell the whole story of these functions; use `help()` or the `?` mark for further details." ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "nbpresent": { "id": "73cffb9a-90ee-4f92-a71f-858759133eb0" } }, "source": [ "A useful aspect of NumPy arrays is that the basic arithmetic \n", "operations of Python (think `+` and `*`) apply to such arrays via *vectorized* operations.\n", "For example, two arrays *of equal length* can easily be multiplied:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "nbpresent": { "id": "d83ea8c1-3fd3-4f42-ac60-2f3334dc5d1a" } }, "outputs": [ { "data": { "text/plain": [ "array([ 2, 6, 12])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.array([1, 2, 3])\n", "b = np.array([2, 3, 4])\n", "c = a*b\n", "c" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "f4c615a0-5c0a-4537-8886-ff0d1f2df3cc" } }, "source": [ "Individual arrays can also be operated on by arithmetic operaters. For instance, we could double each element of `a` by doing" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "nbpresent": { "id": "cee25d6f-74f7-47b4-adfa-7181b1fdf9cb" } }, "outputs": [ { "data": { "text/plain": [ "array([2, 4, 6])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d = 2*a\n", "d" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "16301cce-e2f8-4df6-8145-dd4d2205aab0" } }, "source": [ "### Inspecting Arrays and Their Elements" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "a9a4543c-39d7-4f53-aefd-d9e1548f114c" } }, "source": [ "What if we need to get the value of an array element? For example, suppose, as done above, we doubled the array `a`, called it `d`, and wanted the first value of `d`. We need to use array `indexing` via the operator `[]`. Here's how we get that first value of `d`:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "nbpresent": { "id": "2aea0c67-93d3-4332-84ad-d75fe0225a9d" } }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d[0]" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ca145966-b9d7-4317-816e-c7fe6ff2e983" } }, "source": [ "Yes--the first element is accessed using a zero. Python, like C, C++, and many other languages, is based on [zero indexing](https://en.wikipedia.org/wiki/Zero-based_numbering), in which the numbering of sequences starts with zero. Get used to it!\n", "\n", "> **Warning**: Numbering starts with zero in Python\n", "\n", "By using indexing, we can *change* the value of `d[0]`, too, e.g.," ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "nbpresent": { "id": "9dba623e-eeae-4fba-9819-15429ed53f9e" } }, "outputs": [ { "data": { "text/plain": [ "array([99, 4, 6])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d[0] = 99\n", "d" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "f68a00b1-2587-4c13-9aa4-b841d3f20185" } }, "source": [ "The number of elements in an array can be found in two ways. First, we can use the built-in `len` function:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "nbpresent": { "id": "b120c52a-1966-46db-ab64-83a226ea74d3" } }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(d)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "8870b445-238d-4dec-b25f-d4ebeb5ddb02" } }, "source": [ "We can also use the `size` *attribute*, associated with any array, that can be accessed through the `.` operator:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "nbpresent": { "id": "0a95b785-c644-42b0-bd2f-2a990b8559c0" } }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.size" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want to access the last element of `d`, we can use that length directly via" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d[len(d)-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "but a much cleaner way to do so is via" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In fact, by using a negative number, the elements are accessed in reverse starting from the last element. In other words, `d[-1]` is the same as `d[len(d)-1]`, `d[-2]` is the same as `d[len(d)-2]`, and so on.\n", "\n", "> **Note**: Access the $i$th to last element of `array` via `array[-(1+i)]`." ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "7cd39b4b-3858-4138-a9e7-76a6d3b07a13" } }, "source": [ "What else do arrays have to help us? Try using `dir`! " ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "nbpresent": { "id": "cd03f52d-725f-4b62-bc32-78a3a37de256" } }, "outputs": [ { "data": { "text/plain": [ "['T',\n", " '__abs__',\n", " '__add__',\n", " '__and__',\n", " '__array__',\n", " '__array_finalize__',\n", " '__array_interface__',\n", " '__array_prepare__',\n", " '__array_priority__',\n", " '__array_struct__',\n", " '__array_ufunc__',\n", " '__array_wrap__',\n", " '__bool__',\n", " '__class__',\n", " '__complex__',\n", " '__contains__',\n", " '__copy__',\n", " '__deepcopy__',\n", " '__delattr__',\n", " '__delitem__',\n", " '__dir__',\n", " '__divmod__',\n", " '__doc__',\n", " '__eq__',\n", " '__float__',\n", " '__floordiv__',\n", " '__format__',\n", " '__ge__',\n", " '__getattribute__',\n", " '__getitem__',\n", " '__gt__',\n", " '__hash__',\n", " '__iadd__',\n", " '__iand__',\n", " '__ifloordiv__',\n", " '__ilshift__',\n", " '__imatmul__',\n", " '__imod__',\n", " '__imul__',\n", " '__index__',\n", " '__init__',\n", " '__init_subclass__',\n", " '__int__',\n", " '__invert__',\n", " '__ior__',\n", " '__ipow__',\n", " '__irshift__',\n", " '__isub__',\n", " '__iter__',\n", " '__itruediv__',\n", " '__ixor__',\n", " '__le__',\n", " '__len__',\n", " '__lshift__',\n", " '__lt__',\n", " '__matmul__',\n", " '__mod__',\n", " '__mul__',\n", " '__ne__',\n", " '__neg__',\n", " '__new__',\n", " '__or__',\n", " '__pos__',\n", " '__pow__',\n", " '__radd__',\n", " '__rand__',\n", " '__rdivmod__',\n", " '__reduce__',\n", " '__reduce_ex__',\n", " '__repr__',\n", " '__rfloordiv__',\n", " '__rlshift__',\n", " '__rmatmul__',\n", " '__rmod__',\n", " '__rmul__',\n", " '__ror__',\n", " '__rpow__',\n", " '__rrshift__',\n", " '__rshift__',\n", " '__rsub__',\n", " '__rtruediv__',\n", " '__rxor__',\n", " '__setattr__',\n", " '__setitem__',\n", " '__setstate__',\n", " '__sizeof__',\n", " '__str__',\n", " '__sub__',\n", " '__subclasshook__',\n", " '__truediv__',\n", " '__xor__',\n", " 'all',\n", " 'any',\n", " 'argmax',\n", " 'argmin',\n", " 'argpartition',\n", " 'argsort',\n", " 'astype',\n", " 'base',\n", " 'byteswap',\n", " 'choose',\n", " 'clip',\n", " 'compress',\n", " 'conj',\n", " 'conjugate',\n", " 'copy',\n", " 'ctypes',\n", " 'cumprod',\n", " 'cumsum',\n", " 'data',\n", " 'diagonal',\n", " 'dot',\n", " 'dtype',\n", " 'dump',\n", " 'dumps',\n", " 'fill',\n", " 'flags',\n", " 'flat',\n", " 'flatten',\n", " 'getfield',\n", " 'imag',\n", " 'item',\n", " 'itemset',\n", " 'itemsize',\n", " 'max',\n", " 'mean',\n", " 'min',\n", " 'nbytes',\n", " 'ndim',\n", " 'newbyteorder',\n", " 'nonzero',\n", " 'partition',\n", " 'prod',\n", " 'ptp',\n", " 'put',\n", " 'ravel',\n", " 'real',\n", " 'repeat',\n", " 'reshape',\n", " 'resize',\n", " 'round',\n", " 'searchsorted',\n", " 'setfield',\n", " 'setflags',\n", " 'shape',\n", " 'size',\n", " 'sort',\n", " 'squeeze',\n", " 'std',\n", " 'strides',\n", " 'sum',\n", " 'swapaxes',\n", " 'take',\n", " 'tobytes',\n", " 'tofile',\n", " 'tolist',\n", " 'tostring',\n", " 'trace',\n", " 'transpose',\n", " 'var',\n", " 'view']" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(d)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "8a35d33a-bfd6-456a-bb3f-d3d9a15a37b0" } }, "source": [ "Several names worth pointing out are `dot`, `max`, `mean`, `shape`, and `sum`. The `max`, `mean`, and `sum` functions have pretty intuitive names (and purposes):" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "nbpresent": { "id": "2a53b60e-b4f0-4967-817b-dc15bba9bf22" } }, "outputs": [ { "data": { "text/plain": [ "99" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.max()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "nbpresent": { "id": "bca634f7-6639-407c-85b2-ba0d3ba2ad9c" } }, "outputs": [ { "data": { "text/plain": [ "36.333333333333336" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.mean() # here, (99+4+6)/3" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "nbpresent": { "id": "15c2afe2-64fb-470e-aadd-84e22f7ccb72" } }, "outputs": [ { "data": { "text/plain": [ "109" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.sum()" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "b150c2ce-4268-4e3f-94ef-3f0dd7088b79" } }, "source": [ "It turns out that Python has `max` and `sum` as built-in functions. Hence, we could instead do" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "nbpresent": { "id": "983c773e-9265-4dfc-b9c0-de5d867a5a06" } }, "outputs": [ { "data": { "text/plain": [ "99" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(d)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "nbpresent": { "id": "591b707d-dd57-4460-a76a-9fb1a80d7a76" } }, "outputs": [ { "data": { "text/plain": [ "109" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(d)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c20cb43d-37ea-4f1a-bca2-4f7a4f2b8242" } }, "source": [ "but not `mean(d)` because `mean` is not a built-in function. However, `mean` *is* a NumPy function, so we could do" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "nbpresent": { "id": "7d5aea0d-8552-4408-b402-54db871102f3" } }, "outputs": [ { "data": { "text/plain": [ "36.333333333333336" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.mean(d)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0846eae5-9037-436a-80c4-f146ea24c6d8" } }, "source": [ "There is no real difference between `d.mean()` and `np.mean(d)`. My own personal preference is the latter because it looks closer to the programming I first learned eons ago." ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c734f840-7a1d-40c8-9df4-9f905d3e330f" } }, "source": [ "The `shape` attribute is somewhat special; here it is for `d`:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "nbpresent": { "id": "c0f58cf7-3066-489d-a673-751126c4ea26" } }, "outputs": [ { "data": { "text/plain": [ "(3,)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.shape" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "19e6a46b-1ce8-4ed6-98a3-3e1dc012d1c0" } }, "source": [ "Here, the shape indicates a purely one-dimensional array. We'll see below that `shape` is a bit more interesting for two-dimensional arrays." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, the `dot` function implements the [dot product](https://en.wikipedia.org/wiki/Dot_product), sometimes called the *scalar* product, for two arrays. In mathematics, we typically refer to one-dimensional arrays of numbers as *vectors*. For two vectors `c` and `d` of length $n$, the dot product is defined as \n", "\n", "$$\n", " \\mathbf{c} \\cdot \\mathbf{d} = c_0 d_0 + c_1 d_1 + \\ldots c_{n-1} d_{n-1} = \\sum_{i=0}^{n-1} c_i d_i \\, ,\n", "$$\n", "\n", "where $c_i$ is the $i$th element of $\\mathbf{c}$. In NumPy, that operation is done via" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "294" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c.dot(d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "294" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.dot(c, d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course, knowing how the dot product is defined, we could also use basic element-wise arithmetic coupled with the built-in `sum` function, e.g.," ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "294" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(c*d)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ccdc1aaf-d5fd-45d2-ace2-befe2ddcbba3" } }, "source": [ "## Diving into `pyplot`" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "591b8b01-66ce-4003-a2dc-6aad17308a73" } }, "source": [ "Recall our motivating example: defined `x` at evenly spaced points, and evaluate `np.sin` at those points. We printed the points and the function at those points, but it's often useful to *show* it via a graph. [Matplotlib](https://matplotlib.org) gives us the tools to do just that. The most common way to import Matplotlib (and, specifically, its `pyplot` \"submodule\") is via" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "nbpresent": { "id": "591a3dac-2afc-4055-a043-a75b15a15e84" } }, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "fbbc7a45-be27-4130-a861-a31380127143" } }, "source": [ "In other words, `plt` is used as an abbreviation to the longer `matplotlib.pyplot`.\n", "\n", "> **Note**: Just like NumPy is often shorted to `np`, `matplotlib.pyplot` is often used as `plt`. " ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "5f5a272b-a97d-411d-ae62-12c637a40f6e" } }, "source": [ "The most basic plot is very easy to make using `plt.plot`:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "nbpresent": { "id": "ef2abeac-8f8c-48c0-a3ea-c6e93409e5da" } }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(x, y) # x and y were defined above" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "c1d6e507-2c59-477b-9000-d4458050888b" } }, "source": [ "To show the plot, we need to use `plt.show`:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "nbpresent": { "id": "298df42f-86a5-47ef-97f7-c9eb75a27ec3" } }, "outputs": [], "source": [ "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "47fb4b50-a33d-4d01-b72a-608226dcd179" } }, "source": [ "### Multiple Curves and Best Practices\n", "\n", "What about multiple curves? Let's define a second curved equal to `np.cos` evaluated at `x`:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "nbpresent": { "id": "8f02aa22-6c80-4f40-b224-1b3bc3855898" } }, "outputs": [], "source": [ "z = np.cos(x)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "d63733fb-11ed-4dd1-8f60-c2a5fc3903c1" } }, "source": [ "To plot both `y` and `z` is also easy, and here, I've added a couple extra features that define the basic ingredients needed for a good plot:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "nbpresent": { "id": "5b5b877c-7b4c-4adf-852c-ea73ffd6a3be" } }, "outputs": [ { "data": { "text/plain": [ "[,\n", " ]" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "Text(0.5,0,'x')" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAEKCAYAAADpfBXhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XlYVeX2wPHvq2GKZeZQ1xxAywkQMzG7t7LIITOnyspySFNRc/rlNedyxCnNsWuimaaUmVlqmlOidktLzHkoUQS5NpCZmrOyfn+8TCLDAQ4cOKzP85wHzt6bc9YWXLys/e53GRFBKaWUeynk6gCUUko5nyZ3pZRyQ5rclVLKDWlyV0opN6TJXSml3JAmd6WUckOa3JVSyg1pcldKKTekyV0ppdzQLa564zJlyoi3t7er3l4ppfKlnTt3/iEiZTM6zmXJ3dvbm/DwcFe9vVJK5UvGmChHjtOyjFJKuSFN7kop5YY0uSullBtyWc1dKaXScvXqVWJiYrh06ZKrQ3GZokWLUqFCBTw8PLL09ZrclVJ5TkxMDLfffjve3t4YY1wdTq4TEU6dOkVMTAyVK1fO0mtkWJYxxsw3xvxujNmfxn5jjJlhjIkwxuw1xjyQpUgyMmkShIXduC0szG5XSrmVS5cuUbp06QKZ2AGMMZQuXTpbf7k4UnNfADRNZ/9TQNX4RxAwO8vRpKdePXjhhaQEHxZmn9erlyNvlyb9JaNUriioiT1Bds8/w7KMiGw1xninc0gr4EOx/fq2G2NKGmPKicgv2YospcBAWLrUJvQGDWDdOujcGSIi4H//gzJloGn876DDh+HKFfD0hGLF7MPTE4oWzX4cCb9kli61MSX8klm6NPuvrZRSTuKMmnt54ESy5zHx225K7saYIOzonkqVKmX+nQIDoWdPGDPGPp81K2lfzZpJyb1rV/j22xu/NiAAduxIep0jR25M/P/8J0ydavcPGABnzybtK1YM/Pzg2Wft1/bpA61bQ6tW8OWXEBpqtyul3FbXrl3p378/Pj4+6R43bdo0SpUqRceOHdM8pm3btowZM4aqVas6O8xEzkjuqf3tkGrXbREJAUIAAgICMt+ZOywMZs+G4cPhvfdg3jyoWxcuXrzxuAkT4Ndf7faER+nSSfsbNoQqVez2Cxfsx1uS/VNs2wbHjiV97ZUr0KaNTe5gfwmcPQuLFtnnzZpBUBDMmQMi0KsX3H03lC8PFSrYj15eUKJEpk9ZKZWx0NBQhg0bRnR0NJUqVSI4OJh27do59T3mzZuX4THXrl1j/vz5/Pjjj+ke17NnTyZNmsTcuXOdFd7NRCTDB+AN7E9j3xzgpWTPfwLKZfSadevWlUzZtEmkTBn7MbXnOenaNZFLl5KeL1woUrKkSPv2IrffLtKli8gXX9h9f/8t8o9/iBgjYlO9fQwZYvf/9ZfI44/brx00SGTmTJHPPxeJjs5cTBMn3nzumzbZ7UrlcwcPHnT42MWLF4unp6dgB5UCiKenpyxevDjL7//3339Ls2bNxN/fX3x9fWXJkiXy2GOPyY4dO0REpHjx4jJ06FDx9/eX+vXry6+//ioiIuvWrZNXXnlFRESuXr0qAQEBEhYWJiIigwcPlqFDh4qIyPXr18Xb21uuXr2abhyp/TsA4eJA3nbGyH0l0NsYswSoD5wRZ9fbwZZUEurckFSD37Ej50sihQvbB9i/Hv79b1i+/Maae8IooXhx+OUXuHrVfoyJsdcEEv78OnfO7vvvf+32q1ft9v/8x5ac9u+Hp56yI/6EUX+FCrYEVLWqPT4uTmv/qsD4v//7P3bv3p3m/u3bt3P58uUbtl24cIEuXbqkOTK+//77mTZtWpqvuXbtWu655x5Wr14NwJkzZ5g9O2muyPnz53nooYcIDg5m4MCBzJ07l+HDh/Ptt99St25dAG655RYWLFhAmzZtmDFjBmvXruX7778HoFChQtx3333s2bMn8XhnyzC5G2M+Bh4HyhhjYoARgAeAiLwHrAGaARHABaBzjkQ6cODN2wIDc7/W7egvGQ8PqFTJPpKrUMEmdrBJ+o8/7C+Ae+6x22691ZaNYmJsov/qKzh/HqpXt8l940ZbBipbFkqWtNcZ6tSx1xCWLdPavypwUib2jLY7olatWgwYMIBBgwbRvHlzHn300Rv2FylShObNmwNQt25dNmzYAMAvv/xCzZo1E4/z9fWlQ4cOtGjRgm3btlGkSJHEfXfddRcnT550XXIXkZcy2C9AL6dFlNc585dMoUJw1132kaBqVViwIOm5iK3v33qrfV6lCowenfQXwdmz8P330L27jWHBAnvNoVYt8PdP+ujtbd9PqXwmvRE22BVmo6JuXijRy8uLzZs3Z+k9q1Wrxs6dO1mzZg1DhgyhSZMmN+z38PBInKpYuHBhrl27BkCxYsVumpu+b98+SpYsyW+//XbD9kuXLlGsWLEsxecIvUM1rzMG7rgj6Xn16vDmm/bzhFLMsGH2Yu6LL9oLuT4+sGsXfPaZ/eUA9i+E0qVh9WqIjLRJv1YtKFUq989JKScKDg4mKCiICxcuJG7z9PQkODg4y6958uRJSpUqRfv27bnttttYkHzAlY6aNWsSERGR+Hz58uWcOnWKrVu30rx5c3744QdKliwJwM8//4yvr2+WY8yQI4X5nHhk+oKqupEjF5jPnRPZvt1eAE7QseONF3rLlxd57rmk/SdPily+nDvnoFQaMnNBVcReVPXy8hJjjHh5eWXrYqqIyNq1a6VWrVpSu3ZtCQgIkB07dtx0QTXBp59+mngR9fjx4/Loo4+KiEhsbKxUrVpVouMnS0yfPl06duwoIiK//vqr1KtXL8M4snNB1YhkfkaiMwQEBIg268iGSZPsRdXk5aCwMFv7T610lEDEXujduxf27bMfRWDxYrv/X/+C8HCoUSOprPPPf9obx5wZh1LpOHTo0A216/zkmWeeYdKkSenOYZ86dSolSpSgS5cu6b5Wav8OxpidIhKQURxalsmvslr7N8ZevL3nnqSbvpIbMMAm5r17YetWe4NWq1ZJyf3FF+01An9/+/Dz01k7SiUzYcIEfvnll3STe8mSJenQoUOOxqHJXd3o2WeTbtYCOH3aTt8EezPXiROwZg38/XfSMe3a2YTeo4e9azj5bCKlCpjq1atTvXr1dI/p3DlnJhUmp8ldpe/OO+0DoEgR+O47O4Xz+PGksk79+nYWT8KyEK1b2/LOY4/Zx4MPJs32UUrlCp0bpzKvUCGbzFu1sjN3PDzsshADB9olFpo0gd9+s/sSFnkDiIqCzZtvXi5CKeV0OnJX2ZO8xh4YaOv4Cc/9/eGbb+zoHeCjj2DoUPsXQP36dnuDBvD44/YXhFLKaXTkrrInvTt2S5e2JZqEefo9e8KqVdC3L1y6BOPHQ4sWcP263b92rX0k1PiVUlmmI3eVPZmZtVOyJDRvbh9gk/iBA0nr7I8da5dqLlwYHnjAjuyffBIaNcq5+JXKIbt27eLdd99NdzXJWbNmUbx48Ry5wKojd+U6t98ODz2U9HzdOtiwAYYMsQl/xgz7SDBuHHzxBZw6dfNraYesgiuPfu/HjRtHnz590j3m1VdfZUbyn3En0uSu8o7ixe0ofcwYO8f+r7/shVqAM2fsyP6ZZ2zXLX9/2zQlfpW9PNOGUeW+HPref/jhh/j7+1O7dm06dOhAVFQUDRs2xN/fn4YNGxIdHQ3Ap59+ip+fH7Vr16ZB/P0g586dY+/evdSuXRuAvn37Mnr0aADWrVtHgwYNiIuLw9PTE29vb3744YdsxZoqR25jzYmHLj+gMu3SJZFvvhEZO1akcWMRT0+RuXPtvmPHRFq0sOvrDxiQe2v9qxxx0233jz128+Pdd+2+8+dF/P1FPDxEKlWyH/39RT74wO6Pjb35azOwf/9+qVatmsTGxoqIyKlTp6R58+ayYMECERF5//33pVWrViIi4ufnJzExMSIicvr0aRER2bRpkzz77LOJr3f+/Hnx8fGRTZs2SbVq1SQiIiJx39ixY2Xy5MmO/TuI48sP6Mhd5R+33gqPPGIXSlu/3o7s27e3+376yU6zPHcOJk+G226z8/D/+sulIatccuedUK4cREfbjwn3ZmTRpk2baNOmDWXKlAGgVKlSbNu2jZdffhmADh068N/4pbsffvhhOnXqxNy5c7kePzngl19+oWzZsomv5+npydy5c2ncuDG9e/fm3nvvTdyXsPSvs+kFVZV/eXgkTaFs2tQ2UHn+efD1he3boV8/u1wC2PVyihSxa+Vks6u8coH0lu719IQRI2wp5s03bSlvxIiki/plyqT/9akQkcQlfdOSsP+9997j+++/Z/Xq1dx///3s3r07zaV/S5cufVMiz6mlf3XkrtxDWBi89JJN8P/9r70wW6oUHDxo9w8fDrVr25uvXn/d/mePX4Nb5XPJ77UYPdp+TF6Dz4KGDRuydOlSTsVfvP/zzz/517/+xZIlSwDbs/WRRx4B4OjRo9SvX5/Ro0dTpkwZTpw4cdPSv1FRUUyZMoVdu3bx1VdfJXZkArv0r5+fX5ZjTZMjtZuceGjNXTlVRj1lf/3V1uefflrk1lvtcseNGycde+VK7sWqMpSpJX9zqJ/wggULxNfXV/z9/eWVV16RyMhICQwMlFq1askTTzwhUVFRIiLyzDPPiJ+fn/j6+krfvn0lLi5ORGwt/uzZsxIXFycNGzaUFStWiIhIeHi4+Pn5ycWLF0VEpE6dOom1/ZR0yV+lMuPvv+20yyJF7E1Uf/8NFSvau2Vbt7bz8JPVS1Xuy89L/iaYOnUqt99+O127dk3zmF27dvHOO++waNGiVPdnZ8lfLcuogue22+C552xiB7hwATp2hN274dVX4R//sIl++3bXxqnytZ49e3JrBgvm/fHHH4xJWHDPyTS5K3XXXTB9ul3p8scfbX3+7Fk77x5s7Xb4cHtR1kV/6ar8p2jRohmu2d64cWO8vb1z5P01uSuVwBioUwdGjbKj+Fq17Pbvv7fr4NSrB5UqQa9e9oJtXJxr43VzrioZ5xXZPX9N7kplZPBgu4TxggU2wX/wAXTtmjSlMjzcjvTz6G3w+VHRokU5depUgU3wIsKpU6comrDuUhboBVWlMuviRTh2zM6nv37d3jRz5oydannokE3+bdrcvByyctjVq1eJiYm5aa54QVK0aFEqVKiAR4rlsLWHqlI5pVgxm9jBjt4/+wxWrIDPP7czb55/3q5Rv3+/JvYs8vDwoHLlyq4Ow+lCQ0MZNmwY0dHRVKpUieDgYNq1a5cj76VlGaWyo1AhePRRu+RBRIRd8uDxx+1NUj172rXsn38evvwSrl51dbTKhUJDQwkKCiIqKgoRISoqiqCgIEJDQ3Pk/TS5K+UsxkBsrB2xJ9wGv2qVTfQtWkCFCtC/v+07qwqUv/76i759+3LhwoUbtl+4cIFhw4blyHtqclfKWVK7DX7WLNtecMUKePhh+/yRR5L6yOpo3m3FxcXx9ddf065dO8qVK8eff/6Z6nEJSwc7myZ3pZwlrZaDu3ZBy5Z23ZuTJ21tvlgxO2e+Xj3baHz5crhyxbXxK6eIjIxkxIgRVKlShUaNGrFmzRpeffVV/vGPf6R6fKVKlXImEEfWKMiJh64towq8S5dE3nhDpFw5u9ZN6dIivXuLZGZdFZUnnD9/XhYtWiSBgYECiDFGGjduLB9//HHiGjKLFy8WT09PARIfnp6esnjx4ky9Fw6uLaPJXSlXu3pVZM0akRdftIuaffSR3f7nnyInT7o2NpWmuLg42bZtm3Tr1k1KlCghgFSpUkVGjx6duKhYSosXLxYvLy8xxoiXl1emE7uIkxcOM8Y0BaYDhYF5IjIhxf5KwEKgZPwxg0VkTXqvqfPclUrF6dN2ffJbb4WJE2HoUNskvFMnW9rJxk0tyjl+/fVXFi1axPz58zl8+DCenp60adOGV199lUcffZRChXK22u20ee7GmMLAu0BjIAbYYYxZKSIHkx02HFgqIrONMT7AGsA7S5ErVZAl7yD03HO2s9SHH9qmIyVLQrt2MHOmNhzJZVeuXGH16tV88MEHrFmzhuvXr/Ovf/2LefPm8fzzz1OiRAlXh3gTR37FPAhEiMgxEbkCLAFapThGgISzuwNwfs8opQqa++6zTcGPH4eNG+1SxL/+mpTYQ0PhxAmXhuju9u3bR//+/SlfvjzPPvss4eHhDBgwgMOHD/Ptt9/SpUuXPJnYwbE7VMsDyX+CYoD6KY4ZCaw3xvQBigONnBKdUsreKNWwoX0klFFjY+0yxSJ2+yuvwLPP2pKOypbTp0/z8ccfM3/+fHbu3ImHhwctW7bk1VdfpUmTJtxyS/64sd+RkXtqf/+lLNS/BCwQkQpAM2CRMeam1zbGBBljwo0x4bGxsZmPVqmCLmHUXrYsHDkCb70FR49Chw52Hfp163QBsyy4fv0669ev56WXXqJcuXL06tWLq1evMm3aNE6ePMmyZcto1qxZvknsQMazZYB/AuuSPR8CDElxzAGgYrLnx4C70ntdnS2jlJNcvy6yebNI584iv/xiW8yVKCHyyisikZH2eZkyN7eiK0DSmqUSEREhw4cPlwoVKgggd955p/Tu3Vt27tyZ2C4vr8FZUyGxpZtjQGWgCLAH8E1xzFdAp/jPa2Jr7ia919XkrlQOevFF+98bRIoUEXn7bZE8mqxyWmrzy4sUKSI1atRInJPetGlT+eSTTxLnpOdljiZ3R6dCNgOmYac5zheRYGPM6Pg3WRk/Q2YucFv8P95AEVmf3mvqVEilcli/fjBjhq3DX7hg+8N+/rmro8p13t7eREVF3bT9lltuYdSoUXTs2JEKFSq4ILKscXQqpK7nrpQ7SljnpmdPu4BZly52qYPnnoPz52HMGOjeHdxwWd3krly5kmYfU2MMcfmwm5Y2yFaqoEptAbP334dSpez+b7+1SxTfe69d1+brr92uN+wff/xBcHBwumvC59iaLnmEJnel3E1aC5jt2GGfN2li584PHQrbtkGjRrZf7OnTLgvZWfbv30+3bt2oWLEiw4cPx8/PjzfeeAPPFFNEPT09CQ4OdlGUucSRwnxOPPSCqlJ5wMWLIgsWiHTpkrRt6VI7yyafuH79uqxatUoaNmwogBQrVky6d+8uBw4cSDzGGWu65BU484JqTtCau1J50IULcPfd9mPLltC3r+0slQeXOzh37hwLFy5k+vTpREREUL58eXr37k23bt0oXbq0q8PLMVpzV0plnqenbfI9eDB88w088QT4+9s6fR4RGRnJv//9bypUqECfPn0oU6YMS5YsITIyksGDB7t1Ys8MTe5KqRtVqADBwXbdmvnzoUgRe0cswM8/23p9LhMRtm7dyrPPPst9993HjBkzaNasGdu2bWPbtm28+OKLeHh45HpceZkmd6VU6ooVg86dYedOqFbNbhsyxM6yeeYZOysnh8u6ly9fZuHChdStW5fHHnuMLVu2MGjQICIjI/n444956KGHcvT98zNN7kopx02bBoMG3ViyWbLE6W/z22+/MWrUKLy8vOjUqROXL19mzpw5nDhxgnHjxuWrm45cRZO7UspxFSvCuHFJJZvChW2NHuD6dchms+fdu3fTqVMnKlWqxMiRI6lbty7r169n//79BAUF3TSlUaUtHy1xppTKMxJKNp06wdWrdtuqVfYO2NatoU8f+P57ePDBpPn2YEs5O3bAwIGJm65fv86qVauYNm0aW7ZswdPTk27dutGnTx+qV6+eu+flRnTkrpTKOmPsBVeAgACbtDdvtgl9zhw7nXLDBrs/4c7ZevUAOHPmDFOnTqVq1ao888wzHD9+nLfffpuYmBhmzZqliT2bNLkrpZyjQgUYPx5iYmDePLj9di7ccgunmjZljDH82agRG4OCiKhYkX79+lGhQoXELkfLli0jIiKCAQMGcGfyVoMqy/QmJqVUjghdvJg3g4LodPEibwGngQ+N4W0RfvfwoG3btvTr14+6deu6OtR8RVeFVEq5lLe3N5WjolgKLAR6Yy/yxQHX2rXDc9QoO61SZYreoaqUcpnLly8nJvYXgDeAp4AzwBrAc9kyO3c+YaaNcjpN7kopp7l48SIzZszg3nvvpR42sW+O37cZaAMcKlkSIiNh6lSoUcPunD8f9C95p9LkrpTKtr///pvJkydTuXJl+vXrR5UqVSg0aBA/pJiX/oOnJ5VmzYJy5eyiZMbA5cswfLidRdO0qb1BSmWbJnelVJadOXOG4OBgvL29eeONN6hVqxabN29m69atTJgwgZCQELy8vDDG4OXlRUhICO3atbvxRW69FQ4ftjNtfvwRGjSARx+F3btdc1JuQi+oKqUy7c8//2T69OnMmDGDv/76i2bNmjF8+HD++c9/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gISH65Lv+cGlS5cYP348EyZMwNPTk4kTJ9K1a1cKFdKxgVK5zRizU0RuaoaUkk6FVOnatGkTPXr04MiRI7z88su888473H333a4OSymVAR16qVTFxsbyyiuv0LBhQ65fv866desIDQ3VxK5UPqHJXd1ARPjggw+oUaMGH330EUOHDmX//v00adLE1aEppTJByzIq0aFDh+jRowdbt27l4YcfZs6cOfj6+ro6LKVUFujIXXHp0iXeeustateuzd69e5k7dy5bt27VxK5UPqYj9wLu66+/pmfPnhw5coR27doxZcoUrasr5QZ05F5A/f7773To0IFGjRoRFxfH+vXrWbx4sSZ2pdyEJvcCJi4ujvfff58aNWrwySefMHz4cPbt20fjxo1dHZpSyom0LFOAHDx4kB49evDNN9/wyCOPMGfOHHx8fFwdllIqB+jIvQC4ePEiw4cP5/7772f//v3MmzePLVu2aGJXyo3pyN3NbdiwgZ49e3L06FHat2/PlClTuOuuu1wdllIqh+nI3U39/vvvtG/fniZNmmCMYcOGDSxatEgTu1IFhCZ3NxMXF8e8efOoUaMGS5cu5c0332Tfvn00atTI1aEppXKRJvd8LGVj6okTJ9KgQQO6detGrVq12LNnD6NHj6Zo0aKuDlUplcu05p5PpdaYevDgwRQvXpz58+fTqVMnjDEujlIp5Sqa3POptBpT33nnnXTu3NkFESml8hIty+RTaTWm/t///pfLkSil8iKHkrsxpqkx5idjTIQxZnAq+/sbYw4aY/YaY742xng5P1QFdknejz76KM2SizamVkqBA8ndGFMYeBd4CvABXjLGpLz7ZRcQICL+wDJgkrMDVbau/vTTT9OuXTu8vb1vulCqjamVUgkcGbk/CESIyDERuQIsAVolP0BEwkQkoQC8Hajg3DALtuvXrzNjxgx8fX3ZunUr06ZN4+eff2bevHnamFoplSpHLqiWB04kex4D1E/n+C7AV6ntMMYEAUGg5QNH7d+/n65du/L999/TtGlTZs+ejbe3NwDt2rXTZK6USpUjI/fUiruS6oHGtAcCgLdT2y8iISISICIBZcuWdTzKAiihgUadOnU4evQooaGhrFmzJjGxK6VUehwZuccAFZM9rwCcTHmQMaYRMAx4TEQuOye8gumbb76hW7du/PTTT3To0IF33nmHMmXKuDos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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(x, y, 'k-o', x, z, 'r--x')\n", "plt.legend(['sin(x)', 'cos(x)'], loc=0)\n", "plt.xlabel('x')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0cd62b9d-8a39-4f2a-ad98-e29d9db87029" } }, "source": [ "Let's breakdown the new components. First, consider `x, y, 'k-o'`. That means `y` is to be plotted against `x`, and the line to be used is black (the `k`), a solid line (the `-`), and has circle markers (the `o`). The second curve is defined by `x, z, 'r--x'`. Here, that plots `z` against `x` with a red (the `r`), dashed (the `--`) line with x's as markers (the `x`). A *legend* is provided indicating which line is which. The format of the legend always has a sequence of `str` labels for each line enclosed in `[]`'s (again, that's a `list` in Python, but just follow the syntax for now. By setting `loc=0`, we're putting the legend in the best possible place to avoid overlapping with the curves displayed. As a baseline rule, any plot produced should contain an `xlabel` and either a `ylabel` (if a single curve) or a `legend` (if multiple curves).\n", "\n", "> **Note**: All plots should include appropriate axis labels and legends.\n", "\n", "Some of the available colors, line styles, and markers available in `plt.plot` are summarized in the tables below.\n", "\n", "| symbol | color | \n", "|-------------|-----------|\n", "| `k` | black |\n", "| `b` | blue |\n", "| `r` | red |\n", "| `g` | green |\n", "| `c` | cyan |\n", "| `m` | magenta |\n", "\n", "| symbol | style | \n", "|-------------|-----------|\n", "| `-` | solid |\n", "| `--` | dash-dash |\n", "| `-.` | dash-dot |\n", "| `:` | dot-dot |\n", "\n", "| symbol | marker | \n", "|-------------|-----------|\n", "| `o` | circle |\n", "| `x` | x |\n", "| `^` | triangle pointed up |\n", "| `>` | triangle pointed right |\n", "| `s` | square |\n", "| `h` | hexagon |\n", "\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "416a720b-83df-41e6-9f12-81ffe971b63c" } }, "source": [ "In some applications, it can be very important to use a combination of colors, line styles, and markers that produce good looking and easily read graphics when viewed in color and in black and white formats. \n", "\n", "> **Note**: Choose good colors, line styles, and markers to ensure excellent contrast in all media." ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "584b914f-dd40-44a4-9854-d5159d80bb4b" } }, "source": [ "## Data Input and Output via NumPy" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "e1305ca8-2eb1-403d-a85f-8cf030493d46" } }, "source": [ "For many problems, the data we need to process lives in a file outside our Python code. There are a variety of ways to load data, but NumPy provides an easy way to load data that is in a relatively simple format. Consider a text file that has the following data:\n", "\n", "```\n", "time (s) vel (m/s) acc (m/s**2)\n", "0.00000000 1.00000000 0.00000000\n", "0.22222222 1.24884887 0.01097394\n", "0.44444444 1.55962350 0.08779150\n", "0.66666667 1.94773404 0.29629630\n", "0.88888889 2.43242545 0.70233196\n", "1.11111111 3.03773178 1.37174211\n", "1.33333333 3.79366789 2.37037037\n", "1.55555556 4.73771786 3.76406036\n", "1.77777778 5.91669359 5.61865569\n", "2.00000000 7.38905610 8.00000000\n", "```\n", "\n", "The structure is simple: three columns separated by white space. The first row contains information about what the data represent. Here, the columns correspond to times at which the velocity and acceleration of some object are given. \n", "\n", "### Loading Text Files\n", "\n", "Go ahead and save this text in a file. Mine is called `data.txt`. To load this file, we'll use `np.loadtxt`. The basic use of this function is just `np.loadtxt(filename)`, where `filename` is a `str` that contains the name of the file. Here, we need just a bit more. In particular, we need tell NumPy to skip the very first row since it contains regular text and not the numbers of interest. Here's one way to read in that text: " ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "nbpresent": { "id": "4a4e2c90-015a-486b-a51f-0a85e604f551" } }, "outputs": [ { "data": { "text/plain": [ "array([[0. , 1. , 0. ],\n", " [0.22222222, 1.24884887, 0.01097394],\n", " [0.44444444, 1.5596235 , 0.0877915 ],\n", " [0.66666667, 1.94773404, 0.2962963 ],\n", " [0.88888889, 2.43242545, 0.70233196],\n", " [1.11111111, 3.03773178, 1.37174211],\n", " [1.33333333, 3.79366789, 2.37037037],\n", " [1.55555556, 4.73771786, 3.76406036],\n", " [1.77777778, 5.91669359, 5.61865569],\n", " [2. , 7.3890561 , 8. ]])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = np.loadtxt('data.txt', skiprows=1)\n", "data" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "37fdd2e9-eda3-4855-ab20-8fa44b88d40c" } }, "source": [ "We have the data stored in the variable `data`. The type looks like an `ndarray`, but the structure is more like a matrix, i.e., a two-dimensional array---and it is! We can try out the `shape` attribute again:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "nbpresent": { "id": "be8d3e6c-7489-4e88-9305-15b7b2ce3ae8" } }, "outputs": [ { "data": { "text/plain": [ "(10, 3)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.shape" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "5230cff0-8cd6-448c-83aa-03cd57a79981" } }, "source": [ "That makes sense: we had 10 times at which the velocity and acceleration were provided. 10 rows, and 3 columns. We'll see next time how to access entire rows and columns of multidimensional arrays, but there is a better way to load in this data directly into three meaningful variables `t`, `v`, and `a`. " ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "nbpresent": { "id": "cf9e7c63-9075-4bed-be5b-660713a9b073" } }, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.22222222, 0.44444444, 0.66666667, 0.88888889,\n", " 1.11111111, 1.33333333, 1.55555556, 1.77777778, 2. ])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t, v, a = np.loadtxt('data.txt', skiprows=1, unpack=True)\n", "t" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "303db569-7531-4fe6-9116-bdfa7fb7fda0" } }, "source": [ "Now, we've got the times, velocities, and accelerations as three, separate, one-dimensional arrays. With NumPy, loading this sort of data is easy and recommended.\n", "\n", "> **Note**: If data is numerical and stored in a simple, collimated format, use `np.loadtxt`\n", "\n", "Like many functions in NumPy and other modules, `np.loadtxt` accepts quite a large number of optional arguments. You need to use `help` or the online documentation to learn more (and, of course, you'll get to explore these in the exercises.)" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "ac5bf565-0e63-4090-af12-78ec1d3dabab" } }, "source": [ "### Saving Text Files\n", "\n", "Saving data is just as easy as loading. The function of interest is `np.savetxt`, and it requires some data and a file name. One way we could save our `t`, `v`, and `a` arrays is via" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "np.savetxt('output_1.txt', [t, v, a])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Go and check `output_1.txt`. The data is there, for sure, but it's not quite the same format that we started with. Instead, `t`, `v`, and `a` were written out in their own row. That's fine, but often, we want to spit out the data in pretty much the same way we'd like it to be read into our programs. \n", "\n", "One issue is that NumPy treats `[t, v, a]` like an array with a shape of `(3, 10)`, which is exactly how it's saved to file. Such two-dimensional arrays are basically *matrices*, and if we want the 3 and 10 reverse, we need the *transpose*. Here, we can first produce a 2-D array explicitly from `[t, v, a]` by using the `np.array` function, i.e., " ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0. , 0.22222222, 0.44444444, 0.66666667, 0.88888889,\n", " 1.11111111, 1.33333333, 1.55555556, 1.77777778, 2. ],\n", " [1. , 1.24884887, 1.5596235 , 1.94773404, 2.43242545,\n", " 3.03773178, 3.79366789, 4.73771786, 5.91669359, 7.3890561 ],\n", " [0. , 0.01097394, 0.0877915 , 0.2962963 , 0.70233196,\n", " 1.37174211, 2.37037037, 3.76406036, 5.61865569, 8. ]])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = np.array([t, v, a])\n", "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then, we need its transpose, i.e.," ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0. , 1. , 0. ],\n", " [0.22222222, 1.24884887, 0.01097394],\n", " [0.44444444, 1.5596235 , 0.0877915 ],\n", " [0.66666667, 1.94773404, 0.2962963 ],\n", " [0.88888889, 2.43242545, 0.70233196],\n", " [1.11111111, 3.03773178, 1.37174211],\n", " [1.33333333, 3.79366789, 2.37037037],\n", " [1.55555556, 4.73771786, 3.76406036],\n", " [1.77777778, 5.91669359, 5.61865569],\n", " [2. , 7.3890561 , 8. ]])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That appears to be what we want in our output (if we want it to look like our original input). The only missing ingredient is the first row that indicates what each column contains. Such information can be included by using the `header` argument. By default, `#` is appended to the beginning, since `np.loadtxt` actually ignores lines that start with `#` (or some other user-specified comment symbol). Here, we can avoid the comment symbol in our output by using setting the `comment` argument to zero.\n", "\n", "Here it all is together:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "np.savetxt('output_2.txt', data.T, header='time (s) vel (m/s) acc (m/s**2)', comments='')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### An Aside: String Formatting\n", "\n", "The output is pretty darn close, but the numbers are longer (and they were the first try, too). Behind the scenes, `float` values are stored with about 15 digits of useful information. When we read in the values from `data.txt`, they were defined only with 8 digits after the decimal point. You can see that `output_2.txt` has pretty much the same values, but there are some strange digits out beyond that eight digit. We can limit the output to only 8 digits by using a string format. Consider the following:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.1\n", "0.1234\n", "0.1234000000000000\n", "1.234e-01\n" ] } ], "source": [ "print(\"%.1f\" % 0.1234)\n", "print(\"%.4f\" % 0.1234)\n", "print(\"%.16f\" % 0.1234)\n", "print(\"%.3e\" % 0.1234)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, the basic syntact is a `str` format, which contains a `%` followed by, e.g., `.4f`. That means to format the number in normal decimal notation (and not, e.g., scientific) with 4 digits after the decimal point. The last example used an `e`, which indicates scientific notation (with, here, three digits after the decimal point and before the `e`). String formatting can be very powerful (and complex). We'll turn again to the topic again later on, but this gives you a taste!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Saving Text Files: Revisited\n", "\n", "Back to our example. Armed with a bit of formatting, here's the final solution for getting output identical to our original input:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "np.savetxt('output_3.txt', data.T, header='time (s) vel (m/s) acc (m/s**2)', comments='', fmt='%.8f')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inspection of `output_3.txt` confirms it's exactly like our original `data.txt`. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Further Reading\n", "\n", "Make sure to explore in depth the `help` output of all the functions explored in this lesson. Many times, not all function arguments need to be used, but it's very helpful to know that they exist and what they can help you to do." ] } ], "metadata": { "anaconda-cloud": {}, "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.6.8" }, "nbpresent": { "slides": { "02f8ee21-16f9-4da2-b3f4-e7a367648740": { "id": "02f8ee21-16f9-4da2-b3f4-e7a367648740", "prev": "6c4fe21b-4b7e-494e-bccd-fb2cdaf20e16", "regions": { "3f3d4bcf-b012-4763-a226-5106446168eb": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ca145966-b9d7-4317-816e-c7fe6ff2e983", "part": "whole" }, "id": "3f3d4bcf-b012-4763-a226-5106446168eb" } } }, "061ab4a8-4168-45f7-835c-9cdf9cd5529c": { "id": "061ab4a8-4168-45f7-835c-9cdf9cd5529c", "prev": "81519902-7c6b-4136-9add-490b4a993bcd", "regions": { "39b5c3b9-f03e-4468-84ef-6f134408e9b0": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "8870b445-238d-4dec-b25f-d4ebeb5ddb02", "part": "whole" }, "id": "39b5c3b9-f03e-4468-84ef-6f134408e9b0" } } }, "08ff05f8-e5b4-4e69-9c99-08544ae8b105": { "id": "08ff05f8-e5b4-4e69-9c99-08544ae8b105", "prev": "2a0bd635-6490-40c8-90a4-b9e716dc1413", "regions": { "4cb950f8-b864-4992-af20-9d75d778d3f9": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "cd03f52d-725f-4b62-bc32-78a3a37de256", "part": "whole" }, "id": "4cb950f8-b864-4992-af20-9d75d778d3f9" } } }, "0ef8e784-08e5-4870-ad8d-b657ac25d42d": { "id": "0ef8e784-08e5-4870-ad8d-b657ac25d42d", "prev": "365d9e52-4a9b-4aef-80f5-4fb688697357", "regions": { "2be91d34-033d-4fec-bb2a-6b26c85a8da5": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "73cffb9a-90ee-4f92-a71f-858759133eb0", "part": "whole" }, "id": "2be91d34-033d-4fec-bb2a-6b26c85a8da5" } } }, "112cf242-7afd-41bd-88d3-526115f59615": { "id": "112cf242-7afd-41bd-88d3-526115f59615", "prev": "cae17098-bb79-40f0-a1a2-11ef8263af53", "regions": { "fa42efab-7c84-407a-ba91-9b90a68a6e22": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "be8d3e6c-7489-4e88-9305-15b7b2ce3ae8", "part": "whole" }, "id": "fa42efab-7c84-407a-ba91-9b90a68a6e22" } } }, "1febbbcf-84fb-4836-8a4b-b403f3206c57": { "id": "1febbbcf-84fb-4836-8a4b-b403f3206c57", "prev": "6d3a12e3-b722-4f66-8a4f-5e89d0f2ecea", "regions": { "4b2b2012-01fe-4f80-8a77-2db1dff79f95": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "983c773e-9265-4dfc-b9c0-de5d867a5a06", "part": "whole" }, "id": "4b2b2012-01fe-4f80-8a77-2db1dff79f95" } } }, "2104c032-dfcc-41f3-a0ff-5ad0d9d57b44": { "id": "2104c032-dfcc-41f3-a0ff-5ad0d9d57b44", "prev": "0ef8e784-08e5-4870-ad8d-b657ac25d42d", "regions": { "fe6c189f-dccc-434d-96dd-9382a57c8913": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "d83ea8c1-3fd3-4f42-ac60-2f3334dc5d1a", "part": "whole" }, "id": "fe6c189f-dccc-434d-96dd-9382a57c8913" } } }, "2901d73c-d5bd-4fa9-bda0-05cbb2441541": { "id": "2901d73c-d5bd-4fa9-bda0-05cbb2441541", "prev": "847612dd-a57d-4d3b-adf6-2638ff009abc", "regions": { "23ca1667-83be-41a7-9579-e864c91fc9ce": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "2bf16a59-f0e4-4b84-a224-3499f4be6ca2", "part": "whole" }, "id": "23ca1667-83be-41a7-9579-e864c91fc9ce" } } }, "2a0bd635-6490-40c8-90a4-b9e716dc1413": { "id": "2a0bd635-6490-40c8-90a4-b9e716dc1413", "prev": "3a6d0a22-5e23-46aa-9982-8f19c6036db5", "regions": { "1a78eeef-9bd0-46a5-89dc-9d4727c5de2e": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "7cd39b4b-3858-4138-a9e7-76a6d3b07a13", "part": "whole" }, "id": "1a78eeef-9bd0-46a5-89dc-9d4727c5de2e" } } }, "2dc8d019-4770-42b9-9af9-f1ec17601ad2": { "id": "2dc8d019-4770-42b9-9af9-f1ec17601ad2", "prev": "e7395586-419e-4aee-abab-cddb4b3499bf", "regions": { "7b6043e5-2680-4ca0-8ab4-211315fecc50": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "19e6a46b-1ce8-4ed6-98a3-3e1dc012d1c0", "part": "whole" }, "id": "7b6043e5-2680-4ca0-8ab4-211315fecc50" } } }, "365d9e52-4a9b-4aef-80f5-4fb688697357": { "id": "365d9e52-4a9b-4aef-80f5-4fb688697357", "prev": "66db5ec4-025e-4748-b391-476452f4620a", "regions": { "fa24282f-dc7a-4bbd-81f4-31e5e9a8c676": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "32fff475-8295-4b72-b660-d4dad320bb25", "part": "whole" }, "id": "fa24282f-dc7a-4bbd-81f4-31e5e9a8c676" } } }, "37ca5021-4f09-43c5-ab3d-52741ea34ce2": { "id": "37ca5021-4f09-43c5-ab3d-52741ea34ce2", "prev": "7a825839-decf-4944-89f7-4e271ec627f3", "regions": { "e71a87fc-81bd-4a0d-9b0e-61d5c89a7394": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "47fb4b50-a33d-4d01-b72a-608226dcd179", "part": "whole" }, "id": "e71a87fc-81bd-4a0d-9b0e-61d5c89a7394" } } }, "3a1dc4b8-18ff-4563-9e6b-e7a045b18820": { "id": "3a1dc4b8-18ff-4563-9e6b-e7a045b18820", "prev": "2104c032-dfcc-41f3-a0ff-5ad0d9d57b44", "regions": { "aace180a-5102-48e3-a4cc-cedc8eea7f8f": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "f4c615a0-5c0a-4537-8886-ff0d1f2df3cc", "part": "whole" }, "id": "aace180a-5102-48e3-a4cc-cedc8eea7f8f" } } }, "3a61de2e-0b3f-4e76-b4f5-37d9b4548b28": { "id": "3a61de2e-0b3f-4e76-b4f5-37d9b4548b28", "prev": "de42cd45-29ec-4653-965a-f91547a0ca18", "regions": { "18ef0b4f-686a-4116-abd6-597731094d33": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ef9c28a3-5bdb-46b6-a78b-431fd1d30805", "part": "whole" }, "id": "18ef0b4f-686a-4116-abd6-597731094d33" } } }, "3a6d0a22-5e23-46aa-9982-8f19c6036db5": { "id": "3a6d0a22-5e23-46aa-9982-8f19c6036db5", "prev": "061ab4a8-4168-45f7-835c-9cdf9cd5529c", "regions": { "83e2f2ac-98cb-42b7-857c-7e771a32868f": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "0a95b785-c644-42b0-bd2f-2a990b8559c0", "part": "whole" }, "id": "83e2f2ac-98cb-42b7-857c-7e771a32868f" } } }, "3fdca1da-89b8-4d9a-b1b1-f0a59e8e6270": { "id": "3fdca1da-89b8-4d9a-b1b1-f0a59e8e6270", "prev": "4260bf4c-2c83-4ff5-9ec7-334ad91f21df", "regions": { "320ea712-f0ba-4dd6-8915-12d7983331ef": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "2a53b60e-b4f0-4967-817b-dc15bba9bf22", "part": "whole" }, "id": "320ea712-f0ba-4dd6-8915-12d7983331ef" } } }, "420d5081-c5ac-4503-bee9-c297fdab812e": { "id": "420d5081-c5ac-4503-bee9-c297fdab812e", "prev": "c09da137-d9b0-4642-a8e0-d5ce3f493482", "regions": { "20b73ce3-06a3-4a63-b8d8-8648605ccb28": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "047813b2-f745-4719-9494-24c0cd9bffe6", "part": "whole" }, "id": "20b73ce3-06a3-4a63-b8d8-8648605ccb28" } } }, "4260bf4c-2c83-4ff5-9ec7-334ad91f21df": { "id": "4260bf4c-2c83-4ff5-9ec7-334ad91f21df", "prev": "08ff05f8-e5b4-4e69-9c99-08544ae8b105", "regions": { "688b3214-2a41-4b37-b702-d85503dd154f": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "8a35d33a-bfd6-456a-bb3f-d3d9a15a37b0", "part": "whole" }, "id": "688b3214-2a41-4b37-b702-d85503dd154f" } } }, "4ed5808b-dddd-415b-9a33-00f9abe32b1c": { "id": "4ed5808b-dddd-415b-9a33-00f9abe32b1c", "prev": "9929ca97-03e8-45df-b086-28a2f0d88ea9", "regions": { "32d8c677-3315-42e3-84fe-38a211f0e554": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "5b5b877c-7b4c-4adf-852c-ea73ffd6a3be", "part": "whole" }, "id": "32d8c677-3315-42e3-84fe-38a211f0e554" } } }, "51c3906d-0215-4509-b2e0-909c2d98d101": { "id": "51c3906d-0215-4509-b2e0-909c2d98d101", "prev": "88d92870-83da-46cb-ade3-a181b3271eb5", "regions": { "64010f48-94f7-4184-9907-a5ae2be72d86": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ac5bf565-0e63-4090-af12-78ec1d3dabab", "part": "whole" }, "id": "64010f48-94f7-4184-9907-a5ae2be72d86" } } }, "5d8faeeb-e6dd-4e91-aae4-b0d4822e502f": { "id": "5d8faeeb-e6dd-4e91-aae4-b0d4822e502f", "prev": "cb83f14f-1cad-4aff-af5b-8ca8a05a43ae", "regions": { "89cd93aa-d67b-44a5-a122-1c595dccb2ac": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "584b914f-dd40-44a4-9854-d5159d80bb4b", "part": "whole" }, "id": "89cd93aa-d67b-44a5-a122-1c595dccb2ac" } } }, "5f21d086-3beb-4248-8205-b3f7fcde3fa6": { "id": "5f21d086-3beb-4248-8205-b3f7fcde3fa6", "prev": "9768df67-bbe9-4d1e-8345-34a56edf2e1b", "regions": { "5de83f14-e6f0-4e86-9989-f11a07d20edf": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "7d5aea0d-8552-4408-b402-54db871102f3", "part": "whole" }, "id": "5de83f14-e6f0-4e86-9989-f11a07d20edf" } } }, "638384ce-c0f4-4318-aa6c-389ae749354d": { "id": "638384ce-c0f4-4318-aa6c-389ae749354d", "prev": "3fdca1da-89b8-4d9a-b1b1-f0a59e8e6270", "regions": { "debf23c1-29d9-449f-a398-81fec4e962bf": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "bca634f7-6639-407c-85b2-ba0d3ba2ad9c", "part": "whole" }, "id": "debf23c1-29d9-449f-a398-81fec4e962bf" } } }, "66db5ec4-025e-4748-b391-476452f4620a": { "id": "66db5ec4-025e-4748-b391-476452f4620a", "prev": "77c59f01-cdd0-4a3e-a39a-0cb2d9873a94", "regions": { "8d9e9fbb-29b1-45f8-87a4-59b906fe67f5": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "d1338d3b-74f3-45ae-b49c-e9bbc3d499c9", "part": "whole" }, "id": "8d9e9fbb-29b1-45f8-87a4-59b906fe67f5" } } }, "6c4fe21b-4b7e-494e-bccd-fb2cdaf20e16": { "id": "6c4fe21b-4b7e-494e-bccd-fb2cdaf20e16", "prev": "89163416-085d-4eec-be2f-f1995175d47c", "regions": { "9ec890c8-eb62-4ad1-97b3-ad724320cf66": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "2aea0c67-93d3-4332-84ad-d75fe0225a9d", "part": "whole" }, "id": "9ec890c8-eb62-4ad1-97b3-ad724320cf66" } } }, "6d3a12e3-b722-4f66-8a4f-5e89d0f2ecea": { "id": "6d3a12e3-b722-4f66-8a4f-5e89d0f2ecea", "prev": "b86fc250-a3b2-4312-b7b5-c5635a57cb38", "regions": { "9b61e9e0-46ee-4be5-a7ef-9e676735f9ae": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "b150c2ce-4268-4e3f-94ef-3f0dd7088b79", "part": "whole" }, "id": "9b61e9e0-46ee-4be5-a7ef-9e676735f9ae" } } }, "75606e09-a641-4ff0-bb50-079886942e34": { "id": "75606e09-a641-4ff0-bb50-079886942e34", "prev": "5d8faeeb-e6dd-4e91-aae4-b0d4822e502f", "regions": { "d2054855-599f-478f-84f2-522494aba357": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "e1305ca8-2eb1-403d-a85f-8cf030493d46", "part": "whole" }, "id": "d2054855-599f-478f-84f2-522494aba357" } } }, "768acc21-9af6-457a-ae4d-5018bdc3c36b": { "id": "768acc21-9af6-457a-ae4d-5018bdc3c36b", "prev": "b72623a4-5243-4b04-bb1c-8b1d3c472c93", "regions": { "0495e51d-9f07-493b-ab81-0058a83e0190": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "c734f840-7a1d-40c8-9df4-9f905d3e330f", "part": "whole" }, "id": "0495e51d-9f07-493b-ab81-0058a83e0190" } } }, "77c59f01-cdd0-4a3e-a39a-0cb2d9873a94": { "id": "77c59f01-cdd0-4a3e-a39a-0cb2d9873a94", "prev": "8bc952e1-cde2-4980-a397-a7abc57d5f29", "regions": { "fb692fe6-dc54-46fa-b57c-f3093058eb93": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "843efd91-8f2e-4abc-b7af-3deb9f003eb4", "part": "whole" }, "id": "fb692fe6-dc54-46fa-b57c-f3093058eb93" } } }, "77e407f2-e061-4110-9d1a-81a3caf6e410": { "id": "77e407f2-e061-4110-9d1a-81a3caf6e410", "prev": "4ed5808b-dddd-415b-9a33-00f9abe32b1c", "regions": { "150a6195-b35b-43a2-bab6-c795a9e9c1fd": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "0cd62b9d-8a39-4f2a-ad98-e29d9db87029", "part": "whole" }, "id": "150a6195-b35b-43a2-bab6-c795a9e9c1fd" } } }, "7a825839-decf-4944-89f7-4e271ec627f3": { "id": "7a825839-decf-4944-89f7-4e271ec627f3", "prev": "cb1ec09f-779a-476b-a948-f9806e4713cc", "regions": { "82a3c159-d35d-4af3-a595-a80c88833d34": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "298df42f-86a5-47ef-97f7-c9eb75a27ec3", "part": "whole" }, "id": "82a3c159-d35d-4af3-a595-a80c88833d34" } } }, "7bca4b8d-7213-4094-b5fb-825fe05bd98a": { "id": "7bca4b8d-7213-4094-b5fb-825fe05bd98a", "prev": "8c738d23-d5f5-4f58-8e9e-772a89dd2ff6", "regions": { "dd32b718-bc3f-4a91-a8d4-00fc6235b9ad": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "f68a00b1-2587-4c13-9aa4-b841d3f20185", "part": "whole" }, "id": "dd32b718-bc3f-4a91-a8d4-00fc6235b9ad" } } }, "80fc4044-455e-4254-bd15-f5f09ff906b1": { "id": "80fc4044-455e-4254-bd15-f5f09ff906b1", "prev": "bec94ea6-fe5c-4fc4-a3a9-ead674c3d92c", "regions": { "98cb1768-b3a6-4bd4-afd9-7a248f42832c": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "d944635a-8fcb-4dd8-9fd8-3d951df43601", "part": "whole" }, "id": "98cb1768-b3a6-4bd4-afd9-7a248f42832c" } } }, "81519902-7c6b-4136-9add-490b4a993bcd": { "id": "81519902-7c6b-4136-9add-490b4a993bcd", "prev": "7bca4b8d-7213-4094-b5fb-825fe05bd98a", "regions": { "4f308efa-04db-44c7-b371-0d7598ed9607": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "b120c52a-1966-46db-ab64-83a226ea74d3", "part": "whole" }, "id": "4f308efa-04db-44c7-b371-0d7598ed9607" } } }, "847612dd-a57d-4d3b-adf6-2638ff009abc": { "id": "847612dd-a57d-4d3b-adf6-2638ff009abc", "prev": "cf9799f2-1da9-478b-bd91-b8fcef910361", "regions": { "1a58c5a2-3add-4e42-ab32-e6c89e0e2453": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "c3ac8b3e-c8af-4d04-a74a-2f99222fec62", "part": "whole" }, "id": "1a58c5a2-3add-4e42-ab32-e6c89e0e2453" } } }, "864608a2-ce94-4631-b101-f9e669dc1066": { "id": "864608a2-ce94-4631-b101-f9e669dc1066", "prev": "fb2b55b5-1002-4175-9dca-ba3dbf207b1c", "regions": { "1f8fe6de-286a-428b-814a-92fbf4490269": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ef2abeac-8f8c-48c0-a3ea-c6e93409e5da", "part": "whole" }, "id": "1f8fe6de-286a-428b-814a-92fbf4490269" } } }, "88d92870-83da-46cb-ade3-a181b3271eb5": { "id": "88d92870-83da-46cb-ade3-a181b3271eb5", "prev": "bd9252b4-54cb-43c3-bc01-4453495bbbf9", "regions": { "354e50ae-c7e4-4b40-9564-f5f13a0ba150": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "303db569-7531-4fe6-9116-bdfa7fb7fda0", "part": "whole" }, "id": "354e50ae-c7e4-4b40-9564-f5f13a0ba150" } } }, "89163416-085d-4eec-be2f-f1995175d47c": { "id": "89163416-085d-4eec-be2f-f1995175d47c", "prev": "b9b07209-69cf-4b3e-85b9-fe95664d790c", "regions": { "d64676c3-bb3f-4d2d-930e-b1d5e79d643e": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "a9a4543c-39d7-4f53-aefd-d9e1548f114c", "part": "whole" }, "id": "d64676c3-bb3f-4d2d-930e-b1d5e79d643e" } } }, "8bc952e1-cde2-4980-a397-a7abc57d5f29": { "id": "8bc952e1-cde2-4980-a397-a7abc57d5f29", "prev": "420d5081-c5ac-4503-bee9-c297fdab812e", "regions": { "706d3d5b-8015-481d-98df-27ccf7fa4735": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "34091a11-965e-410c-8301-7a1478106486", "part": "whole" }, "id": "706d3d5b-8015-481d-98df-27ccf7fa4735" } } }, "8bdb0a8e-2436-4662-be67-3828f99ce1db": { "id": "8bdb0a8e-2436-4662-be67-3828f99ce1db", "prev": "75606e09-a641-4ff0-bb50-079886942e34", "regions": { "b90fe601-6ee9-49ff-a4ac-744dd8e9419c": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "4a4e2c90-015a-486b-a51f-0a85e604f551", "part": "whole" }, "id": "b90fe601-6ee9-49ff-a4ac-744dd8e9419c" } } }, "8c738d23-d5f5-4f58-8e9e-772a89dd2ff6": { "id": "8c738d23-d5f5-4f58-8e9e-772a89dd2ff6", "prev": "02f8ee21-16f9-4da2-b3f4-e7a367648740", "regions": { "55fb7253-cbd2-4936-a538-60950ec488ee": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "9dba623e-eeae-4fba-9819-15429ed53f9e", "part": "whole" }, "id": "55fb7253-cbd2-4936-a538-60950ec488ee" } } }, "8d21ccf1-00ef-49ae-a4c8-d8160b4609f0": { "id": "8d21ccf1-00ef-49ae-a4c8-d8160b4609f0", "prev": "2901d73c-d5bd-4fa9-bda0-05cbb2441541", "regions": { "c20e3841-8fb1-44c4-b1d5-a85e6b01fcd0": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "2910ae3c-511b-4e00-aebb-072a601ee9c8", "part": "whole" }, "id": "c20e3841-8fb1-44c4-b1d5-a85e6b01fcd0" } } }, "95ed4754-630a-46ff-8a5a-a89eac543eec": { "id": "95ed4754-630a-46ff-8a5a-a89eac543eec", "prev": "cf8ad9fd-fc71-4ce3-b710-921d9f8da51a", "regions": { "400879d3-af5c-481b-a0d4-0f62b97f0162": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "fbbc7a45-be27-4130-a861-a31380127143", "part": "whole" }, "id": "400879d3-af5c-481b-a0d4-0f62b97f0162" } } }, "9768df67-bbe9-4d1e-8345-34a56edf2e1b": { "id": "9768df67-bbe9-4d1e-8345-34a56edf2e1b", "prev": "d460e553-45e2-41ae-b4b8-b2a4db4f85da", "regions": { "9be25018-2817-4877-b476-3901ffdffc37": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "c20cb43d-37ea-4f1a-bca2-4f7a4f2b8242", "part": "whole" }, "id": "9be25018-2817-4877-b476-3901ffdffc37" } } }, "9929ca97-03e8-45df-b086-28a2f0d88ea9": { "id": "9929ca97-03e8-45df-b086-28a2f0d88ea9", "prev": "ee7c1264-60fc-4492-a86b-0524e1b5a8fe", "regions": { "1c574c76-6c4d-4450-8d4b-f2c63eb81668": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "d63733fb-11ed-4dd1-8f60-c2a5fc3903c1", "part": "whole" }, "id": "1c574c76-6c4d-4450-8d4b-f2c63eb81668" } } }, "a9560553-9684-430c-9e5d-8e2b0907d236": { "id": "a9560553-9684-430c-9e5d-8e2b0907d236", "prev": "eba4db38-efd0-4dd8-bbbb-86d9ec8fd916", "regions": { "00300653-7a56-475f-9cbe-ffbeddfebf6e": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "b749b600-3e7f-4f3e-b82e-2d90dda169d6", "part": "whole" }, "id": "00300653-7a56-475f-9cbe-ffbeddfebf6e" } } }, "b72623a4-5243-4b04-bb1c-8b1d3c472c93": { "id": "b72623a4-5243-4b04-bb1c-8b1d3c472c93", "prev": "5f21d086-3beb-4248-8205-b3f7fcde3fa6", "regions": { "d4710784-c777-414d-a636-74882aaeb390": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "0846eae5-9037-436a-80c4-f146ea24c6d8", "part": "whole" }, "id": "d4710784-c777-414d-a636-74882aaeb390" } } }, "b86fc250-a3b2-4312-b7b5-c5635a57cb38": { "id": "b86fc250-a3b2-4312-b7b5-c5635a57cb38", "prev": "638384ce-c0f4-4318-aa6c-389ae749354d", "regions": { "6db909bc-f8ba-4312-a4c8-700803a44644": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "15c2afe2-64fb-470e-aadd-84e22f7ccb72", "part": "whole" }, "id": "6db909bc-f8ba-4312-a4c8-700803a44644" } } }, "b9b07209-69cf-4b3e-85b9-fe95664d790c": { "id": "b9b07209-69cf-4b3e-85b9-fe95664d790c", "prev": "da4c91b4-846f-45a2-83e6-9eaa964d9a9f", "regions": { "8cdb3abf-9ab5-4854-a070-b6f9ec8aeae4": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "16301cce-e2f8-4df6-8145-dd4d2205aab0", "part": "whole" }, "id": "8cdb3abf-9ab5-4854-a070-b6f9ec8aeae4" } } }, "bcd90869-3de3-432a-949a-af68deb1297a": { "id": "bcd90869-3de3-432a-949a-af68deb1297a", "prev": "80fc4044-455e-4254-bd15-f5f09ff906b1", "regions": { "4c817142-6cac-4d62-befb-972bc91888dc": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "c7d6c030-605a-4284-a69a-fb09dc69061e", "part": "whole" }, "id": "4c817142-6cac-4d62-befb-972bc91888dc" } } }, "bd9252b4-54cb-43c3-bc01-4453495bbbf9": { "id": "bd9252b4-54cb-43c3-bc01-4453495bbbf9", "prev": "e97776f8-4931-453f-9156-6ebc634eba42", "regions": { "b37edac2-8094-42e1-ab64-ba63a61c9f3b": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "cf9e7c63-9075-4bed-be5b-660713a9b073", "part": "whole" }, "id": "b37edac2-8094-42e1-ab64-ba63a61c9f3b" } } }, "bec94ea6-fe5c-4fc4-a3a9-ead674c3d92c": { "id": "bec94ea6-fe5c-4fc4-a3a9-ead674c3d92c", "prev": null, "regions": { "2df80672-1114-41a5-90ff-575e3330c1a3": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "2e399b29-d227-4a3a-9667-e7a38677ed1c", "part": "whole" }, "id": "2df80672-1114-41a5-90ff-575e3330c1a3" } } }, "c09da137-d9b0-4642-a8e0-d5ce3f493482": { "id": "c09da137-d9b0-4642-a8e0-d5ce3f493482", "prev": "3a61de2e-0b3f-4e76-b4f5-37d9b4548b28", "regions": { "1fc3cac4-a1d4-45dc-a612-5b677400d87a": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "0d77e572-b4c3-4e48-8097-adcef183ee44", "part": "whole" }, "id": "1fc3cac4-a1d4-45dc-a612-5b677400d87a" } } }, "c0ba2104-6bdf-4b0b-a013-5199e54656f7": { "id": "c0ba2104-6bdf-4b0b-a013-5199e54656f7", "prev": "2dc8d019-4770-42b9-9af9-f1ec17601ad2", "regions": { "b7aa5e83-add0-4103-87c5-84a19d42edff": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ccdc1aaf-d5fd-45d2-ace2-befe2ddcbba3", "part": "whole" }, "id": "b7aa5e83-add0-4103-87c5-84a19d42edff" } } }, "c9cbbbac-2a57-45d2-a14e-54d1a47957f9": { "id": "c9cbbbac-2a57-45d2-a14e-54d1a47957f9", "prev": "c0ba2104-6bdf-4b0b-a013-5199e54656f7", "regions": { "085fe725-457d-436e-881a-85d4e70270b0": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "591b8b01-66ce-4003-a2dc-6aad17308a73", "part": "whole" }, "id": "085fe725-457d-436e-881a-85d4e70270b0" } } }, "cae17098-bb79-40f0-a1a2-11ef8263af53": { "id": "cae17098-bb79-40f0-a1a2-11ef8263af53", "prev": "8bdb0a8e-2436-4662-be67-3828f99ce1db", "regions": { "b93c411d-614d-4099-91a3-39464a2b5a7e": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "37fdd2e9-eda3-4855-ab20-8fa44b88d40c", "part": "whole" }, "id": "b93c411d-614d-4099-91a3-39464a2b5a7e" } } }, "cb1ec09f-779a-476b-a948-f9806e4713cc": { "id": "cb1ec09f-779a-476b-a948-f9806e4713cc", "prev": "864608a2-ce94-4631-b101-f9e669dc1066", "regions": { "5524a950-ada3-4373-8a1a-d94a2b15ff79": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "c1d6e507-2c59-477b-9000-d4458050888b", "part": "whole" }, "id": "5524a950-ada3-4373-8a1a-d94a2b15ff79" } } }, "cb83f14f-1cad-4aff-af5b-8ca8a05a43ae": { "id": "cb83f14f-1cad-4aff-af5b-8ca8a05a43ae", "prev": "77e407f2-e061-4110-9d1a-81a3caf6e410", "regions": { "0a373235-f082-4fbd-90cb-c37c2c428500": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "416a720b-83df-41e6-9f12-81ffe971b63c", "part": "whole" }, "id": "0a373235-f082-4fbd-90cb-c37c2c428500" } } }, "cf8ad9fd-fc71-4ce3-b710-921d9f8da51a": { "id": "cf8ad9fd-fc71-4ce3-b710-921d9f8da51a", "prev": "c9cbbbac-2a57-45d2-a14e-54d1a47957f9", "regions": { "5dac95ed-5730-44e5-b184-32ae7bfb4e04": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "591a3dac-2afc-4055-a043-a75b15a15e84", "part": "whole" }, "id": "5dac95ed-5730-44e5-b184-32ae7bfb4e04" } } }, "cf9799f2-1da9-478b-bd91-b8fcef910361": { "id": "cf9799f2-1da9-478b-bd91-b8fcef910361", "prev": "a9560553-9684-430c-9e5d-8e2b0907d236", "regions": { "765bc95a-1ef5-40e0-92b7-919a2e0ab9a0": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "f353b376-e74b-49d1-89d4-155658283c9d", "part": "whole" }, "id": "765bc95a-1ef5-40e0-92b7-919a2e0ab9a0" } } }, "d460e553-45e2-41ae-b4b8-b2a4db4f85da": { "id": "d460e553-45e2-41ae-b4b8-b2a4db4f85da", "prev": "1febbbcf-84fb-4836-8a4b-b403f3206c57", "regions": { "857d667c-0cb2-4358-9402-d62a76ce2de7": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "591b707d-dd57-4460-a76a-9fb1a80d7a76", "part": "whole" }, "id": "857d667c-0cb2-4358-9402-d62a76ce2de7" } } }, "da4c91b4-846f-45a2-83e6-9eaa964d9a9f": { "id": "da4c91b4-846f-45a2-83e6-9eaa964d9a9f", "prev": "3a1dc4b8-18ff-4563-9e6b-e7a045b18820", "regions": { "7d778c16-e2b0-4d2e-962b-81c442040be2": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "cee25d6f-74f7-47b4-adfa-7181b1fdf9cb", "part": "whole" }, "id": "7d778c16-e2b0-4d2e-962b-81c442040be2" } } }, "de42cd45-29ec-4653-965a-f91547a0ca18": { "id": "de42cd45-29ec-4653-965a-f91547a0ca18", "prev": "8d21ccf1-00ef-49ae-a4c8-d8160b4609f0", "regions": { "230025f5-2ca8-4b56-99a4-fccf4c94f6b4": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "5d34201c-814d-4eb0-a6df-2b3d8ab41684", "part": "whole" }, "id": "230025f5-2ca8-4b56-99a4-fccf4c94f6b4" } } }, "e7395586-419e-4aee-abab-cddb4b3499bf": { "id": "e7395586-419e-4aee-abab-cddb4b3499bf", "prev": "768acc21-9af6-457a-ae4d-5018bdc3c36b", "regions": { "cb3f2ed1-5d29-4602-a5f6-4980247a89f3": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "c0f58cf7-3066-489d-a673-751126c4ea26", "part": "whole" }, "id": "cb3f2ed1-5d29-4602-a5f6-4980247a89f3" } } }, "e97776f8-4931-453f-9156-6ebc634eba42": { "id": "e97776f8-4931-453f-9156-6ebc634eba42", "prev": "112cf242-7afd-41bd-88d3-526115f59615", "regions": { "9a20dd2a-231a-4fa1-9442-e1b377951195": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "5230cff0-8cd6-448c-83aa-03cd57a79981", "part": "whole" }, "id": "9a20dd2a-231a-4fa1-9442-e1b377951195" } } }, "eba4db38-efd0-4dd8-bbbb-86d9ec8fd916": { "id": "eba4db38-efd0-4dd8-bbbb-86d9ec8fd916", "prev": "bcd90869-3de3-432a-949a-af68deb1297a", "regions": { "c03be5ef-20dc-4859-9189-7b3a5e5ee295": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "40df7c21-ec21-4697-a6ce-56b1c8c0d2dd", "part": "whole" }, "id": "c03be5ef-20dc-4859-9189-7b3a5e5ee295" } } }, "ee7c1264-60fc-4492-a86b-0524e1b5a8fe": { "id": "ee7c1264-60fc-4492-a86b-0524e1b5a8fe", "prev": "37ca5021-4f09-43c5-ab3d-52741ea34ce2", "regions": { "949e2d04-64c8-46fc-ac2a-0defc0bee65e": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "8f02aa22-6c80-4f40-b224-1b3bc3855898", "part": "whole" }, "id": "949e2d04-64c8-46fc-ac2a-0defc0bee65e" } } }, "fb2b55b5-1002-4175-9dca-ba3dbf207b1c": { "id": "fb2b55b5-1002-4175-9dca-ba3dbf207b1c", "prev": "95ed4754-630a-46ff-8a5a-a89eac543eec", "regions": { "dbf25ba1-fa09-43a5-8a9b-b14499c1a81a": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "5f5a272b-a97d-411d-ae62-12c637a40f6e", "part": "whole" }, "id": "dbf25ba1-fa09-43a5-8a9b-b14499c1a81a" } } } }, "themes": {} } }, "nbformat": 4, "nbformat_minor": 2 }