From 0cdac2f683bcda45c306185e5434c0b411be234d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Geron?= Date: Tue, 23 Nov 2021 17:51:16 +1300 Subject: [PATCH] %matplotlib inline not needed anymore, use PIL.Image.open instead of imread --- tools_matplotlib.ipynb | 260 +++++++++++++++++++++++++---------------- 1 file changed, 157 insertions(+), 103 deletions(-) diff --git a/tools_matplotlib.ipynb b/tools_matplotlib.ipynb index 43b2b85..65f4f56 100644 --- a/tools_matplotlib.ipynb +++ b/tools_matplotlib.ipynb @@ -15,10 +15,10 @@ "source": [ "\n", " \n", " \n", "
\n", - " \"Open\n", + " \"Open\n", " \n", - " \n", + " \n", "
" ] @@ -60,7 +60,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Matplotlib can output graphs using various backend graphics libraries, such as Tk, wxPython, etc. When running python using the command line, the graphs are typically shown in a separate window. In a Jupyter notebook, we can simply output the graphs within the notebook itself by running the `%matplotlib inline` magic command." + "Now let's plot our first graph! :)" ] }, { @@ -68,25 +68,9 @@ "execution_count": 2, "metadata": {}, "outputs": [], - "source": [ - "%matplotlib inline\n", - "# matplotlib.use(\"TKAgg\") # use this instead in your program if you want to use Tk as your graphics backend." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's plot our first graph! :)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", + "\n", "plt.plot([1, 2, 4, 9, 5, 3])\n", "plt.show()" ] @@ -95,15 +79,30 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Yep, it's as simple as calling the `plot` function with some data, and then calling the `show` function!\n", + "Yep, it's as simple as calling the `plot` function with some data, and then calling the `show` function!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note**:\n", "\n", + "> Matplotlib can output graphs using various backend graphics libraries, such as Tk, wxPython, etc. When running Python using the command line, you may want to specify which backend to use right after importing matplotlib and before plotting anything. For example, to use the Tk backend, run `matplotlib.use(\"TKAgg\")`.\n", + "> However, in a Jupyter notebook, things are easier: importing `import matplotlib.pyplot` automatically registers Jupyter itself as a backend, so the graphs show up directly within the notebook. This used to require running `%matplotlib inline`, so you'll still see it in some notebooks, but it's not needed anymore." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "If the `plot` function is given one array of data, it will use it as the coordinates on the vertical axis, and it will just use each data point's index in the array as the horizontal coordinate.\n", "You can also provide two arrays: one for the horizontal axis `x`, and the second for the vertical axis `y`:" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": { "scrolled": true }, @@ -122,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -140,11 +139,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", + "\n", "x = np.linspace(-2, 2, 500)\n", "y = x**2\n", "\n", @@ -161,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -189,11 +189,12 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "plt.plot([0, 100, 100, 0, 0, 100, 50, 0, 100], [0, 0, 100, 100, 0, 100, 130, 100, 0])\n", + "plt.plot([0, 100, 100, 0, 0, 100, 50, 0, 100],\n", + " [0, 0, 100, 100, 0, 100, 130, 100, 0])\n", "plt.axis([-10, 110, -10, 140])\n", "plt.show()" ] @@ -208,11 +209,13 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "plt.plot([0, 100, 100, 0, 0, 100, 50, 0, 100], [0, 0, 100, 100, 0, 100, 130, 100, 0], \"g--\")\n", + "plt.plot([0, 100, 100, 0, 0, 100, 50, 0, 100],\n", + " [0, 0, 100, 100, 0, 100, 130, 100, 0],\n", + " \"g--\")\n", "plt.axis([-10, 110, -10, 140])\n", "plt.show()" ] @@ -228,11 +231,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "plt.plot([0, 100, 100, 0, 0], [0, 0, 100, 100, 0], \"r-\", [0, 100, 50, 0, 100], [0, 100, 130, 100, 0], \"g--\")\n", + "plt.plot([0, 100, 100, 0, 0], [0, 0, 100, 100, 0], \"r-\",\n", + " [0, 100, 50, 0, 100], [0, 100, 130, 100, 0], \"g--\")\n", "plt.axis([-10, 110, -10, 140])\n", "plt.show()" ] @@ -246,7 +250,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -266,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -284,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": { "scrolled": true }, @@ -308,7 +312,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "metadata": { "scrolled": true }, @@ -329,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "metadata": { "scrolled": true }, @@ -363,7 +367,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -385,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -417,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "metadata": { "scrolled": true }, @@ -458,7 +462,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -474,7 +478,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": { "scrolled": true }, @@ -517,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -527,9 +531,11 @@ "\n", "plt.plot(x, x**2, \"b-\", px, py, \"ro\")\n", "\n", - "plt.text(0, 1.5, \"Square function\\n$y = x^2$\", fontsize=20, color='blue', horizontalalignment=\"center\")\n", + "plt.text(0, 1.5, \"Square function\\n$y = x^2$\", fontsize=20, color='blue',\n", + " horizontalalignment=\"center\")\n", "plt.text(px - 0.08, py, \"Beautiful point\", ha=\"right\", weight=\"heavy\")\n", - "plt.text(px, py, \"x = %0.2f\\ny = %0.2f\"%(px, py), rotation=50, color='gray')\n", + "plt.text(px + 0.05, py - 0.4, \"x = %0.2f\\ny = %0.2f\"%(px, py), rotation=-30,\n", + " color='gray')\n", "\n", "plt.show()" ] @@ -547,7 +553,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -567,7 +573,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -576,8 +582,10 @@ "bbox_props = dict(boxstyle=\"rarrow,pad=0.3\", ec=\"b\", lw=2, fc=\"lightblue\")\n", "plt.text(px-0.2, py, \"Beautiful point\", bbox=bbox_props, ha=\"right\")\n", "\n", - "bbox_props = dict(boxstyle=\"round4,pad=1,rounding_size=0.2\", ec=\"black\", fc=\"#EEEEFF\", lw=5)\n", - "plt.text(0, 1.5, \"Square function\\n$y = x^2$\", fontsize=20, color='black', ha=\"center\", bbox=bbox_props)\n", + "bbox_props = dict(boxstyle=\"round4,pad=1,rounding_size=0.2\", ec=\"black\",\n", + " fc=\"#EEEEFF\", lw=5)\n", + "plt.text(0, 1.5, \"Square function\\n$y = x^2$\", fontsize=20, color='black',\n", + " ha=\"center\", bbox=bbox_props)\n", "\n", "plt.show()" ] @@ -591,7 +599,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -601,8 +609,10 @@ " bbox_props = dict(boxstyle=\"rarrow,pad=0.3\", ec=\"b\", lw=2, fc=\"lightblue\")\n", " plt.text(px-0.2, py, \"Beautiful point\", bbox=bbox_props, ha=\"right\")\n", "\n", - " bbox_props = dict(boxstyle=\"round4,pad=1,rounding_size=0.2\", ec=\"black\", fc=\"#EEEEFF\", lw=5)\n", - " plt.text(0, 1.5, \"Square function\\n$y = x^2$\", fontsize=20, color='black', ha=\"center\", bbox=bbox_props)\n", + " bbox_props = dict(boxstyle=\"round4,pad=1,rounding_size=0.2\", ec=\"black\",\n", + " fc=\"#EEEEFF\", lw=5)\n", + " plt.text(0, 1.5, \"Square function\\n$y = x^2$\", fontsize=20, color='black',\n", + " ha=\"center\", bbox=bbox_props)\n", "\n", " plt.show()" ] @@ -617,7 +627,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -639,9 +649,10 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "metadata": { - "scrolled": true + "scrolled": true, + "tags": [] }, "outputs": [], "source": [ @@ -668,7 +679,7 @@ "\n", "plt.figure(4)\n", "plt.plot(x, y - y.mean())\n", - "plt.yscale('symlog', linthreshy=0.05)\n", + "plt.yscale('symlog', linthresh=0.05)\n", "plt.title('symlog')\n", "plt.grid(True)\n", "\n", @@ -688,7 +699,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -731,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -755,7 +766,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "metadata": { "scrolled": true }, @@ -771,7 +782,8 @@ "\n", "figure = plt.figure(1, figsize = (12, 4))\n", "subplot3d = plt.subplot(111, projection='3d')\n", - "surface = subplot3d.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=matplotlib.cm.coolwarm, linewidth=0.1)\n", + "surface = subplot3d.plot_surface(X, Y, Z, rstride=1, cstride=1,\n", + " cmap=matplotlib.cm.coolwarm, linewidth=0.1)\n", "plt.show()\n" ] }, @@ -784,7 +796,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -809,12 +821,13 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ - "from numpy.random import rand\n", - "x, y = rand(2, 100)\n", + "np.random.seed(42) # to make this notebook's output reproducible\n", + "\n", + "x, y = np.random.rand(2, 100)\n", "plt.scatter(x, y)\n", "plt.show()" ] @@ -828,11 +841,11 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ - "x, y, scale = rand(3, 100)\n", + "x, y, scale = np.random.rand(3, 100)\n", "scale = 500 * scale ** 5\n", "plt.scatter(x, y, s=scale)\n", "plt.show()" @@ -847,7 +860,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "metadata": { "scrolled": true }, @@ -855,8 +868,8 @@ "source": [ "for color in ['red', 'green', 'blue']:\n", " n = 100\n", - " x, y = rand(2, n)\n", - " scale = 500.0 * rand(n) ** 5\n", + " x, y = np.random.rand(2, n)\n", + " scale = 500.0 * np.random.rand(n) ** 5\n", " plt.scatter(x, y, s=scale, c=color, alpha=0.3, edgecolors='blue')\n", "\n", "plt.grid(True)\n", @@ -875,18 +888,18 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ - "from numpy.random import randn\n", - "\n", "def plot_line(axis, slope, intercept, **kargs):\n", " xmin, xmax = axis.get_xlim()\n", - " plt.plot([xmin, xmax], [xmin*slope+intercept, xmax*slope+intercept], **kargs)\n", + " plt.plot([xmin, xmax],\n", + " [xmin*slope+intercept, xmax*slope+intercept],\n", + " **kargs)\n", "\n", - "x = randn(1000)\n", - "y = 0.5*x + 5 + randn(1000)*2\n", + "x = np.random.randn(1000)\n", + "y = 0.5*x + 5 + np.random.randn(1000) * 2\n", "plt.axis([-2.5, 2.5, -5, 15])\n", "plt.scatter(x, y, alpha=0.2)\n", "plt.plot(1, 0, \"ro\")\n", @@ -906,7 +919,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -924,7 +937,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "metadata": { "scrolled": true }, @@ -936,10 +949,13 @@ "data4a = np.random.randn(200) + 9\n", "data4b = np.random.randn(100) + 10\n", "\n", - "plt.hist(data1, bins=5, color='g', alpha=0.75, label='bar hist') # default histtype='bar'\n", - "plt.hist(data2, color='b', alpha=0.65, histtype='stepfilled', label='stepfilled hist')\n", + "plt.hist(data1, bins=5, color='g', alpha=0.75, histtype='bar', # default type\n", + " label='bar hist')\n", + "plt.hist(data2, color='b', alpha=0.65, histtype='stepfilled',\n", + " label='stepfilled hist')\n", "plt.hist(data3, color='r', histtype='step', label='step hist')\n", - "plt.hist((data4a, data4b), color=('r','m'), alpha=0.55, histtype='barstacked', label=('barstacked a', 'barstacked b'))\n", + "plt.hist((data4a, data4b), color=('r','m'), alpha=0.55, histtype='barstacked',\n", + " label=('barstacked a', 'barstacked b'))\n", "\n", "plt.xlabel(\"Value\")\n", "plt.ylabel(\"Frequency\")\n", @@ -960,13 +976,13 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "import matplotlib.image as mpimg\n", "\n", - "img = mpimg.imread('my_square_function.png')\n", + "img = mpimg.imread(\"my_square_function.png\")\n", "print(img.shape, img.dtype)" ] }, @@ -979,7 +995,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -994,11 +1010,48 @@ "Tadaaa! You may want to hide the axes when you are displaying an image:" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Under the hood, `imread()` uses the Python Image Library (PIL), and Matplotlib's documentation now recommends using PIL directly:" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "plt.imshow(img)\n", + "plt.axis('off')\n", + "plt.show()" + ] + }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], + "source": [ + "import PIL\n", + "\n", + "img = np.asarray(PIL.Image.open(\"my_square_function.png\"))\n", + "print(img.shape, img.dtype)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the array now contains unsigned 8-bit integers (from 0 to 255), but that's fine as `plt.imshow()` supports this format as well:" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], "source": [ "plt.imshow(img)\n", "plt.axis('off')\n", @@ -1009,12 +1062,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "It's just as easy to generate your own image:" + "You can also generate an image from scratch:" ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -1028,12 +1081,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As we did not provide RGB levels, the `imshow` function automatically maps values to a color gradient. By default, the color gradient goes from blue (for low values) to red (for high values), but you can select another color map. For example:" + "As we did not provide RGB levels, the `imshow` function automatically maps values to a color gradient. By default, the color gradient goes from blue (for low values) to yellow (for high values), but you can select another color map. For example:" ] }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ @@ -1050,7 +1103,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 43, "metadata": { "scrolled": true }, @@ -1073,7 +1126,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -1091,11 +1144,9 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "metadata": { - "jupyter": { - "outputs_hidden": true - } + "tags": [] }, "outputs": [], "source": [ @@ -1115,7 +1166,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -1124,7 +1175,7 @@ "data = np.array([x, y])\n", "\n", "fig = plt.figure()\n", - "line, = plt.plot([], [], \"r-\") # start with an empty plot\n", + "line, = plt.plot([], [], \"r-\") # start with an empty plot\n", "plt.axis([-1.1, 1.1, -1.1, 1.1])\n", "plt.plot([-0.5, 0.5], [0, 0], \"b-\", [0, 0], [-0.5, 0.5], \"b-\", 0, 0, \"ro\")\n", "plt.grid(True)\n", @@ -1132,11 +1183,13 @@ "\n", "# this function will be called at every iteration\n", "def update_line(num, data, line):\n", - " line.set_data(data[..., :num] + np.random.rand(2, num) / 25) # we only plot the first `num` data points.\n", + " # we only plot the first `num` data points.\n", + " line.set_data(data[..., :num] + np.random.rand(2, num) / 25)\n", " return line,\n", "\n", - "line_ani = animation.FuncAnimation(fig, update_line, frames=50, fargs=(data, line), interval=100)\n", - "plt.close() # call close() to avoid displaying the static plot" + "line_ani = animation.FuncAnimation(fig, update_line, frames=50,\n", + " fargs=(data, line), interval=100)\n", + "plt.close() # call close() to avoid displaying the static plot" ] }, { @@ -1148,7 +1201,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "metadata": {}, "outputs": [], "source": [ @@ -1166,7 +1219,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -1182,7 +1235,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ @@ -1198,11 +1251,12 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 50, "metadata": {}, "outputs": [], "source": [ - "animation.FuncAnimation(fig, update_line, frames=50, fargs=(data, line), interval=100)" + "animation.FuncAnimation(fig, update_line, frames=50, fargs=(data, line),\n", + " interval=100)" ] }, { @@ -1222,7 +1276,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 51, "metadata": {}, "outputs": [], "source": [