|
217 | 217 | } |
218 | 218 | }, |
219 | 219 | "source": [ |
220 | | - "The colon character `:` is a shorthand notation for the entire set of values allowed for a particular index, and allows us access to an entire row or column. In the cell below, we use it to assign each column of `data` to the new variables `frequency`, `voltage`, and `err`, for later use." |
| 220 | + "The colon character `:` is a shorthand notation for the entire set of values allowed for a particular index, and allows us to access to an entire row or column. In the cell below, we use it to assign each column of `data` to the new variables `frequency`, `voltage`, and `err`, for later use." |
221 | 221 | ] |
222 | 222 | }, |
223 | 223 | { |
|
248 | 248 | }, |
249 | 249 | "source": [ |
250 | 250 | "## Step 3: Plot the data\n", |
251 | | - "To plot the data for analysis, we turn to the routines contained in `matplotlib.pyplot`, which we imported earlier under the abbreviated name `plt`. All of the PyPlot routines are listed on its [help page](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html), which links to additional help on each routine.\n", |
| 251 | + "To plot the data for analysis, we turn to the routines contained in `matplotlib.pyplot`, which we imported earlier under the abbreviated name `plt`. All the PyPlot routines are listed on its [help page](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html), which links to additional help on each routine.\n", |
252 | 252 | "\n", |
253 | 253 | "The following cell shows the voltage as a function of frequency, with the voltage uncertainty represented by an error bar. The first line calls the `errorbar` routine from `plt`. The first two arguments of `errorbar` are required, and correspond to the $x$ and $y$ variables in the plot, respectively. The third argument, `yerr=err`, tells `errorbar` to show errobars that extend `err` above and below the data point along the $y$ axis. The fourth argument, `fmt='o'` causes the data points to be represented as circles (`o`). For more details on `errorbar`, see its [help page](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.errorbar.html). After the `errorbar` statement, the next three lines produce labels for the $x$ and $y$ axes, along with the title. The last line displays the plot." |
254 | 254 | ] |
|
294 | 294 | "metadata": {}, |
295 | 295 | "source": [ |
296 | 296 | "### Tip: Express the model function in appropriate units\n", |
297 | | - "The default behavior of `curve_fit` is to stop adjusting any fit parameter that has been specified to an absolute numerical precision of 10<sup>-8</sup> or better. This will cause your fit to stop prematurely if you use units that make your optimal fit parameters numerically small, so you should typically use units for both your data and your fit parameters that yield numerical values much larger than 10<sup>-8</sup>. For example, express the mercury green emission wavelength as 546.1 nm or 0.5461 µm, not 5.461 × 10<sup>-7</sup> m. In this example, the data are expressed in millivolts and hertz, which yields numerical values for both the data and the optimal fit parameters that are numerically much larger that 10<sup>-8</sup>." |
| 297 | + "The default behavior of `curve_fit` is to stop adjusting any fit parameter that has been specified to an absolute numerical precision of 10<sup>-8</sup> or better. This will cause your fit to stop prematurely if you use units that make your optimal fit parameters numerically small, so you should typically use units for both your data and your fit parameters that yield numerical values much larger than 10<sup>-8</sup>. For example, express the mercury green emission wavelength as 546.1 nm or 0.5461 µm, not 5.461 × 10<sup>-7</sup> m. In this example, the data are expressed in millivolts and hertz, which yields numerical values for both the data and the optimal fit parameters that are numerically much larger than 10<sup>-8</sup>." |
298 | 298 | ] |
299 | 299 | }, |
300 | 300 | { |
|
325 | 325 | "\n", |
326 | 326 | "If you inspect the raw data in the errorbar plot above, you should see that the slope is close to two and the intercept is close to zero. You can also see this relationship in the tabular data, where most of the voltage values (in Hz) are about twice the frequency values (in mV). Consequently, we assign the initial parameter values `mInit = 2` and `bInit = 0` in the first two lines of code in the cell below. The remaining lines create a plot that shows how the model fits the data with these preliminary values for the fit parameters.\n", |
327 | 327 | "\n", |
328 | | - "First, we use the NumPy routine `linspace` to create `fModel`, an array with 1000 equally-spaced points ranging from 0 to 120. This allows us to extend the model curve to frequencies outside of the range of the original data. If necessary, we can adjust this point density to ensure there are no visual differences between the plotted function and the continuous curve it is representing.\n", |
| 328 | + "First, we use the NumPy routine `linspace` to create `fModel`, an array with 1000 equally-spaced points ranging from 0 to 120. This allows us to extend the model curve to frequencies outside the range of the original data. If necessary, we can adjust this point density to ensure there are no visual differences between the plotted function and the continuous curve it is representing.\n", |
329 | 329 | "\n", |
330 | 330 | "Next, we use `plot` from PyPlot to show the model curve evaluated at all fifty points in `fModel` with the parameters `mInit` and `bInit`. The third argument, `'r-'`, tells `plot` to represent this as a red line. The next lines use `errorbar`, `xlabel`, `ylabel`, and `title` to add the data as an errorbar plot, label the axes, and add a title, just as before. We then use `xlim` and `ylim` to adjust the limits of the $x$ and $y$ axes, respectively, and `show` to display the final plot." |
331 | 331 | ] |
|
500 | 500 | "4. Match the number of decimal places in the mean to the standard error.\n", |
501 | 501 | "5. Include units.\n", |
502 | 502 | "\n", |
503 | | - "The cell below uses Python [format specifiers](https://docs.python.org/3/library/string.html#formatspec) to display the variables with the correct precision. Appending `.format()` at the end of each string tells Python to format the arguments to `format` according to the format specifications that appear in the string as curly brackets `{}`. For example, `{0:.2f}` in the first line indicates that `mOpt`, the argument to `format` at position index `0`, should be displayed as a floating point number to two digits of precision (`.2f`). Later in the same line, `{1:.2f}` indicates that `mAlpha`, the argument to `format` at position index `1`, should be displayed with the same precision.See [here](https://docs.python.org/3/library/string.html#formatexamples) for additional examples." |
| 503 | + "The cell below uses Python [f-strings](https://docs.python.org/3/reference/lexical_analysis.html#f-strings) to display the variables with the correct precision. For example, `{mOpt:.2f}` in the first line indicates that `mOpt` should be displayed as a floating point number to two digits of precision (`.2f`). Later in the same line, `{mAlpha:.2f}` indicates that `mAlpha` should be displayed with the same precision. See [here](https://docs.python.org/3/tutorial/inputoutput.html#formatted-string-literals) for additional examples." |
504 | 504 | ] |
505 | 505 | }, |
506 | 506 | { |
|
512 | 512 | "# Display formatted results at correct level of significance\n", |
513 | 513 | "# Adjust each format string as appropriate\n", |
514 | 514 | "print(\"Correctly formatted precision:\")\n", |
515 | | - "print(\"Model slope (mV/Hz): {0:.2f} ± {1:.2f}\".format(mOpt, mAlpha))\n", |
516 | | - "print(\"Model intercept (mV): {0:.0f} ± {1:.0f}\".format(bOpt, bAlpha))\n", |
517 | | - "print(\"Correlation coefficient: {0:.1f}\".format(rho_mb))" |
| 515 | + "print(f\"Model slope (mV/Hz): {mOpt:.2f} ± {mAlpha:.2f}\")\n", |
| 516 | + "print(f\"Model intercept (mV): {bOpt:.0f} ± {bAlpha:.0f}\")\n", |
| 517 | + "print(f\"Correlation coefficient: {rho_mb:.1f}\")" |
518 | 518 | ] |
519 | 519 | }, |
520 | 520 | { |
|
592 | 592 | "res = voltage - model(frequency, mOpt, bOpt)\n", |
593 | 593 | "normres = res/err\n", |
594 | 594 | "chisq = np.sum(normres**2)\n", |
595 | | - "print(\"chisq = {0:.1f}\".format(chisq)) # Adjust the format specification as appropriate" |
| 595 | + "print(f\"chisq = {chisq:.1f}\") # Adjust the format specification as appropriate" |
596 | 596 | ] |
597 | 597 | }, |
598 | 598 | { |
|
647 | 647 | "outputs": [], |
648 | 648 | "source": [ |
649 | 649 | "cdf = chi2.cdf(chisq, dof)\n", |
650 | | - "print(\"Cumulative probability = {0:.3f}\".format(cdf))\n", |
651 | | - "print(\"Significance: {0:.3f}\".format(1-cdf))" |
| 650 | + "print(f\"Cumulative probability = {cdf:.3f}\")\n", |
| 651 | + "print(f\"Significance: {1-cdf:.3f}\")" |
652 | 652 | ] |
653 | 653 | }, |
654 | 654 | { |
|
757 | 757 | "* *Importing data files:* for simple file formats, use [genfromtext](https://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html).\n", |
758 | 758 | "* *Defining functions:* see [here](https://docs.python.org/3/tutorial/controlflow.html#defining-functions) for a general introduction to function definitions.\n", |
759 | 759 | "* *Plotting data:* this is what [matplotlib](https://matplotlib.org/users/index.html) was designed for. Within that package, [PyPlot](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.html) has many routines for interactive plotting, such as [errorbar](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.errorbar.html), [plot](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html), and [stem](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.stem.html). Once you have the plot, you can use additional routines to format it, such as [xlabel](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.xlabel.html), [ylabel](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.ylabel.html), [title](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.title.html), [xlim](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.xlim.html), and [ylim](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.ylim.html).\n", |
760 | | - "* *Curve fitting:* the [curve_fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) routine includes all of the features that you need for basic use.\n", |
| 760 | + "* *Curve fitting:* the [curve_fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) routine includes all the features that you need for basic use.\n", |
761 | 761 | "* *Mathematical functions:* Python can perform [basic mathematical operations](https://docs.python.org/3/tutorial/introduction.html#numbers), and NumPy includes several additional [mathematical functions](https://docs.scipy.org/doc/numpy/reference/routines.math.html) such as trigonometric functions, exponentials, array products and sums, etc.\n", |
762 | 762 | "* *The chi-squared distribution:* the [chi2](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chi2.html#scipy.stats.chi2) routine may be used to evaluate fit quality." |
763 | 763 | ] |
|
0 commit comments