import numpy as np
import matplotlib.pyplot as plt
Plotting Graphs
The matplotlib is one of the most popular libraries for plotting graphs with Python. Unlike many modern counterparts, matplotlib is primarily designed to produce static plots. It is still a popular option to generate publication quality plots in the academia.
While it is easy to get started, it is very flexible and allows drawing complex things.
While interactivity is not part of its design, we can achieve that using interactive widgets and creating animations. However, that may required a lot more code and may sound tedius.
Needless to day, we use numpy arrays for plotting graphs.
Getting started with plotting
Let’s plot sqrt.
= np.linspace(0, 2, 100)
x = np.sqrt(x) y
plt.plot(x, y)
# add a grid to the graph
plt.grid()
We can even plot multiple plots in the same figure.
= np.linspace(0, 2, 100)
x
plt.plot(x, x)*x)
plt.plot(x, x
plt.plot(x, np.sqrt(x))
plt.grid()
It is handy to add a legend when there are multiple plots in the same figure. And we can use latex for math expressions.
= np.linspace(0, 2, 100)
x
="$y = x$")
plt.plot(x, x, label=r"$y = \sqrt{x}$")
plt.plot(x, np.sqrt(x), label*x, label="$y = x^2$")
plt.plot(x, x
plt.grid()
plt.legend()
# we can even give a title
# the semicolon at the end of last line is used to supress the output of that expression
"plot of $x$, $\sqrt{x}$ and $x^2$"); plt.title(
Note that we write the last label as r"$y = \sqrt{x}$"
. Notice the prefix r
before the string. That indicates that it is a raw string. In regular strings, the \
character has special meaning. For example \n
means a new line and \t
means a tab character.
If we write "$\theta$"
, python intereprets the \t
in it as a tab and matplotlib only sees "$<tab>heta$"
. To avoid that we use raw strings whenever we are writing math expressions that require using \
character.
Customizing ticks
= np.linspace(0, 360, 100)
x = np.sin(np.radians(x))
y
plt.plot(x, y) plt.grid()
We can customize the ticks.
= np.linspace(0, 360, 100)
x = np.sin(np.radians(x))
y
plt.plot(x, y)
plt.grid()
0, 90, 180, 270, 360]); plt.xticks([
We can even give custom labels to the ticks.
= np.linspace(0, 360, 100)
x = np.sin(np.radians(x))
y
plt.plot(x, y)
plt.grid()
0, 90, 180, 270, 360],
plt.xticks([r"$0$", r"$\frac{\pi}{2}$", r"$\pi$", r"$\frac{3\pi}{2}$", r"$2\pi$"])
[
# and even axis labels
r"$\theta$")
plt.xlabel(r"$\sin{\theta}$")
plt.ylabel(
# and title
r"$y = \sin{\theta}$"); plt.title(
Saving figures as images
Matplotlib allows exporting figures as images or pdf.
= np.linspace(0, 2, 100)
x
="$y = x$")
plt.plot(x, x, label=r"$y = \sqrt{x}$")
plt.plot(x, np.sqrt(x), label*x, label="$y = x^2$")
plt.plot(x, x
plt.grid()
plt.legend()
# we can even give a title
"plot of $x$, $\sqrt{x}$ and $x^2$")
plt.title(
"plots.png")
plt.savefig("plots.svg")
plt.savefig("plots.pdf")
plt.savefig(print("saved the figure as png, svg and pdf.")
saved the figure as png, svg and pdf.
Problem: Plot \(\sin{\theta}\) and \(\cos{\theta}\)
Plot \(\sin{\theta}\) and \(\cos{\theta}\) in the same figure with \(\theta\) going from \(0\) to \(2\pi\).
Please use x ticks in increments of \(\frac{\pi}{2}\) and include legend.
Subplots
For complex visualizations, we need to display multiple sub plots and it is easy to do with matplotlib.
= plt.subplots(1, 2)
fig, (ax0, ax1)
= np.linspace(0, 2, 100)
x
ax0.plot(x, x)"$y = x$")
ax0.set_title(
ax0.grid()
ax1.plot(x, np.sqrt(x))=r"$y = \sqrt{x}$")
ax1.set_title(label ax1.grid()
Please note that the y-axis scale is different for both the graphs. We can force the same scale using sharey=True
when creating subplots.
= plt.subplots(1, 2, sharey=True)
fig, (ax0, ax1)
= np.linspace(0, 2, 100)
x
ax0.plot(x, x)"$y = x$")
ax0.set_title(
ax0.grid()
ax1.plot(x, np.sqrt(x))=r"$y = \sqrt{x}$")
ax1.set_title(label ax1.grid()
# specify custom fig size
= plt.subplots(1, 2, sharey=True, figsize=(8, 4))
fig, (ax0, ax1)
= np.linspace(0, 2, 100)
x
ax0.plot(x, x)"$y = x$")
ax0.set_title(
ax0.grid()
ax1.plot(x, np.sqrt(x))=r"$y = \sqrt{x}$")
ax1.set_title(label ax1.grid()
We can do the same with two rows and one column. In that case, we can sharex instead of y.
# specify custom fig size
= plt.subplots(2, 1, sharex=True, figsize=(4, 8))
fig, (ax0, ax1)
= np.linspace(0, 2, 100)
x
ax0.plot(x, x)"$y = x$")
ax0.set_title(
ax0.grid()
ax1.plot(x, np.sqrt(x))=r"$y = \sqrt{x}$")
ax1.set_title(label ax1.grid()
We can even do a grid.
# specify custom fig size
= plt.subplots(2, 2, sharex=True, sharey=True, figsize=(8, 8))
fig, axs
def plot(ax, x, y, title):
ax.plot(x, y)
ax.set_title(title)
ax.grid()
= np.linspace(0, 2, 100)
x 0, 0], x, x, r"$y = x$")
plot(axs[0, 1], x, x*x, r"$y = x^2$")
plot(axs[1, 0], x, np.sqrt(x), r"$y = \sqrt{x}$")
plot(axs[1, 1], x, 2**x, r"$y = 2^x$")
plot(axs[
# set super title
"Exploring subplots"); plt.suptitle(
Problem: Plot \(\sin\) and \(\cos\) as subplots
Plot \(\sin{\theta}\) and \(\cos{\theta}\) as subplots with \(\theta\) going from \(0\) to \(2\pi\).
Please use x ticks in increments of \(\frac{\pi}{2}\) and include titles for the subplots.
Example: Lassajous Curves
Lassajous Curves are interesting mathematical curves that are generated using:
\(x = \sin{(at + \delta)}\)
\(y = \sin{(bt)}\)
def lassajous(a, b, delta):
= np.linspace(0, 2*np.pi, 1000)
t = np.sin(a*t+delta)
x = np.sin(b*t)
y
=(6, 6))
plt.figure(figsize
plt.plot(x, y)
plt.grid()
# show delta as a fraction of pi
= delta/np.pi
delta_fraction rf"$\delta={delta_fraction}\pi, a={a}, b={b}$") plt.title(
=1, b=1, delta=0) lassajous(a
=1, b=1, delta=np.pi/2) lassajous(a
=1, b=1, delta=np.pi/4) lassajous(a
=1, b=2, delta=np.pi/2) lassajous(a
Problem: Table of Lassajous curves
Plot the following lassajous curves using subplots. The row labels in the picture shows the ratio \(a:b\) and the column label shows the value of \(\delta\).
It may be tricky to set the row and column labels as shown in the image. Specfify the value of \(\delta, a, b\) for each subplot.