import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as stats
6 Graphics
6.1 Introduction
In this chapter, we introduce two modules for graphics: matplotlib
and seaborn
. Matplotlib offers two primary approaches for creating figures: (i) the MATLAB-style (or pyplot) approach, and (ii) the object-oriented programming (OOP) approach. The MATLAB-style tools are contained in the pyplot
(plt
) interface. For plot styles and color defaults, we rely on the seaborn
module.
6.2 Setting plotting styles
The theme of a figure refers to the overall appearance, including colors, fonts, and line styles. We use the seaborn
module to set the theme of our figures. The are five preset seaborn themes: darkgrid
, whitegrid
, dark
, white
, and ticks
. The sns.set_style()
function can be used to set these themes. The default theme is darkgrid
. For more information, see Controlling figure aesthetics from the documentation.
# Setting seaborn style
#sns.set_style('whitegrid')
#sns.set_style('dark')
#sns.set_style('white')
#sns.set_style('ticks')
'darkgrid') sns.set_style(
The plt.style.available()
function lists all available styles in Matplotlib.
# List available styles
plt.style.available
['Solarize_Light2',
'_classic_test_patch',
'_mpl-gallery',
'_mpl-gallery-nogrid',
'bmh',
'classic',
'dark_background',
'fast',
'fivethirtyeight',
'ggplot',
'grayscale',
'seaborn-v0_8',
'seaborn-v0_8-bright',
'seaborn-v0_8-colorblind',
'seaborn-v0_8-dark',
'seaborn-v0_8-dark-palette',
'seaborn-v0_8-darkgrid',
'seaborn-v0_8-deep',
'seaborn-v0_8-muted',
'seaborn-v0_8-notebook',
'seaborn-v0_8-paper',
'seaborn-v0_8-pastel',
'seaborn-v0_8-poster',
'seaborn-v0_8-talk',
'seaborn-v0_8-ticks',
'seaborn-v0_8-white',
'seaborn-v0_8-whitegrid',
'tableau-colorblind10']
Alternatively, we can set the darkgrid
style using the plt.style.use()
function. In the following example (Figure 6.1), we first create a figure using plt.figure(figsize=(5, 5))
, which sets the size of the figure area to 5x5 inches. In Matplotlib, plots are contained within a Figure
. We then set the plotting style with plt.style.use('seaborn-v0_8-darkgrid')
and display the plot using plt.plot()
.
=(5,4)) # set figure size to 5x5 inches
plt.figure(figsize'seaborn-v0_8-darkgrid')
plt.style.use(
plt.plot() plt.show()

seaborn-v0_8-darkgrid
style
6.3 MATLAB Style Approach
6.3.1 Line plots
In the MATLAB-style approach, we use the plt.plot()
function to create line plots. The plt.plot()
function can be used to create a wide variety of line plots, including simple line plots, line plots with markers, and line plots with different styles. The plt.plot()
function can also be used to add multiple lines to a single figure. The following code chunk generates the line plots shown in Figure 6.2.
# Data
12345)
np.random.seed(= np.random.randn(20)
y = np.cumsum(np.random.rand(20)) x
# Line Plot 1
=(4,4))
plt.figure(figsize
plt.plot(y)
plt.show()# Line Plot 2
=(4,4))
plt.figure(figsize'r-o', label = 'Line Plot 2')
plt.plot(y,
plt.legend()'x label')
plt.xlabel('Line Plot 2')
plt.title('y label')
plt.ylabel(
plt.show()# Line Plot 3
=(4,4))
plt.figure(figsize'b-d', label = 'Line Plot 3')
plt.plot(x, y,
plt.legend()'x label')
plt.xlabel('Line Plot 3')
plt.title('y label')
plt.ylabel(
plt.show()# Line Plot 4
=(4,4))
plt.figure(figsize= "-", color = 'steelblue', label = 'Line Plot 4')
plt.plot(x, y, linestyle
plt.legend()'x label')
plt.xlabel('Line Plot 4')
plt.title('y label')
plt.ylabel( plt.show()




Some options used to customize the appearance of axes and lines are described in the following list:
- In Figure 6.2 (b),
r-o
indicates the color red (r), a solid line (-), and a circle (o) marker. - In Figure 6.2 (c),
b-d
indicates the color blue (b), a solid line (-), and a diamond (d) marker. - In Figure 6.2 (d), the line style and color are specified using
linestyle = "-"
andcolor='steelblue'
. - Titles are added with
plt.title()
, and legends are added usingplt.legend()
. The legend requires that the line includes a label. - Labels for the x- and y-axes are added using
plt.xlabel()
andplt.ylabel()
.
In the following example, we specify the arguments of the plt.plot()
function explicitly.
# Specify arguments
=(5,4))
plt.figure(figsize
plt.plot(x, y,= 1,
alpha = "#FF7F00",
color = "Line Label",
label = "-",
linestyle = 2,
linewidth = "o",
marker = "#000000",
markeredgecolor = 1,
markeredgewidth = "#FF7F99",
markerfacecolor = 5,
markersize
)
plt.legend()"x label")
plt.xlabel("A line plot")
plt.title("y label")
plt.ylabel( plt.show()

The most useful arguments of the plt.plot()
function are listed below:
alpha
: Alpha (transparency) of the plot- default is 1 (no transparency)color
: Color description for the line. It can be specified in several ways, including:- Color name (e.g.,
'red'
,'steelblue'
,'green'
) - Short color code (e.g.,
'r'
,'g'
,'b'
) - Grayscale value (e.g.,
'0.5'
for gray) - Hexadecimal code (e.g.,
'#FF0000'
for red) - RGB tuple (e.g.,
(1.0, 0.0, 0.0)
for red) - HTML color names (e.g.,
'DarkMagenta'
)
- Color name (e.g.,
label
: A label for the line, used in the legendlinestyle
: A line style symbollinewidth
: A positive integer indicating the width of the linemarker
: A marker shape symbol or charactermarkeredgecolor
: Color of the edge (a line) around the markermarkeredgewidth
: Width of the edge (a line) around the markermarkerfacecolor
: Face color of the markermarkersize
: A positive integer indicating the size of the marker
Some commonly used options for color
, linestyle
and marker
are shown in Table 6.1. For more information, see Colors, Linestyles and Marker reference from the documentation.
color | linestyle | marker |
---|---|---|
blue: b |
solid: - |
point: . |
green: g |
dashed: -- |
pixel: , |
red: r |
dashdot: -. |
circle: o |
cyan: c |
dotted: : |
square: s |
magenta: m |
diamond: D |
|
yellow: y |
thin diamond: d |
|
black: k |
cross: x |
|
white: w |
plus: + |
|
star: * |
||
pentagon: p |
||
triangles: ^,v,<,> |
The following code chunk, which generates Figure 6.4, shows alternative ways to specify color
.
# Alternative way to specify color
= np.linspace(0, 2, 500)
x =(5,4))
plt.figure(figsize+ 0.2), color='steelblue') # specify color by name
plt.plot(x, np.exp(x - 0.1), color='g') # short color code (rgbcmyk)
plt.plot(x, np.exp(x - 0.4), color='0.2') # grayscale between 0 and 1
plt.plot(x, np.exp(x - 0.6), color='#04fa25') # hex code (RRGGBB from 00 to FF)
plt.plot(x, np.exp(x - 0.8), color=(1.0,0.2,0.3)) # RGB tuple, values 0 and 1
plt.plot(x, np.exp(x - 1), color='DarkMagenta'); # all HTML color names supported
plt.plot(x, np.exp(x 'x')
plt.xlabel('Exponential function')
plt.ylabel( plt.show()

color
options
In Figure 6.4, we have a single figure with multiple line plots. Thus, to add multiple lines to a single figure, we need to call the plt.plot()
function multiple times.
The following code chunk, which generates Figure 6.5, provide alternative ways for specifying the linestyle
options.
# Alternative way to specify linestyle
= np.linspace(0, 5, 500)
x =(5,4))
plt.figure(figsize+ 0.1), linestyle='solid', linewidth=2)
plt.plot(x, np.log(x + 0.6), linestyle='dashed', linewidth=2)
plt.plot(x, np.log(x + 1), linestyle='dashdot', linewidth=2)
plt.plot(x, np.log(x + 1.5), linestyle='dotted', linewidth=2)
plt.plot(x, np.log(x 0, color="k", linestyle="-", linewidth=1, alpha=0.5)
plt.axhline('x')
plt.xlabel('Natural logarithm')
plt.ylabel( plt.show()

linestyle
options
The plt.setp()
function can be used to set options for plot elements, as shown in the following example (Figure 6.6):
45)
np.random.seed(= np.random.randn(10)
x =(5,4))
plt.figure(figsize= plt.plot(x)
h
plt.setp(h,=1,
alpha="--",
linestyle=1.5,
linewidth="Line Label",
label="d",
marker="red",
color="black",
markeredgecolor="green",
markerfacecolor=5
markersize
)0, color="k", linestyle="-",linewidth=1, alpha=0.5)
plt.axhline(
plt.legend()"x label")
plt.xlabel("y label")
plt.ylabel( plt.show()

plt.setp()
function
The plt.getp()
function retrieves the list of properties for a Matplotlib object:
plt.getp(h)
agg_filter = None
alpha = 1
animated = False
antialiased or aa = True
bbox = Bbox(x0=0.0, y0=-2.596878630257014, x1=9.0, y1=0.9...
children = []
clip_box = TransformedBbox( Bbox(x0=0.0, y0=0.0, x1=1.0, ...
clip_on = True
clip_path = None
color or c = red
dash_capstyle = butt
dash_joinstyle = round
data = (array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]), ...
drawstyle or ds = default
figure = Figure(480x384)
fillstyle = full
gapcolor = None
gid = None
in_layout = True
label = Line Label
linestyle or ls = --
linewidth or lw = 1.5
marker = d
markeredgecolor or mec = black
markeredgewidth or mew = 1.0
markerfacecolor or mfc = green
markerfacecoloralt or mfcalt = none
markersize or ms = 5.0
markevery = None
mouseover = False
path = Path(array([[ 0. , 0.02637477], [ 1...
path_effects = []
picker = None
pickradius = 5
rasterized = False
sketch_params = None
snap = None
solid_capstyle = round
solid_joinstyle = round
tightbbox = Bbox(x0=73.57575757575758, y0=52.34666666666667, x...
transform = CompositeGenericTransform( TransformWrapper( ...
transformed_clip_path_and_affine = (None, None)
url = None
visible = True
window_extent = Bbox(x0=73.57575757575758, y0=52.34666666666667, x...
xdata = [0. 1. 2. 3. 4. 5.]...
xydata = [[ 0. 0.02637477] [ 1. 0.260321...
ydata = [ 0.02637477 0.2603217 -0.39514554 -0.20430091 -...
zorder = 2
The plt.xlim()
and plt.ylim()
can be used to set axes limits, as illustrated in the following examples.
= np.linspace(0, 10, 1000)
x =(5,4))
plt.figure(figsize
plt.plot(x, np.cos(x))0, color="k", linestyle="-", linewidth=1, alpha=0.5)
plt.axhline(-1, 12)
plt.xlim(-1.5, 1.5)
plt.ylim('x')
plt.xlabel('Cosine function')
plt.ylabel( plt.show()

plt.xlim()
and plt.ylim()
functions
# Setting x and y limits with plt.axis()
=(5,4))
plt.figure(figsize
plt.plot(x, np.cos(x))-1, 12, -1.5, 1.5]) # specify [xmin,xmax,ymin,ymax]
plt.axis(['x')
plt.xlabel('Cosine function')
plt.ylabel( plt.show()

plt.axis()
function
6.3.2 Scatter plots
Scatter plots can be generated using the plt.scatter()
function or the plt.plot()
function with the option linestyle=""
. Consider the following example, which generates Figure 6.9.
# Scatter plots using plt.scatter()
45)
np.random.seed(= np.random.randn(100, 2)
z 1] = 0.5 * z[:, 0] + np.sqrt(0.5) * z[:, 1]
z[:, = z[:, 0]
x = z[:, 1]
y =(5,4))
plt.figure(figsize="steelblue", marker="o", alpha=1, s = 25, label="Scatter Data")
plt.scatter(x, y, c"x", fontsize=12)
plt.xlabel("y", fontsize=12)
plt.ylabel("A scatter plot", fontsize=14)
plt.title( plt.show()

plt.scatter()
Alternatively, we can use the plt.plot()
function with the option linestyle=""
as shown in the following example.
# Scatter plot using plt.plot()
=(5,4))
plt.figure(figsize="", c="steelblue", marker="o", ms=5,
plt.plot(x, y, linestyle=1, label="Scatter Data")
alpha"x", fontsize=12)
plt.xlabel("y", fontsize=12)
plt.ylabel( plt.show()

plt.plot()
6.3.3 Bar plots
The plt.bar()
function is used to create bar plots. The following code chunk generates the bar plots shown in Figure 6.11 and Figure 6.12.
123)
np.random.seed(= np.random.rand(5)
y = np.arange(5)
x =(5,4))
plt.figure(figsize= plt.bar(x, y, width = 1, color = 'steelblue',
b = 'black', linewidth = 0.5)
edgecolor "Bar Plot")
plt.title("x label")
plt.xlabel("y label")
plt.ylabel( plt.show()

plt.bar()
45)
np.random.seed(= np.random.rand(5)
y = ["G1", "G2", "G3", "G4", "G5"]
x =(5,4))
plt.figure(figsize= plt.bar(x,y, width = 1, color = 'steelblue',
b = 'black', linewidth = 0.5)
edgecolor "Bar Plot")
plt.title( plt.show()

plt.bar()
In the following example, we generate a horizontal bar plot using the plt.barh()
function.
# Horizontal Bar plot using plt.barh()
45)
np.random.seed(= np.random.rand(5)
y = ["G1", "G2","G3","G4","G5"]
x =(5,4))
plt.figure(figsize= plt.barh(x,y, height = 0.5, color = 'steelblue',
b = 'black', linewidth = 0.5)
edgecolor "Horizontal Bar Plot")
plt.title( plt.show()

plt.barh()
6.3.4 Pie plots
The plt.pie()
function is used to create pie plots. The following code chunk generates the pie plot shown in Figure 6.14.
# Pie plot using plt.pie()
45)
np.random.seed(= np.random.rand(5)
y = y / sum(y)
y <.05] = .05
y[y= ['One','Two','Three','Four','Five']
labels = ['#FF00FF','#FFF000','#00FF0F','#00FFF0','#00000F']
colors = np.array([0.1,0,0,0.1,0])
explode =(5,5))
plt.figure(figsize=labels,colors=colors,shadow=True,explode=explode)
plt.pie(y,labels plt.show()

plt.pie()
6.3.5 Histograms
We can use the plt.hist()
function to generate histograms. In the following example, the histtype
option assumes the following options: bar
, barstacked
, step
, and stepfilled
.
# Histograms using plt.hist()
45)
np.random.seed(= np.random.randn(1000)
x =(5,4))
plt.figure(figsize= 30, density=True, color='steelblue',
plt.hist(x, bins ="bar", edgecolor='black', linewidth=0.5)
histtype'x')
plt.xlabel('Density')
plt.ylabel( plt.show()

plt.hist()
In the following example, we show how to add multiple plots to the same axes. The first plot is a histogram, and the second plot is the probability density function (PDF) of the normal distribution.
# Multiple Plots on the Same Axes
45)
np.random.seed(= stats.norm.rvs(loc=2, scale=1.5, size=1000)
x =(5,4))
plt.figure(figsize= 30, density=True, label = 'Empirical')
plt.hist(x, bins = np.linspace(x.min(), x.max(), 1000)
pdfx = stats.norm.pdf(pdfx, loc=2, scale=1.5)
pdfy 'r-', label = 'PDF')
plt.plot(pdfx, pdfy,'x')
plt.xlabel('Density')
plt.ylabel(
plt.legend() plt.show()

6.3.6 Kernel Density and Empirical CDF plots
The sns.kdeplot()
function from the seaborn
module can be used to create a kernel density plot. The kernel density estimate is a non-parametric way to estimate the probability density function of a random variable. In the following example, we generate random draws from a t-distribution and a normal distribution, and then plot their kernel density estimates. The fill=True
option fills the area under the curve, and the alpha
option sets the transparency of the fill color.
# Kernel Density Plot
45)
np.random.seed(= stats.t.rvs(df=3, loc=0, scale=1, size=1000)
x = np.random.randn(1000)
y
=(5, 4))
plt.figure(figsize='steelblue', fill=True, alpha=0.5, linewidth=1, label='t-distribution')
sns.kdeplot(x, color='orange', fill=True, alpha=0.5, linewidth=1, label='Normal distribution')
sns.kdeplot(y, color'x')
plt.xlabel(-6, 6)
plt.xlim('Density')
plt.ylabel('Kernel Density Plots')
plt.title(
plt.legend()
plt.tight_layout() plt.show()

The empirical cumulative distribution function (CDF) can be plotted using the sns.ecdfplot()
function from the seaborn
module. The empirical CDF is a step function that estimates the cumulative distribution function of a random variable based on a sample. In the following example, we generate random draws from a t-distribution and a normal distribution, and then plot their empirical CDFs.
# Empirical CDF plot
45)
np.random.seed(= np.random.randn(1000)
x = stats.t.rvs(df=3, loc=0, scale=1, size=1000)
y
=(5, 4))
plt.figure(figsize=x, color='steelblue', linewidth=1, label='Normal distribution')
sns.ecdfplot(x=y, color='orange', linewidth=1, label='t-distribution')
sns.ecdfplot(x'x', fontsize=12)
plt.xlabel(-6, 6)
plt.xlim(0, 1.05)
plt.ylim('Cumulative Probability', fontsize=12)
plt.ylabel('Empirical CDF', fontsize=14)
plt.title(
plt.legend()
plt.tight_layout() plt.show()

6.3.7 Multiple plots on the same figure
To add subplots to a figure, we can use the plt.subplot()
function. In the example below, we use plt.subplot(2, 2, p)
to divide the figure area into a 2x2 grid, where p
indicates the position of the subplot within the grid.
=(7,7))
plt.figure(figsize45)
np.random.seed(
# Panel 1
2, 2, 1)
plt.subplot(= np.random.randn(100)
y1
plt.plot(y1)'Plot 1')
plt.title(
# Panel 2
2, 2, 2)
plt.subplot(= np.random.rand(5)
y2 = np.arange(5)
x2 ='Bar Chart', color='steelblue', edgecolor='black', linewidth=0.5)
plt.bar(x2, y2, label
plt.legend()'x label')
plt.xlabel('y label')
plt.ylabel('Plot 2')
plt.title(
# Panel 3
2, 2, 3)
plt.subplot(= np.random.rand(5)
y3 = y3 / y3.sum()
y3 < 0.05] = 0.05
y3[y3 = ['A', 'B', 'C', 'D', 'E']
labels = ['#FF00FF','#FFF000','#00FF0F','#00FFF0','#F0000F']
colors =labels, colors=colors, autopct='%1.1f%%', startangle=90)
plt.pie(y3, labels'Plot 3')
plt.title(
# Panel 4
2, 2, 4)
plt.subplot(= np.random.randn(100, 2)
z 1] = 0.5 * z[:,0] + np.sqrt(0.5) * z[:,1]
z[:,= z[:,0]
x4 = z[:,1]
y4 =20, color='steelblue', alpha=0.8, edgecolor='black')
plt.scatter(x4, y4, s'Plot 4')
plt.title('x values')
plt.xlabel('y values')
plt.ylabel(
# Padding
=0.5, wspace=0.5)
plt.subplots_adjust(hspace
plt.tight_layout() plt.show()

plt.subplot()
function
The padding between subplots can be adjusted using the plt.subplots_adjust()
function. In Figure 6.19, we use plt.subplots_adjust(hspace=0.5, wspace=0.5)
to add horizontal and vertical spacing between subplots.
6.3.8 Saving figures
The plt.savefig()
function allows user to save figures in a wide variety of formats. The supported formats can be listed using the canvas.get_supported_filetypes
method of the figure object, as shown below:
# The supported file types
= plt.figure()
fig fig.canvas.get_supported_filetypes()
{'eps': 'Encapsulated Postscript',
'jpg': 'Joint Photographic Experts Group',
'jpeg': 'Joint Photographic Experts Group',
'pdf': 'Portable Document Format',
'pgf': 'PGF code for LaTeX',
'png': 'Portable Network Graphics',
'ps': 'Postscript',
'raw': 'Raw RGBA bitmap',
'rgba': 'Raw RGBA bitmap',
'svg': 'Scalable Vector Graphics',
'svgz': 'Scalable Vector Graphics',
'tif': 'Tagged Image File Format',
'tiff': 'Tagged Image File Format',
'webp': 'WebP Image Format'}
<Figure size 672x480 with 0 Axes>
In the following example, we show how to save a figure in PDF, PNG, and SVG formats. The dpi
option can be used to specify the resolution of the image in dots per inch (DPI). A higher DPI value results in a higher resolution image. The default DPI value is 100.
# Exporting plots
45)
np.random.seed(=(5, 4))
plt.figure(figsize10,2))
plt.plot(np.random.randn(# plt.savefig('figures/Myfigure.pdf') # PDF export
# plt.savefig('figures/Myfigure.png') # PNG export
# plt.savefig('figures/Myfigure.svg') # Scalable Vector Graphics export
# plt.savefig('figures/Myfigure2.png', dpi = 600) # High resolution PNG export
plt.show()

plt.savefig()
6.4 OOP Approach
The object-oriented interface in Matplotlib offers greater control over figures. In this approach, plotting functions are methods associated with explicit Figure and Axes objects. To create a plot, we begin by initializing a Figure object and an Axes object. The Figure object, referred to as fig
, can be created as follows:
# Create fig object
= plt.figure(figsize=(5, 4))
fig type(fig)
matplotlib.figure.Figure
<Figure size 480x384 with 0 Axes>
The fig
object (an instance of the plt.figure.Figure
class) serves as a container that holds all components, including axes, graphics, text, and labels. The Axes object, referred to as ax
, can be created as follows:
# Create ax object
= plt.figure(figsize=(5, 4))
fig = plt.axes()
ax type(ax)
matplotlib.axes._axes.Axes
The ax
(an instance of the plt.axes._axes.Axes
class) object represents the box that contains the plot elements making up the visualization.
6.4.1 Line plots
In the OOP approach, we can create line plots using the ax.plot()
function. The ax.plot()
function is similar to the plt.plot()
function, but it is called on the ax
object instead of the plt
module. In the following example, we generate a line plot of the sine function using the ax.plot()
function. The ax.axhline()
function is used to add a horizontal line at \(y=0\).
= plt.figure(figsize=(5, 3))
fig = plt.axes()
ax = np.linspace(0, 10, 1000)
x ='r')
ax.plot(x,np.sin(x),color# Add a horizontal line at y=0
0, color='k', linestyle='-', linewidth=1, alpha=0.5)
ax.axhline( plt.show()

ax.plot()
function
Note that in Figure 6.21, the ax.plot()
function serves the same purpose as the plt.plot()
function. While most plt
functions translate directly to ax
methods (such as plt.plot()
\(\rightarrow\) ax.plot()
, and plt.legend()
\(\rightarrow\) ax.legend()
), this is not the case for all commands. Below, we give some commonly used translations.
plt.plot()
\(\rightarrow\)ax.plot()
plt.legend()
\(\rightarrow\)ax.legend()
plt.xlabel()
\(\rightarrow\)ax.set_xlabel()
plt.ylabel()
\(\rightarrow\)ax.set_ylabel()
plt.xlim()
\(\rightarrow\)ax.set_xlim()
plt.ylim()
\(\rightarrow\)ax.set_ylim()
plt.title()
\(\rightarrow\)ax.set_title
plt.subplot()
\(\rightarrow\)ax.fig.add_subplot()
plt.hline()
\(\rightarrow\)ax.axhline()
plt.vline()
\(\rightarrow\)ax.axvline()
plt.text()
\(\rightarrow\)ax.text()
plt.annotate()
\(\rightarrow\)ax.annotate()
plt.grid()
\(\rightarrow\)ax.grid()
plt.subplots()
\(\rightarrow\)fig, ax = plt.subplots()
plt.show()
\(\rightarrow\)plt.show()
(remains unchanged)plt.savefig()
\(\rightarrow\)fig.savefig()
In the following example, we generate a line plot of the sine function using the ax.plot()
function. The ax.set_title()
, ax.set_xlabel()
, and ax.set_ylabel()
functions are used to set the title and labels of the axes. The ax.set_xlim()
and ax.set_ylim()
functions are used to set the limits of the x- and y-axes, respectively. Finally, we add a legend using the ax.legend()
function.
= np.linspace(0, 10, 1000)
x = plt.figure(figsize=(5, 3))
fig = plt.axes()
ax ='steelblue', label='sin(x)')
ax.plot(x, np.sin(x), color0, color='k', linestyle='-', linewidth=1, alpha=0.5)
ax.axhline('The sine function')
ax.set_title('x')
ax.set_xlabel('sin(x)')
ax.set_ylabel(0,10)
ax.set_xlim(-2,2)
ax.set_ylim(
ax.legend() plt.show()

ax.plot()
function
In the OOP approach, rather than calling ax
methods individually, it is often more convenient to use the ax.set()
function as shown in the next examples. In this example r'$\sin(x)$'
and r'$\cos(x)$'
are used to render the sine and cosine functions in LaTeX format. The r
before the string indicates that it is a raw string, which allows us to use LaTeX commands without escaping them.
= np.linspace(0, 10, 1000)
x = plt.figure(figsize=(5, 3))
fig = plt.axes()
ax ='steelblue', label=r'$\sin(x)$', linewidth=1)
ax.plot(x, np.sin(x), color='orange', label=r'$\cos(x)$', linewidth=1)
ax.plot(x, np.cos(x), color0, color='k', linestyle='-', linewidth=1, alpha=0.5)
ax.axhline(set(
ax.=(0, 10),
xlim=(-1.2, 1.2),
ylim='x',
xlabel=r"$\sin(x)$ and $\cos(x)$",
ylabel="Sine and cosine functions"
title
)='upper right', frameon=False)
ax.legend(loc
fig.tight_layout() plt.show()

ax.set()
function
In the above examples, we create the fig
and ax
objects separately using fig = plt.figure()
and ax = plt.axes()
. Alternatively, we can generate both objects with a single command by using the plt.subplots()
function. Consider the following example:
# Improved version: clearer labels, LaTeX formatting, grid, and tight layout
= np.linspace(0, 10, 1000)
x = plt.subplots(figsize=(5, 3))
fig, ax =r'$\sin(x)$', color='steelblue', linewidth=1)
ax.plot(x, np.sin(x), label=r'$\cos(x)$', color='orange', linewidth=1)
ax.plot(x, np.cos(x), label0, color='k', linestyle='-', linewidth=1, alpha=0.5)
ax.axhline(set(
ax.=(0, 10),
xlim=(-1.2, 1.2),
ylim='x',
xlabel='Value',
ylabel='Sine and Cosine Functions'
title
)='upper right', frameon=True)
ax.legend(loc
fig.tight_layout() plt.show()

plt.subplots()
function
6.4.2 Scatter plots
Scatter plots can be generated using the ax.scatter()
function or the ax.plot()
function with the option linestyle=""
. The following example generates a scatter plot using the ax.scatter()
function.
# Scatter plot using ax.scatter()
45)
np.random.seed(= plt.figure(figsize=(5, 4))
fig = plt.axes()
ax = np.random.randn(100,2)
z 1] = 0.5*z[:,0] + np.sqrt(0.5)*z[:,1]
z[:,= z[:,0]
x = z[:,1]
y ='steelblue', s=25)
ax.scatter(x, y, color'x')
ax.set_xlabel('y')
ax.set_ylabel( plt.show()

ax.scatter()
In the following example, we generate a scatter plot using the ax.plot()
function with the option linestyle=""
.
# Scatter plot using ax.plot()
= plt.subplots(figsize=(5, 4))
fig, ax ='', marker='o', ms=5, color='steelblue', alpha=0.8, label="Data points")
ax.plot(x, y, linestyle'x', fontsize=12)
ax.set_xlabel('y', fontsize=12)
ax.set_ylabel(# ax.set_title('Scatter plot using ax.plot()', fontsize=14)
# ax.legend()
True, linestyle='--', alpha=0.5)
ax.grid(
plt.tight_layout() plt.show()

ax.plot()
6.4.3 Bar plots
Bar plots can be generated using the ax.bar()
function for vertical bars or the ax.barh()
function for horizontal bars.
# Bar plot using ax.bar()
45)
np.random.seed(= np.random.rand(5)
y = np.arange(5)
x = plt.subplots(figsize=(5, 4))
fig, ax = 1, color = 'steelblue',
ax.bar(x,y, width = '#000000', linewidth = 0.5, alpha = 0.8)
edgecolor 'x')
ax.set_xlabel('y')
ax.set_ylabel( plt.show()

ax.bar()
In the following example, we generate a horizontal bar plot using the ax.barh()
function.
# Horizontal Bar plot using ax.barh()
45)
np.random.seed(= np.random.rand(5)
y = ["G1", "G2", "G3", "G4", "G5"]
x = plt.subplots(figsize=(5, 4))
fig, ax =0.5, color='steelblue',
ax.barh(x, y, height='#000000', linewidth=0.5, alpha=0.8)
edgecolor# ax.set_title('Horizontal Bar Plot')
'y')
ax.set_xlabel('Groups')
ax.set_ylabel( plt.show()

ax.barh()
6.4.4 Pie plot
Pie plots can be generated using the ax.pie()
function. The explode
option can be used to separate the slices of the pie chart, and the autopct
option can be used to display the percentage of each slice.
# Pie plot using ax.pie()
45)
np.random.seed(= np.random.rand(5)
y = y / sum(y)
y <.05] = .05
y[y=['Group 1', 'Group 2', 'Group 3', 'Group 4', 'Group 5']
labels= ['#FF0000','#FFFF00','#00FF00','#00FFFF','#0000FF']
colors = plt.subplots(figsize=(5, 5))
fig, ax =labels, colors=colors,
ax.pie(y,labels=True, explode=np.array([0.1,0,0,0.1,0]), autopct='%1.1f%%', startangle=90)
shadow plt.show()

ax.pie()
6.4.5 Histograms
The ax.hist()
function is used to create a histogram. In the following example, the density
option takes a boolean value that determines whether the histogram is normalized to form a probability density function (PDF).
# First Histogram
45)
np.random.seed(= np.random.randn(1000)
x = plt.subplots(figsize=(5, 4))
fig, ax =30, density=False, color='steelblue', edgecolor='black', alpha=0.8)
ax.hist(x, bins'Histogram')
ax.set_title('x')
ax.set_xlabel('Frequency')
ax.set_ylabel(
plt.tight_layout()
plt.show()
# Second Histogram
= np.random.randn(1000)
x = plt.subplots(figsize=(5, 4))
fig, ax =30, density=True, color='#FF7F00', edgecolor='black', alpha=0.7)
ax.hist(x, bins'Normalized Histogram')
ax.set_title('x')
ax.set_xlabel('Density')
ax.set_ylabel(
plt.tight_layout() plt.show()


ax.hist()
In the following example, we show how to add multiple plots to the same axes. The first plot is a histogram, and the second plot is the probability density function (PDF) of the normal distribution.
# First Histogram with PDF overlay (OOP style, improved)
45)
np.random.seed(= np.random.randn(1000)
x = plt.subplots(figsize=(5, 4))
fig, ax # Plot histogram
=30, label='Empirical', density=True, color='steelblue', edgecolor='black', alpha=0.7)
ax.hist(x, bins# Overlay normal PDF
= np.linspace(x.min(), x.max(), 1000)
pdfx = stats.norm.pdf(pdfx)
pdfy 'k-', label='Normal PDF', linewidth=1)
ax.plot(pdfx, pdfy, # Labels and legend
'x')
ax.set_xlabel('Density')
ax.set_ylabel('Histogram with Normal PDF')
ax.set_title(
ax.legend()
fig.tight_layout() plt.show()

6.4.6 Multiple plots on the same figure
In the following example, we first create a Figure
of size 8x7 inches using fig=plt.figure(figsize=(8,7))
. We then create the 2x2 grid of subplots and the Axes
objects with fig.add_subplot(2,2,p)
, where p
indicates the position of the subplot within the grid.
45)
np.random.seed(= plt.figure(figsize=(7, 7))
fig
# Panel 1: Line plot
= fig.add_subplot(2, 2, 1)
ax1 = np.random.randn(100)
y1 ='steelblue', linewidth=1)
ax1.plot(y1, color'Line Plot')
ax1.set_title('Index')
ax1.set_xlabel('Value')
ax1.set_ylabel(True, linestyle='--', alpha=0.5)
ax1.grid(
# Panel 2: Bar plot
= fig.add_subplot(2, 2, 2)
ax2 = np.random.rand(5)
y2 = np.arange(5)
x2 ='Bar Chart', color='orange', edgecolor='black', linewidth=0.7, alpha=0.8)
ax2.bar(x2, y2, label
ax2.legend()'x label')
ax2.set_xlabel('y label')
ax2.set_ylabel('Bar Plot')
ax2.set_title(='y', linestyle=':', alpha=0.5)
ax2.grid(axis
# Panel 3: Pie plot
= fig.add_subplot(2, 2, 3)
ax3 = np.random.rand(5)
y3 = y3 / y3.sum()
y3 < .05] = .05
y3[y3 = ['A', 'B', 'C', 'D', 'E']
labels = ['#FF00FF', '#FFF000', '#00FF0F', '#00FFF0', '#F0000F']
colors =labels, colors=colors, autopct='%1.1f%%', startangle=90)
ax3.pie(y3, labels'Pie Plot')
ax3.set_title(
# Panel 4: Scatter plot
= fig.add_subplot(2, 2, 4)
ax4 = np.random.randn(100, 2)
z 1] = 0.5 * z[:, 0] + np.sqrt(0.5) * z[:, 1]
z[:, = z[:, 0]
x4 = z[:, 1]
y4 =25, color='steelblue', alpha=0.8, edgecolor='black')
ax4.scatter(x4, y4, s'Scatter Plot')
ax4.set_title('x values')
ax4.set_xlabel('y values')
ax4.set_ylabel(True, linestyle='--', alpha=0.5)
ax4.grid(
=0.4, wspace=0.3)
fig.subplots_adjust(hspace
fig.tight_layout() plt.show()

fig.add_subplot()
function
Alternatively, we can create the 2x2 grid of subplots and the Axes
objects using fig, ax = plt.subplots(2,2,figsize=(8,7))
. The positions of subplots are specified through ax[i,j]
.
45)
np.random.seed(= plt.subplots(2, 2, figsize=(7, 7))
fig, ax
# Panel 1: Line plot
= np.random.randn(100)
y1 0, 0].plot(y1, color='steelblue', linewidth=1)
ax[0, 0].set_title('Line Plot')
ax[0, 0].set_xlabel('Index')
ax[0, 0].set_ylabel('Value')
ax[0, 0].grid(True, linestyle='--', alpha=0.5)
ax[
# Panel 2: Bar plot
= np.random.rand(5)
y2 = np.arange(5)
x2 0, 1].bar(x2, y2, label='Bar Plot', color='orange', edgecolor='black', linewidth=0.7, alpha=0.8)
ax[0, 1].legend()
ax[0, 1].set_xlabel('x label')
ax[0, 1].set_ylabel('y label')
ax[0, 1].set_title('Bar Plot')
ax[0, 1].grid(axis='y', linestyle=':', alpha=0.5)
ax[
# Panel 3: Pie plot
= np.random.rand(5)
y3 = y3 / y3.sum()
y3 < 0.05] = 0.05
y3[y3 = ['A', 'B', 'C', 'D', 'E']
labels = ['#FF00FF', '#FFF000', '#00FF0F', '#00FFF0', '#F0000F']
colors 1, 0].pie(y3, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
ax[1, 0].set_title('Pie Plot')
ax[
# Panel 4: Scatter plot
= np.random.randn(100, 2)
z 1] = 0.5 * z[:, 0] + np.sqrt(0.5) * z[:, 1]
z[:, = z[:, 0]
x4 = z[:, 1]
y4 1, 1].scatter(x4, y4, s=25, color='steelblue', alpha=0.8, edgecolor='black')
ax[1, 1].set_title('Scatter Plot')
ax[1, 1].set_xlabel('x values')
ax[1, 1].set_ylabel('y values')
ax[1, 1].grid(True, linestyle='--', alpha=0.5)
ax[
=0.4, wspace=0.3)
fig.subplots_adjust(hspace
fig.tight_layout() plt.show()

plt.subplots()
function
6.5 Other Tools for Graphics
In this chapter, we covered only the most commonly used plotting methods. Matplotlib also provides functions for other types of plots, such as density plots, contour plots, and three-dimensional plots, as well as customization tools for legends, colorbars, ticks, text, and annotations. In addition to Matplotlib, the Seaborn and Pandas modules offer additional plotting methods. For further reading, we refer the reader to Sheppard (2021), McKinney (2022), and VanderPlas (2023).