A quick introduction to plotting in Python
Matplotlib (MPL) is the default choice, with other options including Seaborn for high-level plotting, Plotly for JS plotting framework, Bokeh for interactive plotting.
Installation
Matplotlib is included in the Anaconda distribution.
Install it via condaif you have not (e.g. a miniconda distribution)
conda install matplotlibor by pip if you're not using conda at all.
pip install matplotlibReference
Matplotlib Tutorial – A Complete Guide to Python Plot w/ Examples
Matplotlib Tutorial: Learn the basics of Python’s powerful Plotting library
Conventional short names for matplotlib and numpy
import matplotlib.pyplot as pltimport numpy as np# For inline plotting in jupyter notebooks%matplotlib inline Anatomy of a figure (from mpl official website)

Line plots
Line plots are usually for visualization of 2D data e.g. time series (y-t) and phase plots (x-y)
plt.plot(x, y)# Data #x = np.linspace(0, 10, num=100)y1 = np.sin(x)y2 = np.cos(x)# Opens a new figure to be plottedplt.figure()# plot(x, y, <MATLAB stylestring>)plt.plot(x, y1, '-') plt.plot(x, y2, '--')# Save figure to diskfig.savefig('./plots/plt-fig1.png')Adding more options to the plot.
# Let's add some more options# Set figure (whole picture) size to 10 * 10plt.figure(figsize = (10, 10))# Add gridplt.grid() # Titleplt.title("Waves")# Lables for X & Y axesplt.xlabel("Time")plt.ylabel("Amplitude")# 'o-' does not mean orange line rather than circle dots# '^' means triangle dots# line labels are also setplt.plot(x, y1, '^-', label="Line1", color='orange') plt.plot(x, y2, 'b--', label="Line2")# Show the labelsplt.legend(loc='upper left')Multiple series
1 column = 1 series of data
# Data #x = np.linspace(0, 10, 100)# 4 columns of data = 4 series# y = sin(x + 0.5k * pi); k = 0, 1, 2, 3y = np.sin(x[:, np.newaxis] + np.pi * np.arange(0, 2, 0.5))y.shapeplt.figure()plt.plot(x, y)legend() to activate line labels
plt.figure()lines = plt.plot(x, y[:, 0:2])# Another way to set labelsplt.legend(lines, ['First', 'Second'], loc='upper right')More on
Tweaking Axis ticks
Logarithmic scale
plt.xscale('log')Hiding ticks From stack overflow
plt.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom=False, # ticks along the bottom edge are off top=False, # ticks along the top edge are off labelbottom=False) # labels along the bottom edge are offMore on: axes()
# Bode plot example# Define a transfer functiondef H(w): wc = 4000*np.pi return 1.0 / (1.0 + 1j * w / wc)freq = np.logspace(1,5) # frequencies from 10**1 to 10**5 Hzplt.figure()plt.plot(freq, 20*np.log10(abs(H(2*np.pi*freq))))plt.xscale('log')plt.xlabel('Frequency (Hz)')plt.ylabel('dB')plt.tick_params( axis='x', # changes apply to the x-axis which='both', # both major and minor ticks are affected bottom=False, # ticks along the bottom edge are off top=False, # ticks along the top edge are off labelbottom=False) # labels along the bottom edge are offMultiple subplots
# MATLAB style# subplot(rows, columns, panel number)plt.subplot(2, 1, 1)plt.plot(x, y1)# create the second panel and set current axisplt.subplot(2, 1, 2)plt.plot(x, y2)The usage of subplots (object-oriented way) is sometimes simpler.
fig, ax = plt.subplots(nrows, ncols, figsize=(n, m))# OO style (recommended)fig, ax = plt.subplots(2)# Plot for each axes (an unit in the figure)ax[0].plot(x, y1)ax[0].set_title("Upper panel")ax[1].plot(x, y2)ax[1].set_title("Lower panel")# Common titleplt.suptitle("Common title")Scatter plots
plt.plot(x, y)Ref: Python Data Science Handbook
# Using plot() functionplt.figure()x = np.linspace(0, 10)y1 = np.sin(x)plt.plot(x, y1, 'o', color='black')# Same as plt.scatter(x, y1, marker='o', color='black')Color map (cmap) and colorbar()
plt.scatter(x, y, c=colors)plt.colorbar()More on colormaps and colorbar
# Data #rng = np.random.RandomState(0)x = rng.randn(100)y = rng.randn(100)colors = rng.rand(100)sizes = 1000 * rng.rand(100)# Plot #plt.figure()# cmap for color mappingplt.scatter(x, y, c=colors, s=sizes, alpha=0.3, cmap='viridis')# show color scale barplt.colorbar()Error bar
plt.errorbar(x, y, yerr=dy, fmt='.k')More on errorbar
# Data #x = np.linspace(0, 10, 50) # Inputdy = 0.8 # Uncertainty levely = np.sin(x) + dy * np.random.randn(50) # Output with uncertainty# Plot #plt.figure()# xerr or yerr parameter to set error barsplt.errorbar(x, y, yerr=dy, fmt='.k')Contour plots
plt.contour(X, Y, Z)More on contour()
# data #def f(x, y): return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)x = np.linspace(0, 5, 50)y = np.linspace(0, 5, 40)X, Y = np.meshgrid(x, y)Z = f(X, Y)# plot #plt.figure()plt.contour(X, Y, Z)plt.figure()# Change color mapplt.contour(X, Y, Z, 20, cmap='RdGy')plt.figure()# contourf() for filled countor plotplt.contourf(X, Y, Z, 20, cmap='RdGy')plt.colorbar()plt.figure()contours = plt.contour(X, Y, Z, 3, colors='black')# Add labels of levels in the contour plotplt.clabel(contours, inline=True, fontsize=8)# Render image on the plot (faster but lower quality)plt.imshow(Z, extent=[0, 5, 0, 5], origin='lower', cmap='RdGy', alpha=0.5)plt.colorbar()More on imshow()
#### set_clim() to set limits on the values in the color barimport numpy as npimport matplotlib.pyplot as pltimport matplotlib as mpl# Data #x = np.linspace(0, 10, 1000) # 1000 * 1I = np.sin(x) * np.cos(x[:, np.newaxis]) # 1000 * 1000speckles = (np.random.random(I.shape) < 0.01)I[speckles] = np.random.normal(0, 3, np.count_nonzero(speckles))# Figure #fig, axs = plt.subplots(ncols=2, figsize=(10, 5))# Left subplotaxs[0].set_title('Without limit')im0 = axs[0].imshow(I, cmap='RdBu')cb0 = plt.colorbar(im0, ax=axs[0], orientation='horizontal')# Right subplotaxs[1].set_title('With limit')im1 = axs[1].imshow(I, cmap='RdBu')im1.set_clim(-1, 1)cb1 = plt.colorbar(im1, ax=axs[1], extend='both', orientation='horizontal')Plotting vector fields (quiver / streamplot plot)
Source: https://scipython.com/blog/visualizing-the-earths-magnetic-field/
More on: quiver(), streamplot()
Another example: https://stackoverflow.com/questions/25342072/computing-and-drawing-vector-fields
import sysimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib.patches import Circle# Mean magnitude of the Earth's magnetic field at the equator in TB0 = 3.12e-5# Radius of Earth, Mm (10^6 m: mega-metres!)RE = 6.370# Deviation of magnetic pole from axisalpha = np.radians(9.6)def B(r, theta): """Return the magnetic field vector at (r, theta).""" fac = B0 * (RE / r)**3 return -2 * fac * np.cos(theta + alpha), -fac * np.sin(theta + alpha)# Grid of x, y points on a Cartesian gridnx, ny = 64, 64XMAX, YMAX = 40, 40x = np.linspace(-XMAX, XMAX, nx)y = np.linspace(-YMAX, YMAX, ny)X, Y = np.meshgrid(x, y)r, theta = np.hypot(X, Y), np.arctan2(Y, X)# Magnetic field vector, B = (Ex, Ey), as separate componentsBr, Btheta = B(r, theta)# Transform to Cartesian coordinates: NB make North point up, not to the right.c, s = np.cos(np.pi/2 + theta), np.sin(np.pi/2 + theta)Bx = -Btheta * s + Br * cBy = Btheta * c + Br * sfig, ax = plt.subplots()# Plot the streamlines with an appropriate colormap and arrow stylecolor = 2 * np.log(np.hypot(Bx, By))ax.streamplot(x, y, Bx, By, color=color, linewidth=1, cmap=plt.cm.inferno, density=2, arrowstyle='->', arrowsize=1.5)# Add a filled circle for the Earth; make sure it's on top of the streamlines.ax.add_patch(Circle((0,0), RE, color='b', zorder=100))ax.set_xlabel('$x$')ax.set_ylabel('$y$')ax.set_xlim(-XMAX, XMAX)ax.set_ylim(-YMAX, YMAX)ax.set_aspect('equal')# Another vector field exampleimport numpy as npimport matplotlib.pyplot as plt# Set limits and number of points in gridy, x = np.mgrid[10:-10:100j, 10:-10:100j]x_obstacle, y_obstacle = 0.0, 0.0alpha_obstacle, a_obstacle, b_obstacle = 1.0, 1e3, 2e3p = -alpha_obstacle * np.exp(-((x - x_obstacle)**2 / a_obstacle + (y - y_obstacle)**2 / b_obstacle))# For the absolute values of "dx" and "dy" to mean anything, we'll need to# specify the "cellsize" of our grid. For purely visual purposes, though,# we could get away with just "dy, dx = np.gradient(p)".dy, dx = np.gradient(p)fig, ax = plt.subplots()ax.quiver(x, y, dx, dy, p)ax.set(aspect=1, title='Quiver Plot')# Quiver plot with less density (draw every 3rd point)skip = (slice(None, None, 3), slice(None, None, 3))fig, ax = plt.subplots()ax.quiver(x[skip], y[skip], dx[skip], dy[skip], p[skip])ax.set(aspect=1, title='Quiver Plot (3rd points)')# Streamplot with contour plotfig, ax = plt.subplots()ax.streamplot(x, y, dx, dy, color=p, density=0.5, cmap='gist_earth')cont = ax.contour(x, y, p, cmap='gist_earth')ax.clabel(cont)ax.set(aspect=1, title='Streamplot with contours')# Streamplot with stroke + contour plotfrom matplotlib.patheffects import withStrokefig, ax = plt.subplots()ax.streamplot(x, y, dx, dy, linewidth=500*np.hypot(dx, dy),color=p, density=1.2, cmap='gist_earth')cont = ax.contour(x, y, p, cmap='gist_earth', vmin=p.min(), vmax=p.max())labels = ax.clabel(cont)plt.setp(labels, path_effects=[withStroke(linewidth=8, foreground='w')])ax.set(aspect=1, title='Streamplot with contours and strokes')