Solutions

Exercise 1

In this exercise we're using the data in BoltData.csv to find out how fast Usain Bolt runs in 100 m.

First we need to read in the data using np.loadtxt, and check that it's read in as expected.

In [23]:
dist, dist_unc, time, time_unc = np.loadtxt('./data/BoltData.csv', unpack=True, skiprows=1, delimiter=',')
In [24]:
print(dist, dist.shape)
print(dist_unc, dist_unc.shape)
print(time, time.shape)
print(time_unc, time_unc.shape)
[  0.  10.  20.  30.  40.  50.  60.  70.  80.  90. 100.] (11,)
[0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02 0.02] (11,)
[0.         0.9234224  2.17814477 2.46189746 3.38705138 5.26387915
 6.04270515 7.93919241 8.22177923 8.57812847 9.56287374] (11,)
[1.0048096  0.63756914 0.38236597 0.91178482 0.19851041 1.15222207
 0.16182731 0.732011   1.26732922 0.59090761 1.02233664] (11,)

The next thing to do is to plot the data. Get in the habit of plotting your data frequently. It's much easier to see if it looks like you expect from a plot than by staring at numbers on a screen.

In [25]:
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(1,1,1)
ax.errorbar(dist, time, yerr=time_unc, marker='o', ms=4,c='k', ls='None', capsize=4, label='Data')
ax.set_ylabel('Time (s)')
ax.set_xlabel('Distance (m)')
ax.legend(loc='upper left')
plt.show()

Measuring the speed

We want to measure the speed from the time and distance data:

$$v = \dfrac{d}{t}$$

We can do this by fitting a function of the form $y = m x + c$ to our data.

$$ t = \dfrac{d}{v} + c$$

Why is there a constant, $c$, in this function if we know that $t = \dfrac{d}{v}$? We don't know how the data was taken, so it may be that the timer didn't start at the exact time Bolt started running, so $c$ takes this into account.

Now set up our function:

In [26]:
def time_run(d, v, c):
    return d / v + c

and now we can find the value of $v$ and it's associated uncertainty $\sigma_v$ (and $c$, $\sigma_c$) using curve_fit

In [27]:
popt, pcov = curve_fit(time_run, dist, time)
speed = popt[0]
speed_unc = pcov[0][0]
intercept = popt[1]
int_unc = pcov[1][1]
print(speed, speed_unc)
print(intercept, int_unc)
9.984175690191293 0.20643331413262758
-0.04800892191601898 0.07271120631997624

Now we can re-plot our data with our best fit line and have the speed printed out in the title. We can save the plot using plt.savefig

In [28]:
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(1,1,1)
ax.plot(dist, time_run(dist, speed, intercept), 'b-', label='Best Fit')
ax.errorbar(dist, time, yerr=time_unc, marker='o', ms=4,c='k', ls='None', capsize=4, label='Data')
ax.set_ylabel('Time (s)')
ax.set_xlabel('Distance (m)')
title_string = "$v = {0:.2f} \pm {1:.2f}$ m s$^{{-1}}$".format(speed, speed_unc)
ax.set_title(title_string)
ax.legend(loc='upper left')
plt.show()
plt.savefig('Bolt_plot.png', dpi=300)
<Figure size 432x288 with 0 Axes>