For CCNY PHYS 35100
Fall 2024
J. Hedberg
---Let's plot some PHYS 20700 level kinematics, namely the speed and position of an object undergoing constant acceleration, i.e. $\frac{dv}{dt} = \textrm{constant}$
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 experiment involves one constant value: the acceleration of our particle. We can call it $a$ and give it a value of 5.
# Define a variable to store the value of a
a = 5.0
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 $v$, as a function of time. The following line will create a new list `speed` that is populated by the basic kinematic function that related speed, acceleration, and time. (We'll start at rest for simplicity sake) $$ v = v_0 + at $$
# make a new list called speed
speed = a*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: $$ x = x_0 + v_0 t + \frac{1}{2}a t^2$$ (We can assume for simplicity that $x_0$ and $v_0$ are both zero.)
# 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*a*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),a)
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