Let's plot some PHYS 20700 level kinematics, namely the speed and position of an object in free fall near the surface of the Earth.
Our first step is to import two libraries that will be useful: numpy
, to handle variables in array formats and mapplotlib
to the plotting.
import numpy as np
import matplotlib.pyplot as plt
Our setup involves one constant value: the acceleration due to gravity,
# Define a variable to store the value of little g
g = 9.80
Now, we create a list (or array) of time values. The function np.linespace()
creates a linear spacing of values set by the 3 arguments in the parenthesis: begin, end, and how many. If you didn't know how the function works, you can always look it up in the documentation: Numpy Linspace
# make a list called time that ranges from 0 to 10 seconds.
time = np.linspace(0, 10, 100)
Next, we use our physics understanding to make a function for speed
# make a new list called speed
speed = g*time
Now, we can plot speed as a function of time using our two lists of values that we just created. Make sure to label the axes (and include the units), and give the plot a title.
fig, ax = plt.subplots()
ax.plot(time, speed)
ax.set_xlabel('Time [s]')
ax.set_ylabel('Speed [m/s]')
ax.set_title('Speed as a function of time')
plt.show()
This will result in the following plot
We can also consider the position of the object. That will be given by:
# create the position list based on the equation above
# we can use the np.square() function to ask for the square of each value in the time list
# rather than the square of the 1-d matrix.
position = 0.5*g*np.square(time)
Do the same plot routine, but change the speed
to position
.
fig, ax = plt.subplots()
ax.plot(time, position, linewidth=2.0)
ax.set_xlabel('Time [s]')
ax.set_ylabel('Position [m]')
ax.set_title('Position as a function of time')
plt.show()
We can annotate plots too, to help explain things. Here's an example where the point halfway through the motion is highlighted.
# Since our lists where 100 values long, we can just call our special point = 50.
specialPoint = 50
fig, ax = plt.subplots()
ax.plot(time, position, linewidth=2.0)
ax.set_xlabel('Time [s]')
ax.set_ylabel('Position [m]')
ax.set_title('Position as a function of time')
ax.grid()
# This line adds a circular 'o' marker at the specialPoint values for time and position.
ax.plot(time[specialPoint], position[specialPoint],'o', color = 'tab:blue')
# All of this is for the annotation.
plt.annotate("Important Data \n Point", # this is the text
xy=(time[50], position[50]), # these are the coordinates to position the label
textcoords="offset points", # how to position the text
xytext=(-40,40), # distance from text to points (x,y)
ha='center',
va='bottom',
bbox=dict(boxstyle='round,pad=0.5', fc='white', alpha=0.2),
arrowprops=dict(arrowstyle = '-|>', connectionstyle='arc3, rad=0'))
plt.show()
Now, let's plot both functions on the same graph. One will use the right axis, the other the left.
fig, ax1 = plt.subplots()
color = 'darkred'
ax1.set_xlabel('time [s]')
ax1.set_ylabel('Speed [m/s]', color=color)
ax1.plot(time, speed, color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax1.set_title('Position and Speed as a function of time')
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
color = 'darkblue'
ax2.set_ylabel('Position [m]', color=color) # we already handled the x-label with ax1
ax2.plot(time, position, color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
acceleration = np.full((100, 1),g)
fig, axs = plt.subplots(3, 1, figsize=(7, 7))
axs[0].plot(time, acceleration, color = "purple")
axs[0].set_ylabel('acceleration [m/s/s]')
axs[0].grid(True)
axs[0].set_title('The 3 kinematic variables')
axs[1].plot(time, speed, color = "green" )
axs[1].set_ylabel('speed [m/s]')
axs[1].grid(True)
axs[2].plot(time, position, color = "darkblue")
axs[2].set_xlabel('time [s]')
axs[2].set_ylabel('position [m]')
axs[2].grid(True)
fig.tight_layout()
plt.show()
Great. This should be a useful starting point for plotting analytic functions. To test your understanding and further develop this skillset, try making the following modifications.
This tutorial also exists as a Colab Notebook. You can find it here: Colab Function Plotting