2. Visualization#
Visualizatin is vital in data analysis and scientific computing, to
get intuitive understanding
come up with a new hypothesis
detect a bug or data anormaly
That is why we’ll cover this topic at the beginning of this course.
Matplotlib#
Matplotlib is the standard graphics package for Python.
It mimics many graphics functions of MATLAB.
The Matplotlib gallery (http://matplotlib.org/stable/gallery) illustrates variety of plots.
Usually matplotlib opens a window for a new plot.
A nice feature of Jupyter notebook is that you can embed the figures produced by your program within the notebook by the following magic command
%matplotlib inline
(It may be a default setting in recent jupyter notebook).
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
Plotting functions#
The standard way is to prepare an array for x values, compute y values, and call plot( )
function.
# make an array from 0 to 10, the default is 50 points
x = np.linspace(0, 10)
# comupute a function for each point
y = x*np.sin(x)
# plot the points
plt.plot(y) # x is the index of y
[<matplotlib.lines.Line2D at 0x115a54680>]
![_images/b6dcee7526659b55f92dbaf8d1e980df2a3d4ed56f466db322ec1e12715f459b.png](_images/b6dcee7526659b55f92dbaf8d1e980df2a3d4ed56f466db322ec1e12715f459b.png)
There are multiple ways to pass variables to plot():
plot(y)
: x is assumed as the indices of yplot(x, y)
: specify both x and y valuesplot(x1, y1, x2, y2,...)
: multiple linesplot(x, Y)
: lines for columns of matrix Y
# specify both x and y values
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x115aa1010>]
![_images/f2c3cd2893d273e04fa79cb47382f8885484f6dc2ec8bcb7727f04ba4b5a655a.png](_images/f2c3cd2893d273e04fa79cb47382f8885484f6dc2ec8bcb7727f04ba4b5a655a.png)
# take another function of x
y2 = x*np.cos(x)
# plot two lines
plt.plot(x, y, x, y2)
[<matplotlib.lines.Line2D at 0x115b7c8f0>,
<matplotlib.lines.Line2D at 0x115b7c920>]
![_images/cc3e25a3ec148f3f582f9eb453455d02cd63426d8f626bad9d5a699ca866885c.png](_images/cc3e25a3ec148f3f582f9eb453455d02cd63426d8f626bad9d5a699ca866885c.png)
# phase plot
plt.plot(y, y2);
# you can supress <matplotlib...> output by ;
![_images/1b0a0698eef09f6203abab10b0ffd5cb5fb901379bf2665c27a6c48852340936.png](_images/1b0a0698eef09f6203abab10b0ffd5cb5fb901379bf2665c27a6c48852340936.png)
# plot multiple lines by a matrix
Y = np.array([y, y2]) # stack data in two rows
plt.plot(x, Y.T); # transpose to give data in two columns
![_images/cc3e25a3ec148f3f582f9eb453455d02cd63426d8f626bad9d5a699ca866885c.png](_images/cc3e25a3ec148f3f582f9eb453455d02cd63426d8f626bad9d5a699ca866885c.png)
# plot multiple lines by a matrix
Y = np.array([np.sin(k*x) for k in range(4)])
plt.plot(x, Y.T);
![_images/ba345399db57b587c2afe3c503312a2e87c2ca81ef72a8bf30e9c1c18dfbc81a.png](_images/ba345399db57b587c2afe3c503312a2e87c2ca81ef72a8bf30e9c1c18dfbc81a.png)
Options for plotting#
Line styles can be specified by
color=
(orc=
) for color by code, name, RGB or RGBAcode: ‘r’, ‘g’, ‘b’, ‘y’, ‘c’, ‘m’, ‘k’, ‘w’
marker=
for marker stylecode: ‘.’, ‘o’, ‘+’, ‘*’, ‘^’, …
linestyle=
(orls=
) for line stylecode: ‘-’, ‘–’, ‘:’, ‘-.’, …
linewidth=
(orlw=
) for line widtha string of color, marker and line sytel codes, e.g. ‘ro:’
# using code string
plt.plot(x, y, 'm:', x, y2, 'c*'); # magenta dash-dot, cyan circle
![_images/826d35732972722c6e80ae9c3a5f3e58a2ae855c9e5463a8b08bd4c5d5361363.png](_images/826d35732972722c6e80ae9c3a5f3e58a2ae855c9e5463a8b08bd4c5d5361363.png)
# using keyword=value
plt.plot(x, y, c=[0.2,0.5,0.8,0.5], marker='o', markersize=10, ls='-.', lw=2);
![_images/7d92f0594ef4c8e032d380ddd8cda3523917c1e3b6c2fe35b5cd093b65b0989b.png](_images/7d92f0594ef4c8e032d380ddd8cda3523917c1e3b6c2fe35b5cd093b65b0989b.png)
It’s a good practice to add axis lables and plot title.
plt.plot(x, y)
plt.title('oscillation')
plt.xlabel('time ($\mu s$)')
plt.ylabel('amplitude')
<>:3: SyntaxWarning: invalid escape sequence '\m'
<>:3: SyntaxWarning: invalid escape sequence '\m'
/var/folders/0z/3cttnw852b959kp4wjh_z_wc0000gn/T/ipykernel_51581/2066067687.py:3: SyntaxWarning: invalid escape sequence '\m'
plt.xlabel('time ($\mu s$)')
Text(0, 0.5, 'amplitude')
![_images/44b65f695b3bdc6ef6225d29ed13b7c625fc9dc1b70da769c877ecbc64b3b7c8.png](_images/44b65f695b3bdc6ef6225d29ed13b7c625fc9dc1b70da769c877ecbc64b3b7c8.png)
It is also nice to add a legend box.
ax = plt.plot(x, y, x, y2)
plt.legend(('x sin x','x cos x'))
<matplotlib.legend.Legend at 0x115c77e00>
![_images/e68de60a58d71c46dc10cde37a234c208046b4ca9a957e8174e036bbfba3c471.png](_images/e68de60a58d71c46dc10cde37a234c208046b4ca9a957e8174e036bbfba3c471.png)
You can control axis ranges and scaling.
plt.plot(x, y)
plt.xlim(-1, 5)
plt.ylim(-4, 4)
(-4.0, 4.0)
![_images/c47db4946a2fa8d0b8f8a0f82e98b382b48d3951b32590068b5044acd5dd3064.png](_images/c47db4946a2fa8d0b8f8a0f82e98b382b48d3951b32590068b5044acd5dd3064.png)
plt.plot(y, y2)
plt.axis('equal') # equal scaling for x and y
(-6.107980677841252, 8.582949839004911, -10.247801600732576, 7.121229063313089)
![_images/296efd853f3fd988a90dda9f446ec412c7c3f9975075c46fe7cec0a4cf5857af.png](_images/296efd853f3fd988a90dda9f446ec412c7c3f9975075c46fe7cec0a4cf5857af.png)
plt.plot(y, y2)
plt.axis('square') # in square plot area
(-6.107980677841252,
11.261049986204412,
-10.247801600732576,
7.121229063313088)
![_images/27122b8bb9af22ca729874ea15d17b048d3a63ac4f097c7a1a7613661db206af.png](_images/27122b8bb9af22ca729874ea15d17b048d3a63ac4f097c7a1a7613661db206af.png)
You can create a fiure of your preferred size by plt.figure()
function
fig = plt.figure(figsize=(6, 6))
plt.plot(y, y2)
[<matplotlib.lines.Line2D at 0x115f8dd30>]
![_images/b20555051806927c15317daaea3420580c1f9cc58eb43db8145e807a40c24667.png](_images/b20555051806927c15317daaea3420580c1f9cc58eb43db8145e807a40c24667.png)
Bar plot and histogram#
i = np.arange(10)
j = i**2
plt.bar(i, j)
<BarContainer object of 10 artists>
![_images/d13a3a44d89cac25123ffccb0154de7acec55c0321ace4c3cf1f4158c9b8d4da.png](_images/d13a3a44d89cac25123ffccb0154de7acec55c0321ace4c3cf1f4158c9b8d4da.png)
np.random.randn()
gives random numbers from the normal distribution
z = np.random.randn(100)
plt.hist(z)
(array([ 1., 2., 14., 13., 20., 26., 11., 8., 4., 1.]),
array([-2.53293677, -1.99641202, -1.45988728, -0.92336253, -0.38683778,
0.14968697, 0.68621172, 1.22273647, 1.75926122, 2.29578597,
2.83231072]),
<BarContainer object of 10 artists>)
![_images/1be40db579a9358c9d7498a51a65820b121b7527130ed77c63d47c706963776f.png](_images/1be40db579a9358c9d7498a51a65820b121b7527130ed77c63d47c706963776f.png)
Subplot and axes#
You can create multiple axes in a figure by subplot(rows, columns, index).
It uses a MATLAB legacy for index starting from 1.
plt.subplot(2, 2, 1)
plt.plot(x, y)
plt.subplot(2, 2, 2)
plt.plot(y, x)
plt.subplot(2, 2, 3)
plt.plot(x, y2)
plt.subplot(2, 2, 4)
plt.plot(y, y2)
[<matplotlib.lines.Line2D at 0x115d1d070>]
![_images/4f82110acb5b08c2fc622cbf67b83b5ed378be3dbbc0f26c6f5d3891df25d882.png](_images/4f82110acb5b08c2fc622cbf67b83b5ed378be3dbbc0f26c6f5d3891df25d882.png)
Figure and axes#
When you make a plot, matplotlib creates a figure object with an axes object.
You can use gcf()
and gca()
to identify them and getp()
and setp()
to access their parameters.
plt.plot(x, y)
fig = plt.gcf() # get current figure
plt.getp(fig) # show all parameters
agg_filter = None
alpha = None
animated = False
axes = [<Axes: >]
children = [<matplotlib.patches.Rectangle object at 0x115f265...
clip_box = None
clip_on = True
clip_path = None
constrained_layout = False
constrained_layout_pads = (None, None, None, None)
default_bbox_extra_artists = [<Axes: >, <matplotlib.spines.Spine object at 0x11...
dpi = 100.0
edgecolor = (1.0, 1.0, 1.0, 1.0)
facecolor = (1.0, 1.0, 1.0, 1.0)
figheight = 4.8
figure = Figure(640x480)
figwidth = 6.4
frameon = True
gid = None
in_layout = True
label =
layout_engine = None
linewidth = 0.0
mouseover = False
path_effects = []
picker = None
rasterized = False
size_inches = [6.4 4.8]
sketch_params = None
snap = None
suptitle =
supxlabel =
supylabel =
tight_layout = False
tightbbox = TransformedBbox( Bbox(x0=49.77777777777777, y0...
transform = IdentityTransform()
transformed_clip_path_and_affine = (None, None)
url = None
visible = True
window_extent = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=6.4, ...
zorder = 0
![_images/f2c3cd2893d273e04fa79cb47382f8885484f6dc2ec8bcb7727f04ba4b5a655a.png](_images/f2c3cd2893d273e04fa79cb47382f8885484f6dc2ec8bcb7727f04ba4b5a655a.png)
plt.plot(x, y)
fig = plt.gcf()
plt.setp(fig, size_inches=(8,4), facecolor=[0.5,0.5,0.5])
[None, None]
![_images/6acf0471d2d0f5ca0e0614b825e1d2788b863799681806457a757643c70fb7de.png](_images/6acf0471d2d0f5ca0e0614b825e1d2788b863799681806457a757643c70fb7de.png)
plt.plot(x, y)
ax = plt.gca() # get current axes
plt.getp(ax)
plt.setp(ax, facecolor='y') # change parameters
adjustable = box
agg_filter = None
alpha = None
anchor = C
animated = False
aspect = auto
autoscale_on = True
autoscalex_on = True
autoscaley_on = True
axes_locator = None
axisbelow = line
box_aspect = None
children = [<matplotlib.lines.Line2D object at 0x115c0b500>, ...
clip_box = None
clip_on = True
clip_path = None
data_ratio = 1.3355391378951056
default_bbox_extra_artists = [<matplotlib.spines.Spine object at 0x11611c0b0>, ...
facecolor or fc = (1.0, 1.0, 1.0, 1.0)
figure = Figure(640x480)
frame_on = True
gid = None
gridspec = GridSpec(1, 1)
images = <a list of 0 AxesImage objects>
in_layout = True
label =
legend = None
legend_handles_labels = ([], [])
lines = <a list of 1 Line2D objects>
mouseover = False
navigate = True
navigate_mode = None
path_effects = []
picker = None
position = Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=...
rasterization_zorder = None
rasterized = False
shared_x_axes = <matplotlib.cbook.GrouperView object at 0x115f6958...
shared_y_axes = <matplotlib.cbook.GrouperView object at 0x115f683e...
sketch_params = None
snap = None
subplotspec = GridSpec(1, 1)[0:1, 0:1]
tightbbox = Bbox(x0=49.77777777777777, y0=29.077777777777776, ...
title =
transform = IdentityTransform()
transformed_clip_path_and_affine = (None, None)
url = None
visible = True
window_extent = TransformedBbox( Bbox(x0=0.125, y0=0.109999999...
xaxis = XAxis(80.0,52.8)
xaxis_transform = BlendedGenericTransform( CompositeGenericTrans...
xbound = (-0.5, 10.5)
xgridlines = <a list of 8 Line2D gridline objects>
xlabel =
xlim = (-0.5, 10.5)
xmajorticklabels = [Text(-2.0, 0, '−2'), Text(0.0, 0, '0'), Text(2.0,...
xminorticklabels = []
xscale = linear
xticklabels = [Text(-2.0, 0, '−2'), Text(0.0, 0, '0'), Text(2.0,...
xticklines = <a list of 16 Line2D ticklines objects>
xticks = [-2. 0. 2. 4. 6. 8.]...
yaxis = YAxis(80.0,52.8)
yaxis_transform = BlendedGenericTransform( BboxTransformTo( ...
ybound = (-6.107980677841252, 8.582949839004911)
ygridlines = <a list of 10 Line2D gridline objects>
ylabel =
ylim = (-6.107980677841252, 8.582949839004911)
ymajorticklabels = [Text(0, -8.0, '−8'), Text(0, -6.0, '−6'), Text(0,...
yminorticklabels = []
yscale = linear
yticklabels = [Text(0, -8.0, '−8'), Text(0, -6.0, '−6'), Text(0,...
yticklines = <a list of 20 Line2D ticklines objects>
yticks = [-8. -6. -4. -2. 0. 2.]...
zorder = 0
[None]
![_images/9849dba0a1021e01c32838bfa3db2e2cf00bafffc3a15beecf0d949ec1ed5d46.png](_images/9849dba0a1021e01c32838bfa3db2e2cf00bafffc3a15beecf0d949ec1ed5d46.png)
Visualizing data in 2D#
A standard way for visualizing pariwise data is a scatter plot.
n = 100
x = np.random.uniform(-1, 1, n) # n points in [-1,1]
y = 2*x + np.random.randn(n) # scale and add noise
plt.plot(x, y, 'o')
[<matplotlib.lines.Line2D at 0x1160496d0>]
![_images/3cc96e22393480fc38eade30ee5b53a0d810a0a58bea37725f4bbbcf5cbddc58.png](_images/3cc96e22393480fc38eade30ee5b53a0d810a0a58bea37725f4bbbcf5cbddc58.png)
By scatterplot( )
you can specify the size and the color of each point to visualize higher dimension information.
z = x**2 + y**2
c = y - 2*x
# z for size, c for color
plt.scatter(x, y, z, c)
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x116189130>
![_images/034e7acff8245ecaa6a0c65977ae5c53fe9fdedb3fd65c99be7a17203bdc0462.png](_images/034e7acff8245ecaa6a0c65977ae5c53fe9fdedb3fd65c99be7a17203bdc0462.png)
Visualizing a matrix or a function in 2D space#
meshgrid() is for preparing x and y values in a grid.
x = np.linspace(-4, 4, 9)
y = np.linspace(-3, 3, 7)
print(x, y)
X, Y = np.meshgrid(x, y)
print(X, Y)
[-4. -3. -2. -1. 0. 1. 2. 3. 4.] [-3. -2. -1. 0. 1. 2. 3.]
[[-4. -3. -2. -1. 0. 1. 2. 3. 4.]
[-4. -3. -2. -1. 0. 1. 2. 3. 4.]
[-4. -3. -2. -1. 0. 1. 2. 3. 4.]
[-4. -3. -2. -1. 0. 1. 2. 3. 4.]
[-4. -3. -2. -1. 0. 1. 2. 3. 4.]
[-4. -3. -2. -1. 0. 1. 2. 3. 4.]
[-4. -3. -2. -1. 0. 1. 2. 3. 4.]] [[-3. -3. -3. -3. -3. -3. -3. -3. -3.]
[-2. -2. -2. -2. -2. -2. -2. -2. -2.]
[-1. -1. -1. -1. -1. -1. -1. -1. -1.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 2. 2. 2. 2. 2. 2. 2. 2. 2.]
[ 3. 3. 3. 3. 3. 3. 3. 3. 3.]]
We can use imshow() to visualize a matrix as an image.
Z = X**2 * Y
print(Z)
plt.imshow(Z)
[[-48. -27. -12. -3. -0. -3. -12. -27. -48.]
[-32. -18. -8. -2. -0. -2. -8. -18. -32.]
[-16. -9. -4. -1. -0. -1. -4. -9. -16.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 16. 9. 4. 1. 0. 1. 4. 9. 16.]
[ 32. 18. 8. 2. 0. 2. 8. 18. 32.]
[ 48. 27. 12. 3. 0. 3. 12. 27. 48.]]
<matplotlib.image.AxesImage at 0x11629d070>
![_images/2837c9b552291f5902c8c8b5f0c9393c0f27e94f23398a7e3741e1d3ff28fd65.png](_images/2837c9b552291f5902c8c8b5f0c9393c0f27e94f23398a7e3741e1d3ff28fd65.png)
# some more options
plt.imshow(Z, origin='lower', extent=(-4.5, 4.5, -3.5, 3.5))
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x116344a10>
![_images/01eb253f07e309acc8ae4fe5e7caa60f944bcb710520b0e820d089050bf841b2.png](_images/01eb253f07e309acc8ae4fe5e7caa60f944bcb710520b0e820d089050bf841b2.png)
color maps#
imshow( )
maps a scalar Z value to color by a colormap. The standard color map viridis is friedly to color blindness and monochrome printing. You can also choose other color maps.
plt.imshow(Z, cmap='jet')
<matplotlib.image.AxesImage at 0x116419fa0>
![_images/a68600ce6a613c75a3ab562e51d096a09292999c5ffb25b4502f2e6591f8df34.png](_images/a68600ce6a613c75a3ab562e51d096a09292999c5ffb25b4502f2e6591f8df34.png)
contour plot#
x = np.linspace(-4, 4, 25)
y = np.linspace(-4, 4, 25)
X, Y = np.meshgrid(x, y)
Z = X**2 + 2*Y**2
plt.contour(X, Y, Z)
plt.axis('square')
(-4.0, 4.0, -4.0, 4.0)
![_images/5cad26d3529b18947d75bbabd48661e44c4359aae6218ae3ac4e412c45405f08.png](_images/5cad26d3529b18947d75bbabd48661e44c4359aae6218ae3ac4e412c45405f08.png)
vector field by quiver( )
#
x = np.linspace(-3, 3, 15)
y = np.linspace(-3, 3, 15)
X, Y = np.meshgrid(x, y)
# Van del Pol model
k = 1 # paramter
U = Y # dx/dt
V = k*(1 - X**2)*Y - X # dy/dt
plt.quiver(X, Y, U, V)
<matplotlib.quiver.Quiver at 0x116419d30>
![_images/d253409e54b0df34d7629302dc4c7bfd503ca0afb4aeed7b53d58ff0112534ab.png](_images/d253409e54b0df34d7629302dc4c7bfd503ca0afb4aeed7b53d58ff0112534ab.png)