To create a simple line plot that connects points in a Cartesian plane:
plot()
functionHere’s an example, showing a parabola (\(y = x^2\)):
import matplotlib.pyplot as plt
x = [1, 5, 9, 13]
y = [1, 25, 81, 169]
plt.plot(x, y)
When you only plot a few points as in the previous example, the resulting curve will look jagged. If you are plotting a continuous function like this it’s usually better to have it be a smooth curve. While it isn’t technically possible to plot a continuous curve using this method, you can at least make the line appear smooth by simply increasing the number of points you plot:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 13, 100)
y = x**2
plt.plot(x, y)
The above example is plotting 100 points and connecting them with straight lines. So the jagged edges still exist but they are now too small to be noticeable! Note the function that was used to create the x-data: Numpy’s linspace()
. This function creates an array of numbers evenly spaced between a given start point and a given end point with the number of values created being the third input to the function. In this case the inputs were 0, 13 and 100, so 100 values were generated starting at 0 and ending at 13. The y-data was then created by taking the square of the x-data.
If you want to plot a straight line, you can simply plot two points and they will be connected as expected. In the special cases where you want to create horizontal or vertical lines that extend right to the ends of the graph in both directions, there are special functions axhline()
and axvline()
:
# Plot a straight diagonal line
plt.plot([0, 9], [0, 8])
# Plot a horizontal line
plt.axhline(4)
# Plot a vertical line
plt.axvline(7)
Uncertainty can be communicated using the errorbar()
function to plot error bars:
x = [1, 5, 9, 13]
y = [1, 25, 81, 169]
yerr = [1.5, 7.5, 15, 19]
plt.plot(x, y)
plt.errorbar(x, y, yerr=yerr, fmt='o', color='purple')
plt.show()
Change the look of the plot with the following options:
title()
ylabel()
and xlabel()
ylim()
and xlim()
c
and lw
keyword arguments in the plot()
call (see this page for all the colour and line options)show()
Here’s an example using Manchester City’s log points after each matchweek of the 2018-19 English Premier League season:
import matplotlib.pyplot as plt
week = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
]
log_points = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
plt.plot(week, log_points, c='#6caddf', lw=3)
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.show()
Some more options that can be tinkered with:
alpha
keyword argument within plot()
grid()
function in which you can set which
gridlines to mark (major, minor or both) and the axis
to apply the lines to (x, y or both), along with other keyword arguments related to line plots
plt.minorticks_on()
plt.plot(week, log_points, c='#6caddf', lw=3, alpha=0.5)
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.grid(which='major', c='grey', lw='0.5', linestyle='-')
plt.show()
There is a difference between text and annotations on a graph:
text()
function which allows you to specify the x- and y-coordinates of the label’s position along with the string that should appear. There are also additional options that can be edited, such as ha
(the horizontal alignment of the text), size
and color
annotate()
together with a number of arguments. These arguments can be specified by using their keywords or they can be given without keywords if they are in the following order:
text
is the string that should appearxy
is a tuple containing the coordinates of the tip of the arrow. By default, these are interpreted as the Cartesian coordinates of the axes.xytext
is a tuple containing the coordinates of the text. Again, by default, these are Cartesian coordinates.xycoords
is the coordinate system that xy
(the position of the tip of the arrow) is given in. There are a number of options but perhaps the most useful, besides Cartesian, is 'axes fraction'
which allows you to specify the position as fractions of the width and height of the graph area. Unlike the default Cartesian coordinate system, this option allows you to add annotations outside of the actual graph area.textcoords
is similar to xycoords
but is for the text, not the tip of the arrow. In addition to all the options available for xycoords
you can use 'offset points'
or 'offset pixels'
which specifies the position of the text as an offset from the point it is annotating.arrowprops
is a dictionary of options for the arrowannotate()
gives you you can do so. Conversely, you can create arrows without text by simply not specifying a string:plt.plot(week, log_points, c='#6caddf', lw=3, alpha=0.5)
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlim(1, 38)
# Add text and annotations
plt.text(33, 62, 'Final 14 matches', ha='center')
plt.text(33, 58, 'were all victories', ha='center')
plt.annotate(
'Moved clear at the top of the table', (11, 29), (30, -20), textcoords='offset points',
arrowprops=dict(facecolor='black', width=0.5, headwidth=5, headlength=7)
)
plt.annotate('Week 11', (11, 29), (-6, 6), textcoords='offset points', ha='right')
plt.annotate(
'', (16 / 38, -0.07), (28 / 38, -0.07), 'axes fraction', 'axes fraction',
arrowprops=dict(arrowstyle="<->", color='k')
)
plt.annotate('Dropped from top spot', (22 / 38, -0.12), xycoords='axes fraction', ha='center')
plt.show()
Read the full documentation for text labels here and for annotations here.
To plot multiple data series on the same axes, simply use the plot()
function multiple times. When doing this, it’s usually best to include a legend. This is created via legend()
after having specified the label
keyword argument in the plot()
calls:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# Get the data
data = pd.read_csv('Week-by-Week Points.csv')
# Plot
for team in list(data):
log_points = data[team]
week = np.arange(1, 39)
plt.plot(week, log_points, label=team)
plt.title('2018-19 English Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.legend(fontsize='xx-small')
Of course, for this particular example, it makes sense to individually set the team colours:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# Get the data
data = pd.read_csv('Week-by-Week Points.csv')
# Create a dictionary of the colours
team_colours = {
'AFC Bournemouth': '#8b0304',
'Arsenal': '#ff0000',
'Brighton': '#005daa',
'Burnley': '#80bfff',
'Cardiff': '#224781',
'Chelsea': '#0000dd',
'Crystal Palace': '#0a4af5',
'Everton': '#274488',
'Fulham': '#000000',
'Huddersfield': '#176fc0',
'Leicester': '#0101e8',
'Liverpool': '#dd0000',
'Man City': '#6caddf',
'Man Utd': '#e80909',
'Newcastle': '#000000',
'Southampton': '#ed1a3b',
'Spurs': '#132257',
'Watford': '#fbee23',
'West Ham': '#7f0000',
'Wolves': '#fdbc02'
}
# Plot
for team in list(data):
log_points = data[team]
week = np.arange(1, 39)
plt.plot(week, log_points, label=team, c=team_colours[team])
plt.title('2018-19 English Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.legend(fontsize='xx-small')
It often makes sense to place the legend outside of the axes to give it a bit more room. This requires some size adjustments using subplots_adjust()
and more complicated arguments to be passed to legend()
:
for team in list(data):
log_points = data[team]
week = np.arange(1, 39)
plt.plot(week, log_points, label=team, c=team_colours[team])
plt.title('2018-19 English Premier League Season')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.subplots_adjust(right=0.75)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), fontsize='small')
If you want the data series to appear in a particular order in the legend, you can assign each of them to a variable and then call those variables in the legend()
call. In this example, the data for Fulham, Man City and Wolves are plotted in that order, but the order they appear in the legend is manually determined:
week = np.arange(1, 39)
man_city = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
wolves = [
1, 1, 2, 5, 8, 9, 12, 15, 15, 15, 15, 16, 16, 16, 19, 22, 25, 25, 26, 29,
29, 29, 32, 35, 38, 39, 40, 40, 43, 44, 44, 47, 47, 47, 51, 54, 57, 57
]
fulham = [
0, 0, 3, 4, 4, 5, 5, 5, 5, 5, 5, 5, 8, 8, 9, 9, 9, 10, 11, 14, 14,
14, 14, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 20, 23, 26, 26, 26
]
# Notice the commas after the variable names
fulham, = plt.plot(week, fulham, c='#000000')
man_city, = plt.plot(week, man_city, c='#6caddf')
wolves, = plt.plot(week, wolves, c='#fdbc02')
plt.title('2018-19 English Premier League Season')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.legend(
(man_city, wolves, fulham),
('Man City', 'Wolves', 'Fulham'),
loc='center left'
)
There are two methods of doing this. The first - fill()
- will take the points you are plotting, draw straight lines between them (including from the last point back to the first point) and then fill in that enclosed area with colour. This means that, in order to get this method to work for our data, we need to add an extra point at the start and an extra point at the end. These will be at (1, 0) and (38, 0), respectively:
import matplotlib.pyplot as plt
week = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
]
log_points = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
# Plot
plt.plot(week, log_points, c='#6caddf', lw=3)
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
# Add colour fill
week = [
1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 38
]
log_points = [
0, 3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98, 0
]
plt.fill(week, log_points, facecolor='#6caddf', alpha=0.5)
plt.show()
This is obviously quite obtuse, so a simpler option would be to use fill_between()
which fills in the area between lines with colour. If you only specify one line then it will default to assuming that the second line is the x-axis:
import matplotlib.pyplot as plt
week = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
]
log_points = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
# Plot
plt.plot(week, log_points, c='#6caddf', lw=3)
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.fill_between(week, log_points, facecolor='#6caddf', alpha=0.5)
plt.show()
And then, of course, you still have the option of specifying a second line in order to fill in the area between those two:
week = np.arange(1, 39)
man_city = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
wolves = [
1, 1, 2, 5, 8, 9, 12, 15, 15, 15, 15, 16, 16, 16, 19, 22, 25, 25, 26, 29,
29, 29, 32, 35, 38, 39, 40, 40, 43, 44, 44, 47, 47, 47, 51, 54, 57, 57
]
# Plot
plt.plot(week, man_city, c='#6caddf', label='Man City', lw=3)
plt.plot(week, wolves, c='#fdbc02', label='Wolves', lw=3)
plt.title('2018-19 English Premier League Season')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.legend()
plt.fill_between(week, man_city, wolves, facecolor='gray', alpha=0.5)
plt.show()
plt.fill_betweenx(y, x)
to do the same thing as above but between two vertical curves (or between a curve and the y-axis)hatch
keyword argument to apply a pattern to the shaded area. To increase the density of the shading, increase the number of characters when setting the hatch pattern (see here for more examples):week = np.arange(1, 39)
man_city = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
wolves = [
1, 1, 2, 5, 8, 9, 12, 15, 15, 15, 15, 16, 16, 16, 19, 22, 25, 25, 26, 29,
29, 29, 32, 35, 38, 39, 40, 40, 43, 44, 44, 47, 47, 47, 51, 54, 57, 57
]
# Plot
plt.plot(week, man_city, c='#6caddf', label='Man City', lw=3)
plt.plot(week, wolves, c='#fdbc02', label='Wolves', lw=3)
plt.title('2018-19 English Premier League Season')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.legend(framealpha=1)
plt.fill_betweenx(man_city, week, facecolor='#6caddf', alpha=0.5, hatch='++')
plt.fill_between(week, wolves, facecolor='#fdbc02', alpha=0.5, hatch='...')
plt.show()
Use yticks()
and xticks()
to:
import matplotlib.pyplot as plt
week = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
]
log_points = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
plt.plot(week, log_points, c='#6caddf')
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Month')
plt.xlim(1, 38)
plt.xticks(
[1, 4, 7, 11, 14, 21, 25, 29, 32, 37],
['Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May']
)
plt.show()
In the previous example, the plot was created using numbers on the x-axis which were then replaced by text labels manually via the xticks()
function. In this example, however, we ‘cut out the middleman’ and use text strings as the x-data from the start:
plt.rc('text', usetex=True)
month = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
]
temp = [
6.7, 6.8, 8.8, 11.9, 14.7, 18.2,
19.5, 19.3, 17.3, 13.5, 9.9, 7.0
]
plt.plot(month, temp, 'k')
plt.title('Climate of London')
plt.ylabel(r'Mean Daily Temperature [\textdegree C]')
plt.xlabel('Month')
The above data comes from Wikipedia.
If you want to change the scale on an axis, the best practice is to edit the values right as they are being passed into the function as opposed to creating a new variable. For example, the numbers that make up our x-data are in ‘weeks’ but if we want to scale them up to ‘days’ we merely need to convert the list into an array and then multiply it by 7. This should be done right in the argument of the plot()
call instead of defining a new variable:
import matplotlib.pyplot as plt
import numpy as np
week = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
]
log_points = [
3, 6, 7, 10, 13, 16, 19, 20, 23, 26, 29, 32, 35, 38, 41, 41, 44, 44, 44,
47, 50, 53, 56, 56, 62, 65, 65, 68, 71, 74, 74, 80, 80, 83, 89, 92, 95, 98
]
plt.plot(np.array(week) * 7, log_points, c='#6caddf')
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Day')
plt.xlim(7, 266)
plt.show()
The above is better than doing the following if all you want to do is re-scale the axis:
days = np.array(week) * 7
plt.plot(days, log_points, c='#6caddf')
Note that the format of the numbers on the axes can be changed to scientific notation by using the ticklabel_format(<axis>, <style>)
function.
If you want to use logarithmic scales, take a look at the semilogy()
, semilogx()
or loglog()
function, depending on which axis/axes you want to change:
import matplotlib.pyplot as plt
import numpy as np
# Fake up some data
x = np.linspace(0, 10, 50)
y = np.exp(x)
# Plot
plt.semilogy(x, y)
plt.title('The Exponential Function with Log Scaling')
This can be done using the tick_params()
function:
plt.plot(week, log_points, c='#6caddf')
plt.title('Manchester City in the 2018-19 Premier League')
plt.ylabel('Log Points')
plt.ylim(0, 100)
plt.xlabel('Week')
plt.xlim(1, 38)
plt.tick_params('x', labelrotation=30)
plt.show()
To create two (or more) completely separate plots in the same figure you will need to create sub-plots:
subplot(rcn)
will create a sub-plot object where r
is the total number of rows of plots you intend to make, c
is the number of columns of plots you intend to make and n
is the number that this plot will be within the grid of plots. For example, subplot(321)
will divide your figure into a grid with 3 rows and 2 columns (ie space for 6 plots) and then create an empty sub-plot for the first (top-left) of these plots. The plots are numbered using ‘reading order’ (left-to-right, top-to-bottom), ie plot 2 will be top-right, plot 3 will be middle-left and so on.figure(figsize=(w, h))
to set the width and height of the figure you are currently working onrc('figure', figsize=(w, h))
to set the same figsize parameter as above but for all the figures in your codetitle()
creates a title for one individual plot, in order to create a title for the entire figure you need to use suptitle()
tight_layout()
import matplotlib.pyplot as plt
import numpy as np
import math
# Create data
x = np.linspace(0, math.tau, 100)
#
# Plot
#
plt.figure(figsize=(12, 5))
plt.suptitle('Trigonometric Functions')
# First sub-plot
plt.subplot(121)
plt.plot(x, np.sin(x))
plt.axhline(0, c='gray', alpha=0.5)
plt.title(r'$sin(\theta)$')
plt.ylabel(r'Amplitude, $A$')
plt.xlabel(r'Angle of Rotation, $\theta$ [radians]')
plt.xlim(0, math.tau)
# Second sub-plot
plt.subplot(122)
plt.plot(x, np.cos(x))
plt.axhline(0, c='gray', alpha=0.5)
plt.title(r'$cos(\theta)$')
plt.ylabel(r'Amplitude, $A$')
plt.xlabel(r'Angle of Rotation, $\theta$ [radians]')
plt.xlim(0, math.tau)
plt.xticks(
[0, 0.25 * math.tau, 0.5 * math.tau, 0.75 * math.tau, math.tau],
['$0$', r'$\frac{1}{4}\tau$', r'$\frac{1}{2}\tau$', r'$\frac{3}{4}\tau$', r'$\tau$']
)
plt.tight_layout()
plt.show()
See here for more about using Latex formatting in the title and axes’ labels and see here for more about changing the image size.
# Make figures A5 in size
A = 5
plt.rc('figure', figsize=[46.82 * .5**(.5 * A), 33.11 * .5**(.5 * A)])
# Image quality
plt.rc('figure', dpi=141)
# Be able to add Latex
plt.rc('text', usetex=True)
plt.rc('font', family='serif')
plt.rc('text.latex', preamble=r'\usepackage{textgreek}')
# Plot
plt.plot(week, log_points, c='#6caddf')
plt.title(r'How to Include \LaTeX\ in Labels')
plt.ylabel(r'Output, $T$ [\textdegree C]')
plt.ylim(0, 100)
plt.xlabel(r'Input, $t$ [\textmu s]')
plt.xlim(1, 38)
plt.text(20, 30, r'\textAlpha\textBeta\textGamma\textDelta\textEpsilon\textZeta\textEta\textTheta\textIota\textKappa\textLambda\textMu\textNu\textXi\textOmikron\textPi\textRho\textSigma\textTau\textUpsilon\textPhi\textChi\textPsi\textOmega')
plt.text(20, 24, r'\textalpha\textbeta\textgamma\textdelta\textepsilon\textzeta\texteta\texttheta\textiota\textkappa\textlambda\textmu\textmugreek\textnu\textxi\textomikron\textpi\textrho\textsigma\texttau\textupsilon\textphi\textchi\textpsi\textomega')
plt.text(20, 18, r'\textvarsigma\straightphi\scripttheta\straighttheta\straightepsilon')
plt.text(20, 12, r'$$\lim_{n \to \infty} \left(1+\frac{1}{n}\right)^n$$')
Finally, save the plot as a PNG, JPG, PDF or other type of image with savefig()
or display it in a pop-up window with show()
:
plt.savefig('Line Plot.png')
If you are plotting more than one figure in the same Python script use figure()
and close()
before and after each, respectively, in order to tell Python when one plot ends and the next one starts.
With two dependent variables you will often want two y-axes.
It’s not common to represent one series of data with two dependent variables on a 2D graph, but it can be useful when there is a constant relationship between the dependent variables. For example, if we take the force and pressure exerted on a piston, the relationship between the two (\(P = \frac{F}{A}\)) remains constant because the area of the piston head (\(A\)) doesn’t change. Here’s what the force vs time graph might look like:
import math
import matplotlib.pyplot as plt
import numpy as np
# Fake up some data
np.random.seed(20210319)
time = np.linspace(0, 10, 20)
force = time**2 + np.random.normal(size=20) * 2
area = (math.tau * 0.04**2) / 2
# Plot
plt.plot(time, force)
plt.title('Force vs Time')
plt.ylabel(r'Force, $F$ [N]')
plt.ylim(0, )
plt.xlabel(r'Time, $t$ [s]')
plt.xlim(0, 10)
plt.show()
Now, to add in the pressure, we need another whole set of axes. This can be achieved by ‘twinning’ the current x-axis (because the second y-axis will use the same x-axis as the first) via twinx()
to create a new set of axes. This set won’t have any data on it yet, so we need to have calculated the pressure values in order to now plot them. It will also make sense to scale the pressure values by a factor of 1,000 so that they are in kilopascals instead of pascals:
import numpy as np
# Calculate
pressure = [f / area for f in force]
# Plot
plt.plot(time, force)
plt.title('Force and Pressure vs Time')
plt.ylabel(r'Force, $F$ [N]')
plt.ylim(0, )
plt.xlabel(r'Time, $t$ [s]')
plt.xlim(0, 10)
plt.twinx()
plt.plot(time, pressure)
plt.ylabel(r'Pressure, $P$ [kPa]')
plt.ylim(0, )
plt.show()
In the previous example, the two axes both related to the same series of data. If, however, you want to plot two different but related series you will need to separate them more clearly:
yticks()
or xticks()
functionimport numpy as np
import math
import matplotlib.pyplot as plt
# Fake up some data
np.random.seed(20210316)
x = np.linspace(0, 0.4 * math.tau, 20)
y_1 = np.sin(x) + np.random.normal(size=20) * 0.08
y_2 = 5 * np.sin(x * 0.75) + np.random.normal(size=20) * 0.08
#
# Plot
#
plt.title('Measurements vs Time')
plt.xlabel(r'Time, $t$ [s]')
# First dependent variable
plt.plot(x, y_1, c='b', marker='x')
plt.ylabel(r'Measurement 1, $m_1$ [m]', color='b')
plt.ylim(0, )
plt.yticks(c='b')
plt.xlim(0, )
# Create a second set of axes, twinned with the first x-axis
plt.twinx()
# Second dependent variable
plt.plot(x, y_2, c='r', marker='x')
plt.ylabel(r'Measurement 2, $m_2$ [m]', color='r')
plt.ylim(0, )
plt.yticks(c='r')
plt.show()