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.
import numpy as np
import matplotlib.pyplot as plt
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
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 0x111774ec0>]
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 0x111813320>]
# take another function of x
y2 = x*np.cos(x)
# plot two lines
plt.plot(x, y, x, y2)
[<matplotlib.lines.Line2D at 0x1118e4e30>,
<matplotlib.lines.Line2D at 0x1118e4e60>]
# phase plot
plt.plot(y, y2);
# you can supress <matplotlib...> output by ;
# 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
# plot multiple lines by a matrix
Y = np.array([np.sin(k*x) for k in range(4)])
plt.plot(x, Y.T);
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
# using keyword=value
plt.plot(x, y, c=[0.2,0.5,0.8,0.5], marker='o', markersize=10, ls='-.', lw=2);
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')
Text(0, 0.5, 'amplitude')
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 0x111a25ca0>
You can control axis ranges and scaling.
plt.plot(x, y)
plt.xlim(-1, 5)
plt.ylim(-4, 4)
(-4.0, 4.0)
plt.plot(y, y2)
plt.axis('equal') # equal scaling for x and y
(-6.107980677841252, 8.582949839004911, -10.247801600732576, 7.121229063313089)
plt.plot(y, y2)
plt.axis('square') # in square plot area
(-6.107980677841252,
11.261049986204412,
-10.247801600732576,
7.121229063313088)
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 0x111cdfd10>]
Bar plot and histogram#
i = np.arange(10)
j = i**2
plt.bar(i, j)
<BarContainer object of 10 artists>
np.random.randn()
gives random numbers from the normal distribution
z = np.random.randn(500)
plt.hist(z)
(array([ 2., 15., 53., 76., 108., 109., 81., 28., 20., 8.]),
array([-2.91394416, -2.32460043, -1.73525671, -1.14591299, -0.55656926,
0.03277446, 0.62211818, 1.21146191, 1.80080563, 2.39014935,
2.97949308]),
<BarContainer object of 10 artists>)
plt.hist(z, bins=20)
(array([ 1., 1., 6., 9., 21., 32., 29., 47., 53., 55., 53., 56., 48.,
33., 18., 10., 11., 9., 5., 3.]),
array([-2.91394416, -2.6192723 , -2.32460043, -2.02992857, -1.73525671,
-1.44058485, -1.14591299, -0.85124113, -0.55656926, -0.2618974 ,
0.03277446, 0.32744632, 0.62211818, 0.91679005, 1.21146191,
1.50613377, 1.80080563, 2.09547749, 2.39014935, 2.68482122,
2.97949308]),
<BarContainer object of 20 artists>)
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.tight_layout()
adjusts the space between axes.
plt.subplot(2, 2, 1)
plt.plot(x, y)
plt.xlabel('x'); plt.ylabel('y')
plt.subplot(2, 2, 2)
plt.plot(y, x)
plt.xlabel('y'); plt.ylabel('x')
plt.subplot(2, 2, 3)
plt.plot(x, y2)
plt.xlabel('x'); plt.ylabel('y2')
plt.subplot(2, 2, 4)
plt.plot(y, y2)
plt.xlabel('y'); plt.ylabel('y2')
plt.tight_layout()
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 0x111940d...
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
plt.plot(x, y)
fig = plt.gcf()
plt.setp(fig, size_inches=(8,4), facecolor=[0.5,0.5,0.5])
[None, None]
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 0x111f48d70>, ...
clip_box = None
clip_on = True
clip_path = None
data_ratio = 1.3355391378951056
default_bbox_extra_artists = [<matplotlib.spines.Spine object at 0x111f18ad0>, ...
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 0x111ee05c...
shared_y_axes = <matplotlib.cbook.GrouperView object at 0x111ee2bd...
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]
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 0x111fb8b00>]
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 0x111d54ce0>
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 0x1120c40e0>
# some more options
plt.imshow(Z, origin='lower', extent=(-4.5, 4.5, -3.5, 3.5))
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x111992540>
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 0x1121c6270>
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)
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 0x111bf4e60>
Saving the image#
You can save a plot as a .png
file by right-clicking it and choosing a pop-up menu like “save image as …” by the browser.
You can use plt.savefig()
function to save it in other formats.
plt.quiver(X, Y, U, V)
plt.title('Van der Pol model')
plt.xlabel('u')
plt.ylabel('v')
plt.axis('square')
plt.savefig('VdP.pdf')
!open VdP.pdf