PHYSICS AND ENGINEERING RESEARCH › PRACTICE 2
Plots, Slices and Fits
Practice 1 got one number out of a whole run. This one is about looking inside the run: taking the part you actually want, asking the data a question with a condition, and turning a slope into a physical quantity you would be willing to defend.
P2.A Make a plot another person could read without you standing next to them.
P2.B Slice an array, and use a boolean mask to select data by a condition rather than by position.
P2.C Fit a straight line, say what the slope and intercept mean physically, and check the fit rather than trusting it.
1. A plot is a claim, and it has to survive being read by someone else
Both axes get the quantity and its unit. More than one line on the axes gets a legend. That is not decoration: a plot with no axis labels cannot be checked by anybody, including you next month.
plt.xlabel(“Time (s)”)plt.ylabel(“Position (m)”)
Hand your screen to the person next to you and see what they can tell you about the run. Whatever they cannot work out is what your plot is failing to communicate, and the most dangerous gap is the one they guess at confidently.
Save with plt.savefig at dpi=200 rather than taking a screenshot. A saved figure keeps its resolution when it goes into a report, and it can be regenerated exactly when the data changes. A screenshot cannot.
2. Slicing: the part of the run you actually want
a[start:stop] takes from start up to but not including stop. Leave one end off and it runs to the end of the array. Negative counting starts from the back.
t[1:4] has three entries4 minus 1, not four
The first moments of a run are often the cart being let go, and the last few are often it hitting the stop. Slicing is how you leave those out.
3. Masks: choosing by a condition instead of by position
v > 1.0 does not give you a number. It gives an array of True and False, one for every element. Put that inside the brackets and you get back only the elements where it was True.
v[v > 1.0]the speeds above 1.0t[v > 1.0]when they happened
The second one is the interesting one, and it is the whole point of a mask: a condition built from one array can select rows of another, as long as they are the same length. That is how you find the times at which something was true.
Because the mask holds True and False, and Python counts True as one, (v > 1.0).sum() counts how many readings satisfied it.
4. Fitting a line, and what the two numbers mean
On a graph of velocity against time, the slope is the acceleration. np.polyfit(t, v, 1) fits the best straight line and hands back two numbers, the slope first and the intercept second.
slope, intercept = np.polyfit(t, v, 1)
The slope is in meters per second per second, and it is the acceleration. The intercept is in meters per second, and it is the velocity the fitted line predicts at t = 0. For the class run the fit gives 0.4201 m/s² with an intercept of about −0.0008 m/s, which is a cart released very nearly from rest.
Someone else takes the first and last velocity and divides by the elapsed time, and gets 0.4198 m/s². Nearly the same, and that agreement is not guaranteed. The fit uses all sixty-one points; the two-point method uses two, so it hears every bit of noise in exactly those two and nothing else. They agree here because this run is clean and genuinely straight. On a noisy run, or one where the acceleration changed partway, they would not.
What does this line give you?
A line of code from a real analysis. Say what it hands back. These are the four kinds of thing you will be holding, and confusing them is where wrong numbers come from.
5. Checking the fit, because polyfit never complains
polyfit will fit a straight line to a circle without objecting. The fit is not the answer. The fit plus a reason to believe it is the answer.
Draw the fitted line over the data. np.poly1d turns the two numbers back into a function you can evaluate, so you can plot the line on the same axes as the points and look at what is left over.
Plot the residuals. Residual means data minus fit. Plot the residuals against time. A good straight-line fit leaves a shapeless scatter around zero. A bad one leaves an obvious curve, and that curve is the model being wrong in a way the single number never showed you.
Check the number against something independent. The fit says 0.42 m/s². The run covers 1.8903 m in 3.00 s starting from rest, and 2 × 1.8903 / 3.00² gives 0.4201 m/s² from the position data alone, without touching the velocity column. Two different routes through the same run agreeing is worth more than either one on its own.
Check yourself
1. For t = np.array([0.0, 0.1, 0.2, 0.3, 0.4, 0.5]), say what t[1:4], t[:3] and t[-2:] give, and explain the count in the first one to someone who will read it next month.
t[1:4] gives 0.1, 0.2, 0.3, three entries, because the stop index is not included: the count is 4 minus 1. t[:3] gives 0.0, 0.1, 0.2, and t[-2:] gives the last two, 0.4, 0.5. The wording that survives a month is stop minus start, and stop is not included.
2. A student writes v[v > 1.0] and gets an empty array back, but the plot clearly shows the cart going faster than that. Give two different causes and say how you would tell them apart.
Either the velocity column was never loaded into v and it holds something else, such as position or text, or v was sliced earlier and the fast part of the run was cut off. Tell them apart by printing v.max(), len(v) and v.dtype. A max below 1.0 with the full length points at the wrong column. A short length points at the slice. A dtype of object or string points at the file having been loaded without skiprows=1.
3. You fit a straight line to x against t for a cart that is speeding up. The fit succeeds and returns a number. Say what that number is and what it is not.
It is the average velocity over the run, in meters per second, and it is the best straight line through a curve that is not straight. It is not the acceleration, which would be the slope of velocity against time. It is not the velocity at any particular instant either, except by coincidence at one moment in the middle. The residual plot would show an obvious curve, which is the signal that the model is wrong.
4. The two-point method and the fit agree on this run. Describe a run where they would disagree by half, and say which one you would report.
A run where the acceleration is not constant: the cart is released, rolls freely, then meets more friction partway down. The two-point method sees only the endpoints and reports one average. The fit sees the shape and reports the best single slope, and its residual plot shows the curve that tells you a single slope is the wrong description. Report the fit, and report that the residuals are not shapeless, because at that point the honest answer is not one number.
5. Write down the acceleration for the cart run the way it would appear in a report.
Something of the form: the acceleration was 0.420 m/s², obtained from a least-squares straight-line fit to the velocity against time over all 61 samples of the run. The three parts that must be there are the value, the unit, and how it was obtained. A number with no unit is not a result, and a number with no method behind it cannot be checked by anybody.
Uncertainty. Every number on this page was quoted without one. The next step is saying how well you know the slope, which turns a value into a measurement.