diff --git a/content/mooreslaw-tutorial.md b/content/mooreslaw-tutorial.md index 638853c4..e363b998 100644 --- a/content/mooreslaw-tutorial.md +++ b/content/mooreslaw-tutorial.md @@ -289,20 +289,23 @@ The style sheet replicates ```{code-cell} transistor_count_predicted = np.exp(B) * np.exp(A * year) transistor_Moores_law = Moores_law(year) + plt.style.use("fivethirtyeight") -plt.semilogy(year, transistor_count, "s", label="MOS transistor count") -plt.semilogy(year, transistor_count_predicted, label="linear regression") + +fig, ax = plt.subplots() +ax.semilogy(year, transistor_count, "s", label="MOS transistor count") +ax.semilogy(year, transistor_count_predicted, label="linear regression") -plt.plot(year, transistor_Moores_law, label="Moore's Law") -plt.title( +ax.plot(year, transistor_Moores_law, label="Moore's Law") +ax.set_title( "MOS transistor count per microprocessor\n" + "every two years \n" + "Transistor count was x{:.2f} higher".format(np.exp(A * 2)) ) -plt.xlabel("year introduced") -plt.legend(loc="center left", bbox_to_anchor=(1, 0.5)) -plt.ylabel("# of transistors\nper microprocessor") +ax.set_xlabel("year introduced") +ax.set_ylabel("# of transistors\nper microprocessor") +ax.legend(loc="center left", bbox_to_anchor=(1, 0.5)) ``` _A scatter plot of MOS transistor count per microprocessor every two years with a red line for the ordinary least squares prediction and an orange line for Moore's law._ @@ -346,19 +349,20 @@ y = np.linspace(2016.5, 2017.5) your_model2017 = np.exp(B) * np.exp(A * y) Moore_Model2017 = Moores_law(y) -plt.plot( +fig, ax = plt.subplots() +ax.plot( 2017 * np.ones(np.sum(year == 2017)), transistor_count2017, "ro", label="2017", alpha=0.2, ) -plt.plot(2017, transistor_count2017.mean(), "g+", markersize=20, mew=6) +ax.plot(2017, transistor_count2017.mean(), "g+", markersize=20, mew=6) -plt.plot(y, your_model2017, label="Your prediction") -plt.plot(y, Moore_Model2017, label="Moores law") -plt.ylabel("# of transistors\nper microprocessor") -plt.legend() +ax.plot(y, your_model2017, label="Your prediction") +ax.plot(y, Moore_Model2017, label="Moores law") +ax.set_ylabel("# of transistors\nper microprocessor") +ax.legend() ``` The result is that your model is close to the mean, but Gordon diff --git a/content/tutorial-deep-learning-on-mnist.md b/content/tutorial-deep-learning-on-mnist.md index d58f4f7b..9f1db288 100644 --- a/content/tutorial-deep-learning-on-mnist.md +++ b/content/tutorial-deep-learning-on-mnist.md @@ -166,10 +166,10 @@ import matplotlib.pyplot as plt # Take the 60,000th image (indexed at 59,999) from the training set, # reshape from (784, ) to (28, 28) to have a valid shape for displaying purposes. mnist_image = x_train[59999, :].reshape(28, 28) + +fig, ax = plt.subplots() # Set the color mapping to grayscale to have a black background. -plt.imshow(mnist_image, cmap="gray") -# Display the image. -plt.show() +ax.imshow(mnist_image, cmap="gray") ``` ```{code-cell} @@ -586,7 +586,6 @@ for ax, metrics, title in zip( ax.set_title(title) ax.set_xlabel("Epochs") ax.legend() -plt.show() ``` _The training and testing error is shown above in the left and right diff --git a/content/tutorial-ma.md b/content/tutorial-ma.md index fcb69eb2..3f18f86b 100644 --- a/content/tutorial-ma.md +++ b/content/tutorial-ma.md @@ -131,9 +131,11 @@ First of all, we can plot the whole set of data we have and see what it looks li import matplotlib.pyplot as plt selected_dates = [0, 3, 11, 13] -plt.plot(dates, nbcases.T, "--") -plt.xticks(selected_dates, dates[selected_dates]) -plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020") + +fig, ax = plt.subplots() +ax.plot(dates, nbcases.T, "--") +ax.set_xticks(selected_dates, dates[selected_dates]) +ax.set_title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020") ``` The graph has a strange shape from January 24th to February 1st. It would be interesting to know where this data comes from. If we look at the `locations` array we extracted from the `.csv` file, we can see that we have two columns, where the first would contain regions and the second would contain the name of the country. However, only the first few rows contain data for the the first column (province names in China). Following that, we only have country names. So it would make sense to group all the data from China into a single row. For this, we'll select from the `nbcases` array only the rows for which the second entry of the `locations` array corresponds to China. Next, we'll use the [numpy.sum](https://numpy.org/devdocs/reference/generated/numpy.sum.html#numpy.sum) function to sum all the selected rows (`axis=0`). Note also that row 35 corresponds to the total counts for the whole country for each date. Since we want to calculate the sum ourselves from the provinces data, we have to remove that row first from both `locations` and `nbcases`: @@ -183,9 +185,10 @@ Let's try and see what the data looks like excluding the first row (data from th closely: ```{code-cell} -plt.plot(dates, nbcases_ma[1:].T, "--") -plt.xticks(selected_dates, dates[selected_dates]) -plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020") +fig, ax = plt.subplots() +ax.plot(dates, nbcases_ma[1:].T, "--") +ax.set_xticks(selected_dates, dates[selected_dates]) +ax.set_title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020") ``` Now that our data has been masked, let's try summing up all the cases in China: @@ -232,9 +235,10 @@ china_total We can replace the data with this information and plot a new graph, focusing on Mainland China: ```{code-cell} -plt.plot(dates, china_total.T, "--") -plt.xticks(selected_dates, dates[selected_dates]) -plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China") +fig, ax = plt.subplots() +ax.plot(dates, china_total.T, "--") +ax.set_xticks(selected_dates, dates[selected_dates]) +ax.set_title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China") ``` It's clear that masked arrays are the right solution here. We cannot represent the missing data without mischaracterizing the evolution of the curve. @@ -271,21 +275,25 @@ package to create a cubic polynomial model that fits the data as best as possibl ```{code-cell} t = np.arange(len(china_total)) model = np.polynomial.Polynomial.fit(t[~china_total.mask], valid, deg=3) -plt.plot(t, china_total) -plt.plot(t, model(t), "--") + +fig, ax = plt.subplots() +ax.plot(t, china_total) +ax.plot(t, model(t), "--") ``` This plot is not so readable since the lines seem to be over each other, so let's summarize in a more elaborate plot. We'll plot the real data when available, and show the cubic fit for unavailable data, using this fit to compute an estimate to the observed number of cases on January 28th 2020, 7 days after the beginning of the records: ```{code-cell} -plt.plot(t, china_total) -plt.plot(t[china_total.mask], model(t)[china_total.mask], "--", color="orange") -plt.plot(7, model(7), "r*") -plt.xticks([0, 7, 13], dates[[0, 7, 13]]) -plt.yticks([0, model(7), 10000, 17500]) -plt.legend(["Mainland China", "Cubic estimate", "7 days after start"]) -plt.title( +fig, ax = plt.subplots() +ax.plot(t, china_total) +ax.plot(t[china_total.mask], model(t)[china_total.mask], "--", color="orange") +ax.plot(7, model(7), "r*") + +ax.set_xticks([0, 7, 13], dates[[0, 7, 13]]) +ax.set_yticks([0, model(7), 10000, 17500]) +ax.legend(["Mainland China", "Cubic estimate", "7 days after start"]) +ax.set_title( "COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China\n" "Cubic estimate for 7 days after start" ) diff --git a/content/tutorial-plotting-fractals.md b/content/tutorial-plotting-fractals.md index beb64e6d..fb18283e 100644 --- a/content/tutorial-plotting-fractals.md +++ b/content/tutorial-plotting-fractals.md @@ -219,8 +219,7 @@ mesh = x + (1j * y) output = divergence_rate(mesh) -fig = plt.figure(figsize=(5, 5)) -ax = plt.axes() +fig, ax = plt.subplots(figsize=(5, 5)) ax.set_title('$f(z) = z^2 -1$') ax.set_xlabel('Real axis') @@ -273,8 +272,7 @@ We will also write a function that we will use to create our fractal plots: ```{code-cell} ipython3 def plot_fractal(fractal, title='Fractal', figsize=(6, 6), cmap='rainbow', extent=[-2, 2, -2, 2]): - plt.figure(figsize=figsize) - ax = plt.axes() + fig, ax = plt.subplots(figsize=figsize) ax.set_title(f'${title}$') ax.set_xlabel('Real axis') diff --git a/content/tutorial-static_equilibrium.md b/content/tutorial-static_equilibrium.md index 29164be9..7ae1c796 100644 --- a/content/tutorial-static_equilibrium.md +++ b/content/tutorial-static_equilibrium.md @@ -97,8 +97,7 @@ d3.quiver(x, y, z, u, v, w, color="r", label="forceA") u, v, w = forceB d3.quiver(x, y, z, u, v, w, color="b", label="forceB") -plt.legend() -plt.show() +d3.legend() ``` There are two forces emanating from a single point. In order to simplify this problem, you can add them together to find the sum of forces. Note that both `forceA` and `forceB` are three-dimensional vectors, represented by NumPy as arrays with three components. Because NumPy is meant to simplify and optimize operations between vectors, you can easily compute the sum of these two vectors as follows: @@ -129,8 +128,7 @@ d3.quiver(x, y, z, u, v, w, color="b", label="forceB") u, v, w = forceC d3.quiver(x, y, z, u, v, w, color="g", label="forceC") -plt.legend() -plt.show() +d3.legend() ``` However, the goal is equilibrium. @@ -172,8 +170,6 @@ x, y, z = np.array([0, 0, 0]) u, v, w = forceA + forceB + R # add them all together for sum of forces d3.quiver(x, y, z, u, v, w) - -plt.show() ``` The empty graph signifies that there are no outlying forces. This denotes a system in equilibrium. diff --git a/content/tutorial-svd.md b/content/tutorial-svd.md index f7ab3c5c..fe72829c 100644 --- a/content/tutorial-svd.md +++ b/content/tutorial-svd.md @@ -74,8 +74,8 @@ import matplotlib.pyplot as plt ``` ```{code-cell} -plt.imshow(img) -plt.show() +fig, ax = plt.subplots() +ax.imshow(img) ``` ### Shape, axis and array properties @@ -196,8 +196,8 @@ To see if this makes sense in our image, we should use a colormap from `matplotl In our case, we are approximating the grayscale portion of the image, so we will use the colormap `gray`: ```{code-cell} -plt.imshow(img_gray, cmap="gray") -plt.show() +fig, ax = plt.subplots() +ax.imshow(img_gray, cmap="gray") ``` Now, applying the [linalg.svd](https://numpy.org/devdocs/reference/generated/numpy.linalg.svd.html#numpy.linalg.svd) function to this matrix, we obtain the following decomposition: @@ -259,8 +259,8 @@ np.allclose(img_gray, U @ Sigma @ Vt) To see if an approximation is reasonable, we can check the values in `s`: ```{code-cell} -plt.plot(s) -plt.show() +fig, ax = plt.subplots() +ax.plot(s) ``` In the graph, we can see that although we have 768 singular values in `s`, most of those (after the 150th entry or so) are pretty small. So it might make sense to use only the information related to the first (say, 50) *singular values* to build a more economical approximation to our image. @@ -282,8 +282,8 @@ approx = U @ Sigma[:, :k] @ Vt[:k, :] Note that we had to use only the first `k` rows of `Vt`, since all other rows would be multiplied by the zeros corresponding to the singular values we eliminated from this approximation. ```{code-cell} -plt.imshow(approx, cmap="gray") -plt.show() +fig, ax = plt.subplots() +ax.imshow(approx, cmap="gray") ``` Now, you can go ahead and repeat this experiment with other values of `k`, and each of your experiments should give you a slightly better (or worse) image depending on the value you choose. @@ -362,8 +362,9 @@ Since `imshow` expects values in the range, we can use `clip` to excise the floa ```{code-cell} reconstructed = np.clip(reconstructed, 0, 1) -plt.imshow(np.transpose(reconstructed, (1, 2, 0))) -plt.show() + +fig, ax = plt.subplots() +ax.imshow(np.transpose(reconstructed, (1, 2, 0))) ``` ```{note} @@ -391,8 +392,8 @@ approx_img.shape which is not the right shape for showing the image. Finally, reordering the axes back to our original shape of `(768, 1024, 3)`, we can see our approximation: ```{code-cell} -plt.imshow(np.transpose(np.clip(approx_img, 0, 1), (1, 2, 0))) -plt.show() +fig, ax = plt.subplots() +ax.imshow(np.transpose(np.clip(approx_img, 0, 1), (1, 2, 0))) ``` Even though the image is not as sharp, using a small number of `k` singular values (compared to the original set of 768 values), we can recover many of the distinguishing features from this image. diff --git a/content/tutorial-x-ray-image-processing.md b/content/tutorial-x-ray-image-processing.md index aa3f508a..bfed627b 100644 --- a/content/tutorial-x-ray-image-processing.md +++ b/content/tutorial-x-ray-image-processing.md @@ -135,9 +135,9 @@ print(xray_image.dtype) ```{code-cell} import matplotlib.pyplot as plt -plt.imshow(xray_image, cmap="gray") -plt.axis("off") -plt.show() +fig, ax = plt.subplots() +ax.imshow(xray_image, cmap="gray") +ax.set_axis_off() ``` ## Combine images into a multidimensional array to demonstrate progression @@ -240,7 +240,6 @@ axes[1].set_title("Laplacian-Gaussian (edges)") axes[1].imshow(xray_image_laplace_gaussian, cmap="gray") for i in axes: i.axis("off") -plt.show() ``` ### The Gaussian gradient magnitude method @@ -273,7 +272,6 @@ axes[1].set_title("Gaussian gradient (edges)") axes[1].imshow(x_ray_image_gaussian_gradient, cmap="gray") for i in axes: i.axis("off") -plt.show() ``` ### The Sobel-Feldman operator (the Sobel filter) @@ -338,7 +336,6 @@ axes[2].set_title("Sobel (edges) - CMRmap") axes[2].imshow(xray_image_sobel, cmap="CMRmap") for i in axes: i.axis("off") -plt.show() ``` ### The Canny filter @@ -399,7 +396,6 @@ axes[3].set_title("Canny (edges) - terrain") axes[3].imshow(xray_image_canny, cmap="terrain") for i in axes: i.axis("off") -plt.show() ``` ## Apply masks to X-rays with `np.where()` @@ -438,9 +434,9 @@ pixel_intensity_distribution = ndimage.histogram( xray_image, min=np.min(xray_image), max=np.max(xray_image), bins=256 ) -plt.plot(pixel_intensity_distribution) -plt.title("Pixel intensity distribution") -plt.show() +fig, ax = plt.subplots() +ax.plot(pixel_intensity_distribution) +ax.set_title("Pixel intensity distribution") ``` As the pixel intensity distribution suggests, there are many low (between around @@ -455,9 +451,9 @@ a certain threshold: # Return the original image if true, `0` otherwise xray_image_mask_noisy = np.where(xray_image > 150, xray_image, 0) -plt.imshow(xray_image_mask_noisy, cmap="gray") -plt.axis("off") -plt.show() +fig, ax = plt.subplots() +ax.imshow(xray_image_mask_noisy, cmap="gray") +ax.set_axis_off() ``` ```{code-cell} @@ -465,9 +461,9 @@ plt.show() # Return `1` if true, `0` otherwise xray_image_mask_less_noisy = np.where(xray_image > 150, 1, 0) -plt.imshow(xray_image_mask_less_noisy, cmap="gray") -plt.axis("off") -plt.show() +fig, ax = plt.subplots() +ax.imshow(xray_image_mask_less_noisy, cmap="gray") +ax.set_axis_off() ``` ## Compare the results @@ -500,7 +496,6 @@ axes[8].set_title("Mask (> 150, less noisy)") axes[8].imshow(xray_image_mask_less_noisy, cmap="gray") for i in axes: i.axis("off") -plt.show() ``` ## Next steps