Python: Matplotlib & Seaborn

Part I. Matplotlib

Matplotlib

  • Matplotlib 是一个 Python 的 2D 绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。
  • 安装 matplotlib 的最简单方法是使用 pip。

    pip 是一个现代的,通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。

  • 命令提示符(cmd)或 Linux shell 中键入以下命令:
    • pip install matplotlib
  • 使用 matplotlib 库需要首先将其导入代码:
    • import matplotlib.pyplot as plt
  • 每个 pyplot 函数都会对图形进行一些设置 e.g.:
    • 创建图形:plt.figure()
    • 在图形中创建绘图区域:plt.subplot(1, 1)
    • 在绘图区域中绘制一些线:plt.plot([0, 1], [0, 1], label='line')
    • 用标签等装饰绘图:plt.legend()
  • 无论何时使用 matplotlib 绘图,都应有两行主要代码:
    • 图的类型
      定义条形图、折线图等图的类型:plt.plot()plt.bar()
    • 显示图表
      显示图形的代码:plt.show()
  • matplotlib 可以让你轻松完成任务,只需几行代码即可生成绘图、直方图、条形图、误差图、散点图等:

从一个简单的例子开始

1
2
3
4
5
6
7
import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4, 5]
y = [0, 1, 4, 9, 16, 25]

plt.plot(x, y)
plt.show()

  • 注意:如果为 plot() 命令提供单个列表或数组,则 matplotlib 假设它是一个 y 值序列,并且自动生成 x 值。
1
2
3
4
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()

  • Python 默认 x 向量长度与 y 相同,且从 0 开始,因此,x = [0, 1, 2, 3]

pyplot 方法

  • text():在任意位置添加文本
  • xlabel():将文本添加到 x 轴
  • ylabel():将文本添加到 y 轴
  • title():将标题添加到图中
  • savefig():将图形保存到文件中
  • legend():在图上显示图例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt

y1 = []
y2 = []
x = range(-100, 100, 10)
for i in x:
y1.append(i**2)
for i in x:
y2.append(-(i**2))

# 逐渐完善图形
plt.plot(x, y1)
plt.plot(x, y2)
plt.xlabel("x")
plt.ylabel("y")
plt.ylim(-2000, 2000)
plt.axhline(0) # 水平线
plt.axvline(0) # 垂直线

# 保存图形到文件
plt.savefig("quad.png")

# 显示图形到屏幕
plt.show()

折线图

简单折线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# importing the required module
import matplotlib.pyplot as plt

# x 轴的值
x = [1, 2, 3]
# 相对应 y 轴的值
y = [2, 4, 1]

# 绘制这些点
plt.plot(x, y, color="g")

# 为 x 轴命名
plt.xlabel("x - axis")
# 为 y 轴命名
plt.ylabel("y - axis")

# 为图表添加标题
plt.title("My first graph!")

# 显示图像
plt.show()

有两条线的折线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import matplotlib.pyplot as plt

# 折线 1 的点
x1 = [1, 2, 3]
y1 = [2, 4, 1]
# 绘制折线 1 的点
plt.plot(x1, y1, label="line 1",color="g")

# 折线 2 的点
x2 = [1, 2, 3]
y2 = [4, 1, 3]
# 绘制折线 2 的点
plt.plot(x2, y2, label="line 2",color="r")

# 命名 x 轴
plt.xlabel('x - axis')
# 命名 y 轴
plt.ylabel('y - axis')
# 给图表一个标题
plt.title('Two lines on same graph!')

# 在图上显示图例
plt.legend()

# 显示图表的函数
plt.show()

定制折线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import matplotlib.pyplot as plt

# x 轴的值
x = [1, 2, 3, 4, 5, 6]
# 对应的 y 轴的值
y = [2, 4, 1, 5, 2, 6]

# 绘制点
plt.plot(x, y, color='green', linestyle='dashed', linewidth=3,
marker='o', markerfacecolor='blue', markersize=12)

# 设置 x 和 y 轴的范围
plt.ylim(1, 8)
plt.xlim(1, 8)

# 命名 x 轴
plt.xlabel('x - axis')
# 命名 y 轴
plt.ylabel('y - axis')

# 给图表一个标题
plt.title('Some cool customizations!')

# 显示图表的函数
plt.show()

线条标记

符号标记描述
"."pointpoint
","pixelpixel
"o"circlecircle
"v"triangle_downtriangle_down
"^"triangle_uptriangle_up
"<"triangle_lefttriangle_left
">"triangle_righttriangle_right
"1"tri_downtri_down
"2"tri_uptri_up
"3"tri_lefttri_left
"4"tri_righttri_right
"8"octagonoctagon
"s"squaresquare
"p"pentagonpentagon
"P"plus_filledplus (filled)
"*"starstar
"h"hexagon1hexagon1
"H"hexagon2hexagon2
"+"plusplus
"x"xx
"X"x_filledx (filled)
"D"diamonddiamond
"d"thin_diamondthin_diamond
"|"vlinevline
"_"hlinehline
0 (TICKLEFT)ticklefttickleft
1 (TICKRIGHT)tickrighttickright
2 (TICKUP)tickuptickup
3 (TICKDOWN)tickdowntickdown
4 (CARETLEFT)caretleftcaretleft
5 (CARETRIGHT)caretrightcaretright
6 (CARETUP)caretupcaretup
7 (CARETDOWN)caretdowncaretdown
8 (CARETLEFTBASE)caretleft_basecaretleft (centered at base)
9 (CARETRIGHTBASE)caretright_basecaretright (centered at base)
10 (CARETUPBASE)caretup_basecaretup (centered at base)
11 (CARETDOWNBASE)caretdown_basecaretdown (centered at base)

颜色

符号颜色
k黑色
b蓝色
c青色
g绿色
m洋红
r红色
y黄色
graygrey灰色
lightgraylightgrey浅灰色

柱形图

简单柱形图

1
2
3
4
5
6
7
8
import matplotlib.pyplot as plt

# 创建用于绘图的数据
values = [5, 6, 3, 7, 2]
names = ["A", "B", "C", "D", "E"]

plt.bar(names, values, color="green")
plt.show()

  • names 表示 x 的坐标值,默认位置是每个柱状图所在的中点位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import matplotlib.pyplot as plt

# 柱子的高度
height = [10, 24, 36, 40, 5]

# 柱子的标签
names = ["one", "two", "three", "four", "five"]

# 绘制条形图
c1 = ["red", "green"]
c2 = ["b", "g"] # 我们可以用这个来设置颜色
plt.bar(names, height, width=0.8, color=c1)

# 命名 x 轴
plt.xlabel("x - axis")
# 命名 y 轴
plt.ylabel("y - axis")

# 图表标题
plt.title("My bar chart!")

# 显示图表的函数
plt.show()

  • 如果 x 轴的标签出现不按顺序排列的问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt
import numpy as np

# 柱子的高度
height = [10, 24, 36, 40, 5]

# 柱子的标签
names = ["one", "two", "three", "four", "five"]

# 绘制条形图
c1 = ["red", "green"]
c2 = ["b", "g"] # 我们可以用这个来设置颜色
index = np.arange(len(names))
plt.bar(index, height, width=0.8, color=c1)

# 命名 x 轴
plt.xlabel("x - axis")
plt.xticks(index, names)
# 命名 y 轴
plt.ylabel("y - axis")
# 图表标题
plt.title("My bar chart!")
# 显示图表的函数
plt.show()

  • xticks(locs, [labels], **kwargs),其中 locs 用于设置 X 轴刻度间隔,labels 用于设置每个间隔的显示标签。

柱形图(堆积柱形图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
import matplotlib.pyplot as plt

countries = ["USA", "India", "China", "Russia", "Germany"]
bronzes = np.array([38, 17, 26, 19, 15])
silvers = np.array([37, 23, 18, 18, 10])
golds = np.array([46, 27, 26, 19, 17])

# 生成 X 轴刻度间隔 [0, 1, 2, 3, 4]
index = np.arange(len(countries))

# 绘制堆积柱形图
plt.bar(index, golds, width=0.8, label="golds", color="gold", bottom=silvers + bronzes)
plt.bar(index, silvers, width=0.8, label="silvers", color="silver", bottom=bronzes)
plt.bar(index, bronzes, width=0.8, label="bronzes", color="#CD853F")

# 设置坐标轴
plt.xticks(index, countries)
plt.ylabel("Medals")
plt.xlabel("Countries")
plt.legend(loc="upper right")
plt.title("2019 Olympics Top Scorers")
plt.show()

柱形图(簇状柱形图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
import matplotlib.pyplot as plt

# 准备数据
data = [
[30, 25, 50, 20],
[40, 23, 51, 17],
[35, 22, 45, 19],
]
X = np.arange(4)

# 绘制柱状图
plt.bar(X + 0.00, data[0], color="b", width=0.25, label="2014")
plt.bar(X + 0.25, data[1], color="g", width=0.25, label="2016")
plt.bar(X + 0.50, data[2], color="r", width=0.25, label="2022")

plt.xticks(X + 0.25, ["China", "US", "UK", "Russia"])

plt.ylabel("Medals")
plt.xlabel("Countries")
plt.title("Olympics Top Scorers")

plt.legend()
plt.legend(loc="upper right")
plt.show()

图例 loc 参数的表示方法

  • 图例 loc 参数的表示方法,分为字符串和整数两种:
    位置字符串表示整数数字表示
    自适应Best0
    右上方upper right1
    左上方upper left2
    左下lower left3
    右下lower right4
    右侧right5
    居中靠左center left6
    居中靠右center right7
    底部居中lower center8
    上部居中upper center9
    中部center10

条形图

我们还可以将柱形图水平翻转得到条形图,如下所示:

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt

# 创建用于绘图的数据
values = [5, 6, 3, 7, 2]
names = ["A", "B", "C", "D", "E"]

# 在 bar 后加 "h" 会翻转图形
plt.barh(names, values, color="yellowgreen")
plt.show()

直方图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

# 频率
ages = [2, 5, 70, 40, 30, 45, 50, 45, 43, 40, 44, 60, 7, 13, 57, 18, 90, 77, 32, 21, 20, 40]

# 设置范围和区间数量
range = (0, 100)
bins = 10

# 绘制直方图
plt.hist(ages, bins, range, color="green", histtype="bar", rwidth=0.98)

# x 轴标签
plt.xlabel("age")
# 频率标签
plt.ylabel("No. of people")
# 图表标题
plt.title("My histogram")

# 显示图表的函数
plt.show()

1
2
3
4
5
6
7
8
import matplotlib.pyplot as plt

# 生成虚拟数据
x = [2, 1, 6, 4, 2, 4, 8, 9, 4, 2, 4, 10, 6, 4, 5, 7, 7, 3, 2, 7, 5, 3, 5, 9, 2, 1]

# 绘制直方图
plt.hist(x, bins=10, color="blue", alpha=0.5)
plt.show()

  • 代码段添加了两个新参数:
    • Bins: 是一个直方图的特定参数,允许用户自定义所需的箱数。
    • Alpha: 显示数据点的透明度程度。

散点图

1
2
3
4
5
6
7
8
import matplotlib.pyplot as plt

# 创建绘图数据
x_values = [0, 1, 2, 3, 4, 5]
y_values = [0, 1, 4, 9, 16, 25]

plt.scatter(x_values, y_values, s=30, color="blue")
plt.show()

  • 注意:绘图代码由plt.bar()改为了plt.scatter()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

# x 轴数值
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# y 轴数值
y = [2, 4, 5, 7, 6, 8, 9, 11, 12, 12]

# 绘制散点图
plt.scatter(x, y, label="stars", color="green", marker="*", s=30)

# 设置 x 轴标签
plt.xlabel("x - axis")
# 设置 y 轴标签
plt.ylabel("y - axis")
# 设置图表标题
plt.title("My scatter plot!")
# 显示图例
plt.legend()

# 显示图表的函数
plt.show()

饼图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import matplotlib.pyplot as plt

# 定义标签
activities = ["eat", "sleep", "work", "play"]

# 每个标签所占的份额
slices = [3, 7, 8, 6]

# 每个标签的颜色
colors = ["r", "y", "g", "b"]

# 绘制饼图
plt.pie(slices, labels=activities, colors=colors, startangle=90, shadow=True, explode=(0, 0, 0.1, 0), radius=1.2, autopct="%1.1f%%")

# 绘制图例
plt.legend()

# 显示图表
plt.show()

autopct 用于使用 Python 字符串格式显示百分比值。

盒图

  • 盒图能能通过一组数据的最大值、最小值、中位数、及上下四分位数显示数据的分布
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(10)
collectn_1 = np.random.normal(100, 10, 200)
collectn_2 = np.random.normal(80, 30, 200)
collectn_3 = np.random.normal(90, 20, 200)
collectn_4 = np.random.normal(70, 25, 200)
data_to_plot=[collectn_1,collectn_2,collectn_3,collectn_4]

plt.boxplot(data_to_plot)
index = np.arange(1, 5)
plt.xticks(index, ['China', 'US', 'UK', 'Russia'])
plt.show()

小提琴图

  • 小提琴图是用来展示数据分布状态以及概率密度的图表。这种图表结合了箱形图和密度图的特征。小提琴图跟箱形图类似,不同之处在于小提琴图还显示数据在不同数值下的概率密度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(10)
collectn_1 = np.random.normal(100, 10, 200)
collectn_2 = np.random.normal(80, 30, 200)
collectn_3 = np.random.normal(90, 20, 200)
collectn_4 = np.random.normal(70, 25, 200)
data_to_plot=[collectn_1,collectn_2,collectn_3,collectn_4]

plt.violinplot(data_to_plot)
index = np.arange(1, 5)
plt.xticks(index, ['China', 'US', 'UK', 'Russia'])
plt.show()

绘制给定方程的曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 导入所需的模块
import matplotlib.pyplot as plt
import numpy as np

# 设置 x 坐标
x = np.arange(0, 2 * (np.pi), 0.1)
# 设置对应的 y 坐标
y = np.sin(x)
plt.text(3.5, 0.5, "$y=sin(x), x\\in[0,2\\pi)$")

# 绘制点
plt.plot(x, y)

# 显示图表的函数
plt.show()

绘制极线图

plt.polar(theta, r)

  • theta:每个标记所在射线与极径的夹角。
  • r:每个标记到原点的距离。
1
2
3
4
5
6
7
8
9
10
11
12
# 导入所需的模块
import matplotlib.pyplot as plt
import numpy as np

barSlices = 12
theta = np.linspace(0.0, 2 * np.pi, barSlices, endpoint=False)
r = 30 * np.random.rand(barSlices)

plt.polar(theta, r, color="chartreuse", linewidth=2, marker="*", mfc="b", ms=10)

# 显示图表的函数
plt.show()

figure 图形对象

  • 在 matplotlib 中,面向对象编程的核心思想是创建图形对象,然后通过图形对象来调用其它的方法和属性。在这个过程中,pyplot 负责生成图形对象,并通过该对象来添加一个或多个绘图区域(即 axes 对象)。
  • 通过调用 pyplot 模块中 figure() 函数来实例化 figure 对象。
1
2
3
4
import matplotlib.pyplot as plt

# 创建图形对象,也即一个空白画布
fig = plt.figure()
  • 使用 add_axes() 添加一个子绘图区域到画布中。如下所示:
1
ax = fig.add_axes([0,0,1,1]) # 添加的子图区域覆盖了全局绘图区域,也即画布
  • add_axes(left, bottom, width, height)。四个值分别表示添加到画布矩形区域的左下角坐标 (x, y),以及宽度和高度。注意:每个数字必须介于 0 到 1 之间
  • 使用 add_axes() 可添加一个子绘图区域到画布(figure),产生的子绘图区域用 ax 对象表示。通过 ax 可进行图像绘制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import matplotlib.pyplot as plt
import numpy as np
import math

x = np.arange(0, math.pi * 2, 0.05)
y = np.sin(x)

fig = plt.figure()

ax = fig.add_axes([0, 0, 1, 1])
ax.plot(x, y)
ax.set_title("sine wave")
ax.set_xlabel("angle")
ax.set_ylabel("sine")

plt.show()

  • figure() 函数来实例化 figure 对象的参数值,如下所示:
参数说明
figsize指定画布的大小 (宽度,高度),单位为英寸。
dpi指定绘图对象的分辨率,即每英寸多少个像素,默认值为 80。
facecolor背景颜色。
edgecolor边框颜色。
frameon是否显示边框。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import matplotlib.pyplot as plt
import numpy as np
import math

x = np.arange(0, math.pi * 2, 0.05)
y = np.sin(x)

fig = plt.figure(figsize=(5, 5), facecolor="green", dpi=50)

ax = fig.add_axes([0, 0, 1, 1])
ax.plot(x, y)
ax.set_title("sine wave")
ax.set_xlabel("angle")
ax.set_ylabel("sine")

plt.show()

  • 绘制图像之前也可不调用figure()函数创建全局绘图区域,此时,plt 子库会自动创建一个默认的绘图区域
1
2
3
4
5
6
7
8
9
10
11
12
13
import matplotlib.pyplot as plt
import numpy as np
import math

x = np.arange(0, math.pi * 2, 0.05)
y = np.sin(x)

plt.plot(x, y)
plt.title("sine wave")
plt.xlabel("angle")
plt.ylabel("sine")

plt.show()

子图 subplot(创建单个子图)

  • **subplot(nrows, ncols, plot_number)**用于在全局绘图区域内创建子绘
    图区域,其参数表示将全局绘图区域分成nrows行和ncols列,并根据先行后列的计数方式在plot_number位置生成一个坐标系。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import matplotlib.pyplot as plt

# 计算正弦和余弦曲线上的点的 x 和 y 坐标
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# 建立 subplot 网格,高为 2,宽为 1
# 激活第一个 subplot
plt.subplot(2, 1, 1)
# 绘制第一个图像
plt.plot(x, y_sin)
plt.title("Sine")
# 将第二个 subplot 激活,并绘制第二个图像
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title("Cosine")
# 展示图像
plt.show()

  • subplots(nrows, ncols) 函数的使用方法和 subplot() 函数类似。其不同之处在于,subplots() 既创建了一个包含**若干个子图区域(由 ax 表示)**的画布,又创建了一个 figure 图形对象,而 subplot() 只是创建一个包含子图区域的画布。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(2, 2)
x = np.arange(1, 5)

# 绘制平方函数
ax[0][0].plot(x, x * x)
ax[0][0].set_title("square")
# 绘制平方根图像
ax[0][1].plot(x, np.sqrt(x))
ax[0][1].set_title("square root")
# 绘制指数函数
ax[1][0].plot(x, np.exp(x))
ax[1][0].set_title("exp")
# 绘制对数函数
ax[1][1].plot(x, np.log10(x))
ax[1][1].set_title("log")

plt.show()

  • subplots(nrows, ncols) 的另外一个例子。subplots() 创建的若干个子图区域由 ax 表示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 100)

#划分子图
fig,axes=plt.subplots(2,2)
ax1=axes[0,0]
ax2=axes[0,1]
ax3=axes[1,0]
ax4=axes[1,1]

#作图 1
ax1.plot(x, x)

#作图 2
ax2.plot(x, -x)

#作图 3
ax3.plot(x, x ** 2)
ax3.grid(color='r', linestyle='--', linewidth=1,alpha=0.3)

#作图 4
ax4.plot(x, np.log(x))

plt.show()

创建多个子图(面向对象的 API)

  • add_subplotadd_axes 都是面向 figure 对象的创建子图的 API。注意:pyplot 的 API 中没有此命令。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 100)

#新建 figure 对象
fig=plt.figure()

#新建子图 1
ax1=fig.add_subplot(2,2,1)
ax1.plot(x, x)

#新建子图 3
ax3=fig.add_subplot(2,2,3)
ax3.plot(x, x ** 2)
ax3.grid(color='r', linestyle='--',
linewidth=1,alpha=0.3)

#新建子图 4
ax4=fig.add_subplot(2,2,4)
ax4.plot(x, np.log(x))

plt.show()

  • add_subplotsubplot的区别
    • subplot方法属于** API 绘图**,而add_subplot方法为面向对象绘图
    • 使用subplot方法自动生产画布与轴域,而add_subplot方法需要先添加画布 figure,再在画布上添加轴域add_subplot返回的即为子图的轴域
    • 当绘制的子图之间出现遮挡,subplot方法会绘制代码位置靠后的图形,而add_subplot则会绘制所有图形,只是出现遮挡
  • add_subplot方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 100)

# 新建 figure 对象
fig = plt.figure()

# 新建子图 1
ax1 = fig.add_subplot(2, 2, 1)
ax1.plot(x, x)

# 新建子图 3
ax3 = fig.add_subplot(2, 2, 3)
ax3.plot(x, x**2)
ax3.grid(color="r", linestyle="--", linewidth=1, alpha=0.3)

# 新建子图 4
ax4 = fig.add_subplot(2, 2, 4)
ax4.plot(x, np.log(x))

plt.show()

  • subplot方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import matplotlib.pyplot as plt

# 计算正弦和余弦曲线上的点的 x 和 y 坐标
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)

# 建立 subplot 网格,高为 2,宽为 1
# 激活第一个 subplot
plt.subplot(2, 1, 1)
# 绘制第一个图像
plt.plot(x, y_sin)
plt.title("Sine")

# 将第二个 subplot 激活,并绘制第二个图像
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title("Cosine")

# 展示图像
plt.show()

  • add_axes为新增子区域,该区域可以座落在 figure 内任意位置,且该区域可任意设置大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
import matplotlib.pyplot as plt

#新建 figure
fig = plt.figure()

# 定义数据
x = [1, 2, 3, 4, 5, 6, 7]
y = [1, 3, 4, 2, 5, 8, 6]
#新建区域 ax1
#figure 的百分比,从 figure 10%的位置开始绘制,宽高是 figure 的 80%
left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
# 获得绘制的句柄
ax1 = fig.add_axes([left, bottom, width, height])
ax1.plot(x, y, 'r')
ax1.set_title('area1')

#新增区域 ax2, 嵌套在 ax1 内
left, bottom, width, height = 0.2, 0.6, 0.25, 0.25
# 获得绘制的句柄
ax2 = fig.add_axes([left, bottom, width, height])
ax2.plot(x,y, 'b')
ax2.set_title('area2')

plt.show()

双轴图

  • 在一些应用场景中,有时需要绘制两个 x 轴或两个 y 轴,这样可以更直观
    地显现图像,从而获取更有效的数据。
  • matplotlib 提供的 twinx()twiny() 函数,除了可以实现绘制双
    轴的功能外,还可以使用不同的单位来绘制曲线
    ,比如一个轴绘制对数函数,另外一个轴绘制指数函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt
import numpy as np

#创建图形对象
fig = plt.figure()
#添加子图区域
a1 = fig.add_axes([0,0,1,1])

#准备数据
x = np.arange(1,11)

#绘制指数函数
a1.plot(x,np.exp(x))
a1.set_ylabel('exp')

#添加双轴
a2 = a1.twinx()
#绘制对数函数
a2.plot(x, np.log(x),'ro-')
a2.set_ylabel('log')

#绘制图例
fig.legend(labels = ('exp','log'), loc=2)
plt.show()

移动坐标轴位置

  • 有时候需要移动坐标到某些位置,这样看曲线更加方便,比如像下图:
  • matplotlib 中一个图默认是有四个坐标轴线,简称为 spines。这四个轴通过 top、bottom、left、right 来访问。要想实现前面的图那样显示坐标轴,主要要解决两个问题,第一个问题,就是要隐藏上面和右边两条没有用到的坐标轴;第二个问题是移动左边和下面的坐标轴的位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import matplotlib.pyplot as plt
import numpy as np

#创建图形对象
fig = plt.figure()
#添加子图区域
a1 = fig.add_axes([0,0,1,1])

#准备数据
x = np.arange(-10,10,0.1)

#绘制指数函数
a1.plot(x, x**2, color='orange', linewidth=3)
a1.plot(x, 0.7*x, 'b--')

a1.set_xlabel('x axis')
a1.set_ylabel('y axis')

#隐藏右边和上边
a1.spines['right'].set_visible(False)
a1.spines['top'].set_visible(False)

a1.set_ylim(-20, 80)
a1.set_xlim(-7.5, 7.5)

# 移动到左边的 y 轴
a1.spines['left'].set_position(('data', 0))
# 移动到下边的 x 轴
a1.spines['bottom'].set_position(('data', 0))

plt.show()

matplotlib grid() 设置网格格式

  • matplotlib axes 对象提供的 grid() 方法可以开启或者关闭画布中的网格。除此之外,grid() 函数还可以设置网格的颜色、线型以及线宽等属性。grid() 的函数使用格式如下:
1
grid(color='b', ls = '-.', lw = 0.25)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import matplotlib.pyplot as plt
import numpy as np

# fig 画布;axes 子图区域
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
x = np.arange(1, 11)

axes[0].plot(x, x**3, "g", lw=2)

# 开启网格
axes[0].grid(True)
axes[0].set_title("default grid")
axes[1].plot(x, np.exp(x), "r")

# 设置网格的颜色,线型,线宽
axes[1].grid(color="b", ls="-.", lw=0.25)
axes[1].set_title("custom grid")

axes[2].plot(x, x)
axes[2].set_title("no grid")

fig.tight_layout()
plt.show()

  • 注意:fig.tight_layout() 使得子图横纵坐标更加紧凑,主要用于自动调整图区的大小以及间距,使所有的绘图及其标题、坐标轴标签等都可以不重叠的完整显示在画布上。

刻度和刻度标签

  • 刻度指的是轴上数据点的标记,matplotlib 能够自动的在 x 、y 轴上绘制出刻度,但是在某些情况下,刻度标签或刻度也需要满足特定的要求。注意:通过轴对象设置刻度时需要分别通过set_xticklabels()set_yticklabels() 函数设置与刻度线相对应的刻度标签。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt
import numpy as np
import math

x = np.arange(0, math.pi * 2, 0.05)
# 生成画布对象
fig = plt.figure()
# 添加绘图区域
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
y = np.sin(x)
ax.plot(x, y)
# 设置 x 轴标签
ax.set_xlabel("angle")
ax.set_title("sine")
ax.set_xticks([0, 2, 5, 6])

# 设置 x 轴刻度标签
ax.set_xticklabels(["zero", "two", "five", "six"])
# 设置 y 轴刻度
ax.set_yticks([-1, 0, 1])
plt.show()

  • matplotlib.ticker.AutoMinorLocator(n)类用于根据主要刻度的位置动态设置次要刻度的位置。主刻度线需要与线性刻度均匀地间隔开。n 表示主要刻度之间的时间间隔的细分数量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt
import numpy as np
import math
from matplotlib.ticker import AutoMinorLocator

x = np.arange(0, math.pi*2, 0.05)
#生成画布对象
fig = plt.figure()
#添加绘图区域
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
y = np.sin(x)
ax.plot(x, y)
#设置 x 轴标签
ax.set_xlabel('angle')
ax.set_title('sine')
ax.set_xticks([0,2,4,6])

#设置 x 轴刻度标签
ax.set_xticklabels(['zero','two','four','six'])
minor_locator = AutoMinorLocator(5)
ax.xaxis.set_minor_locator(minor_locator)
#设置 y 轴刻度
ax.set_yticks([-1,0,1])
plt.show()

matplotlib 数学表达式

  • matplotlib 中的数学公式都可以使用 Text Markup(文本标记语言)显现出来,具体的使用方法是将文本标记符放在一对、$内。这样,matplotlib 会使用其内置的 Latex 引擎绘制数学公式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)

#绘制函数图像
plt.plot(t,s)

#设置标题
plt.title(r'$\alpha_i> \beta_i$', fontsize=20)

#设置数学表达式
plt.text(0.45, 0.6, r'$\mathrm{sin}(2 \pi t)$', fontsize = 20)
#设置数学表达式
plt.text(0.1, -0.5, r'$\sqrt{2}$', fontsize=10)

plt.xlabel('time (s)')
plt.ylabel('volts (mV)')

plt.show()

显示中文字体

  • 为了正确显示中文字体,请用以下代码更改默认设置,其中'SimHei'表示黑体字。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt

# 设置字体
plt.rcParams["font.sans-serif"] = ["SimHei"]
# 该语句解决图像中的“-”负号的乱码问题'

plt.rcParams["axes.unicode_minus"] = False

x = np.linspace(0, 4 * np.pi)
y = np.sin(x)

plt.title("sin 曲线")
plt.plot(x, y, "g-", label="$sin(x)$")

plt.show()

matplotlib 绘制文本

  • matplotlib 可以通过下表中的方法可以绘制出相应的内容。与此同时,matplotlib 也支持绘制 Latex 包含的数学符号。
参数说明
text在绘图区域的任意位置添加文本。
annotate在绘图区域的任意位置添加带有可选箭头的注释。
xlabel在绘图区域的 x 轴上添加标签。
ylabel在绘图区域的 y 轴上添加标签。
title为绘图区域添加标题。
figtext在画布的任意位置添加文本。
suptitle为画布中添加标题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #正常显示负号

plt.title('axes title')
plt.xlabel('xlabel')
plt.ylabel('ylabel')

# 3,8 表示 x,y 的坐标点;style 设置字体样式为斜体;bbox 用来设置盒子的属性,比如背景色
plt.text(3, 8, 'C 语言中网网,编程爱好者都喜欢的网站', style='italic',bbox = {'facecolor': 'yellow'},fontsize=15)
plt.text(2, 6, r'an equation: $E = mc^2$', fontsize = 15)

#添加文字,并设置样式
plt.text(4, 0.05, '网址:c.biancheng.net',verticalalignment = 'bottom', color = 'green', fontsize = 15)
plt.plot([2], [1], 'o')

#xy 为点的坐标;xytext 为注释内容坐标;arrowprops 设置箭头的属性
plt.annotate('C 语言中文网', xy = (2, 1), xytext = (3, 4),arrowprops = dict(facecolor = 'blue', shrink = 0.1))

plt.xlim(0, 10)
plt.ylim(0, 10)

plt.show()

添加数据标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import matplotlib.pyplot as plt

# x axis values
x = [1, 2, 3, 4, 5, 6]
# corresponding y axis values
y = [2, 4, 1, 5, 2, 6]

# plotting the points
plt.plot(x, y, color="green", linestyle="dashed", linewidth=1, marker="o", markerfacecolor="blue", markersize=3)

# setting x and y axis range
plt.ylim(1, 8)
plt.xlim(1, 8)

# naming the x axis
plt.xlabel("x - axis")
# naming the y axis
plt.ylabel("y - axis")

# giving a title to my graph
plt.title("Some cool customizations!")

for a, b in zip(x, y):
plt.text(a, b + 0.1, "%d" % b, ha="center", va="bottom", fontsize=12)

plt.show()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import matplotlib.pyplot as plt
import numpy as np

# heights of bars
height = [10, 24, 36, 40, 5]

# labels for bars
names = ["one", "two", "three", "four", "five"]

# plotting a bar chart
c1 = ["red", "green"]
c2 = ["b", "g"] # we can use this for color
index = np.arange(len(names))
plt.bar(index, height, width=0.8, color=c1)
# naming the x-axis
plt.xlabel("x - axis")
plt.xticks(index, names)
# naming the y-axis
plt.ylabel("y - axis")
# plot title
plt.title("My bar chart!")

for a, b in zip(index, height):
plt.text(a, b, "%d" % b, ha="center", va="bottom", fontsize=12)

plt.show()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import matplotlib.pyplot as plt
import numpy as np

# heights of bars
height = [10, 24, 36, 40, 5]

# labels for bars
names = ["one", "two", "three", "four", "five"]

# plotting a bar chart
c1 = ["red", "green"]
c2 = ["b", "g"] # we can use this for color
index = np.arange(len(names))
bar = plt.bar(index, height, width=0.8, color=c1)
# naming the x-axis
plt.xlabel("x - axis")
plt.xticks(index, names)
# naming the y-axis
plt.ylabel("y - axis")
# plot title
plt.title("My bar chart!")

plt.bar_label(bar, fmt="%d")

plt.show()

  • 注意bar_label的使用要求 matplotlib 版本大于等于 3.4.1,如果版本较低,是无法进行该操作的。

多边形颜色填充

  • 图表又需要使用不同的颜色来区分数据,比如数据重叠区,比如数据交叉区。
  • 每个简单的多边形可以使用 x 坐标和 y 坐标构造,只要把这些点连接一起,再把里面的空间进行指定的颜色填充。
    • ax.fill(x, y) # 使用默认的颜色填充一个多边形
    • ax.fill(x, y, "b") # 使用蓝色填充一个多边形
    • ax.fill(x, y, x2, y2) # 使用默认颜色填充两个多边形
    • ax.fill(x, y, "b", x2, y2, "r") # 一个蓝色,一个红色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
import matplotlib.pyplot as plt

# 创建子图,等同于 ax=plt.subplot(111)
fig, ax = plt.subplots()
ax.grid(False)

ax.set_xlim(0, 100)
ax.set_ylim(0, 100)

# 填充三角形
x = [10, 20, 30]
y = [20, 80, 20]
ax.fill(x, y, color="b")

# 填充四边形
x = [40, 50, 50, 40]
y = [20, 20, 40, 40]
ax.fill(x, y, color="r")

plt.show()

  • 有时候需要进行不规则图形的填充,或者两条曲线相交的部分进行填充,就需要使用函数host.fill_between()
    matplotlib.pyplot.fill_between(x, y1, y2, where=None, interpolate=False, step=None, *, data=None, **kwargs)
  • 此函数用来填充两条水平曲线之间的区域,区域在点(x, y1)(x, y2)之间,如果还想有条件地选择区域,可以采用where参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

fig, host = plt.subplots()

host.set_xlim(0, 2*np.pi)
host.set_ylim(-2, 2)

#填充正弦曲线
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

host.fill_between(x,y, 0, color = 'r')
host.plot(x, y, color = 'b', alpha = 0.8)
host.plot([0, 2*np.pi], [0, 0], color = 'b', alpha = 0.8)

plt.show()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

ax.set_xlim(0, 2 * np.pi)
ax.set_ylim(-2, 2)

# 填充正弦曲线
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

ax.fill_between(x, y, 0, where=(x > np.pi) & (y < -0.5), color="r")
ax.plot(x, y, color="b", alpha=0.8)
ax.plot([0, 2 * np.pi], [0, 0], color="b", alpha=0.8)

plt.show()

3D 绘图

  • 最初开发的 matplotlib,仅支持绘制 2D 图形,后来随着版本的不断更新,matplotlib 在二维绘图的基础上,构建了一部分较为实用的 3D 绘图程序包,比如 mpl_toolkits.mplot3d,通过调用该程序包一些接口可以绘制 3D 散点图、3D 曲面图、3D 线框图等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
# 创建 3d 绘图区域,axes() 默认创建一个 subplot(111) 坐标系
ax = plt.axes(projection="3d")

# 从三个维度构建
z = np.linspace(0, 1, 100)
x = z * np.sin(20 * z)
y = z * np.cos(20 * z)

# 调用 ax.plot3D 创建三维线图
ax.plot3D(x, y, z, "b")
ax.set_title("3D line plot")
plt.show()

  • 通过 ax.scatter3D() 函数可以绘制 3D 散点图,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
# 创建 3d 绘图区域,axes() 默认创建一个 subplot(111) 坐标系
ax = plt.axes(projection="3d")

# 构建 xyz
z = np.linspace(0, 1, 100)
x = z * np.sin(20 * z)
y = z * np.cos(20 * z)
c = x + y

ax.scatter3D(x, y, z, c=c)
ax.set_title("3D line plot")
plt.show()

  • ax.contour3D() 可以用来创建 3D 等高线图,该函数要求输入数据均采用二维网格式的矩阵坐标。同时,它可以在每个网格点(x,y)处计算出一个 z 值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

def f(x, y):
return np.sin(np.sqrt(x**2 + y**2))

# 构建 x、y 数据
x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

# 将数据网格化处理
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig = plt.figure()
ax = plt.axes(projection="3d")

# 50 表示在 z 轴方向等高线的高度层级,binary 颜色从白色变成黑色
ax.contour3D(X, Y, Z, 50, cmap="binary")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
ax.set_title("3D contour")
plt.show()

  • 3D 线框图同样要采用二维网格形式的数据,与绘制等高线图类似。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

# 要绘制函数图像
def f(x, y):
return np.sin(np.sqrt(x**2 + y**2))

# 准备 x,y 数据
x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
# 生成 x、y 网格化数据
X, Y = np.meshgrid(x, y)
# 准备 z 值
Z = f(X, Y)

# 绘制图像
fig = plt.figure()
ax = plt.axes(projection="3d")

# 调用绘制线框图的函数 plot_wireframe()
ax.plot_wireframe(X, Y, Z, color="black")
ax.set_title("wireframe")
plt.show()

  • 3D 曲面图表示一个指定的因变量 y 与两个自变量 x 和 z 之间的函数关系。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

# 求向量积 (outer() 方法又称外积)
x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
# 矩阵转置
y = x.copy().T
# 数据 z
z = np.cos(x**2 + y**2)
# 绘制曲面图

fig = plt.figure()
ax = plt.axes(projection="3d")

# 调用 plot_surface() 函数
ax.plot_surface(x, y, z, cmap="viridis", edgecolor="none")
ax.set_title("Surface plot")
plt.show()

Part II. seaborn

seaborn

  • seaborn 是一个基于 matplotlib 的 Python 数据可视化库。它为创建有吸引力的图形提供了高级接口
  • seaborn 提供了很多东西,你可以使用一行代码创建图形,而这在 matplotlib 需要十来行。
  • seaborn 可以方便地处理 DataFrame 数据。
  • 可以通过以下代码导入:
    import seaborn as sns
  • 提供了用于检查多个变量之间关系的 API
  • 专门支持对分类变量分析或聚合统计
  • 支持单变量或双变量分布的可视化和比较
  • 不同线性回归模型的构建和可视化
  • 查看复杂数据集的整体结构
  • 可构造多图网格,轻松实现复杂的可视化

导入数据集

  • 在本节中,我们将使用免费的 Iris 数据集。可以使用pandas.read_csv方法加载该数据集。
1
2
3
4
import pandas as pd

iris = pd.read_csv('iris.csv', names=['sepal_length', 'sepal_width','petal_length', 'petal_width', 'class'])
iris.head()

散点图

  • 可以使用.scatterplot方法创建散点图,我们只需要将数据作为附加参数即可。
1
sns.scatterplot(x='sepal_length', y='sepal_width', data=iris)

  • 我们还可以使用 hue 参数按类别突出显示数据点,这要比 matplotlib 中简单得多。
1
sns.scatterplot(x="sepal_length", y="sepal_width", hue="class", data=iris)

  • hue 用于对将产生不同颜色的点的变量进行分组。

折线图

  • 要创建折线图,请使用 sns.lineplot方法。唯一需要的参数是数据,在例子中,数据是来自 Iris 数据集的四个列。
1
sns.lineplot(data=iris.drop(['class'], axis=1))

  • 在 pandas 中,drop()函数用于删除行。axis=1告诉 Python 在列而不是行上进行删除。

直方图

  • 在 seaborn 中可以使用sns.distplot方法创建直方图。我们需要将要绘制的列传递给它,seaborn 将自动计算每个数值范围内值的数量。我们还可以将箱子的数量传递给它。
1
2
wine_reviews = pd.read_csv("winemag-data-130k-v2.csv")
sns.distplot(wine_reviews["points"], bins=10, kde=False)

  • winemag-data-130k-v2.csv 数据集包含从 winemag.com 在 2017 年 6 月 15 日发布的葡萄酒评论数据。
  • kde 用于决定是否绘制高斯核密度估计。
1
sns.distplot(wine_reviews['points'], bins=10, kde=True)

柱形图

  • 在 seaborn 中,可以使用sns.countplot方法创建柱形图以显示每个类别中观测值的数量。
1
sns.countplot(x="points", data=wine_reviews, order=sorted(wine_reviews["points"].unique()), palette=sns.color_palette("husl", 20))

盒图

  • 盒须图主要包括六个统计指标:lower limit (下限), first quartile (第一四分位数), median (中位数), third quartile (第三四分位数), upper limit (上限) and outliers (异常值).
  • 可以使用 sns.boxplot 方法创建盒须图。注意,创建盒须图需要传递 x 和 y 两个列的值。
1
2
df = wine_reviews[(wine_reviews['points']>=95) & (wine_reviews['price']<1000)]
sns.boxplot('points', 'price', data=df)

密度图

  • 密度图是数据的图形表示,其中矩阵中包含的各个值表示为颜色
  • 密度图非常适合探索数据集中特征的相关性
  • 要获取数据集中特征的相关性,我们可以调用<dataset>.corr(),这是 pandas 库 dataframe 方法,其将给出各列的相关矩阵
  • 我们现在可以使用 matplotlib 或 seaborn 来创建密度图。

matplotlib

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

iris = pd.read_csv("iris.csv", names=["sepal_length", "sepal_width", "petal_length", "petal_width", "class"])

# get correlation matrix
corr = iris.drop(["class"], axis=1).corr()
fig, ax = plt.subplots()
# create heatmap
im = ax.imshow(corr.values)

# set labels
ax.set_xticks(np.arange(len(corr.columns)))
ax.set_yticks(np.arange(len(corr.columns)))
ax.set_xticklabels(corr.columns)
ax.set_yticklabels(corr.columns)

# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
plt.show()

  • 要向密度图添加注释,我们需要添加两个 for 循环:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 获取相关矩阵
corr = iris.drop(["class"], axis=1).corr()
fig, ax = plt.subplots()

# 创建热力图
im = ax.imshow(corr.values)

# 设置标签
ax.set_xticks(np.arange(len(corr.columns))) # 指定 x 轴的刻度
ax.set_yticks(np.arange(len(corr.columns))) # 指定 y 轴的刻度
ax.set_xticklabels(corr.columns)
ax.set_yticklabels(corr.columns)

# 旋转刻度标签并设置对齐方式
plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")

# 遍历数据维度并创建文本注释
columns = [0, 1, 2, 3]
for i in columns:
for j in columns:
text = ax.text(j, i, np.around(corr.iloc[i, j], decimals=2), ha="center", va="center", color="black")

seaborn

  • seaborn 使得创建密度图和添加注释变得更加容易:
1
sns.heatmap(iris.drop(["class"], axis=1).corr(), annot=True)

分面(Faceting)

  • 分面是将数据变量分解成多个子图,并将这些子图组合成单个图形的行为
  • 如果想快速浏览数据集,分面非常有用。
  • 要在 seaborn 中使用分面,可以使用 FaceGrid
    • 首先,需要定义 FaceGrid,并将数据以及行或列传递给它,这将用于拆分数据。
    • 然后,需要在 FaceGrid 对象上调用** map 函数**,并定义要使用的绘图类型以及要绘制的列。
1
2
g = sns.FacetGrid(iris, col="class")
g = g.map(sns.kdeplot, "sepal_length")

  • FacetGrid 将数据集映射到多个轴上,这些轴排列在与数据集中变量级别相对应的行或列网格中。
  • FacetGrid.map 函数将绘图函数应用于每个方面的数据子集。

Pairplot(联合分布图)

  • seaborns 的 pairplot 和 pandas 的 scatter_matrix 能够在数据集中绘制成对变量之间关系的网格。
1
sns.pairplot(iris)

1
2
3
4
from pandas.plotting import scatter_matrix

fig, ax = plt.subplots(figsize=(12,12))
scatter_matrix(iris, alpha=1, ax=ax)

  • 可以看到,联合分布图总是需要两个变量进行绘制。图的对角线用直方图填充,其他图是散点图。

Part III. 本章总结

在本章中,我们学习了如何使用 Matplotlib 和 Seaborn 进行数据可视化。这两个库在 Python 数据科学领域中非常重要,提供了丰富的图形绘制功能。以下是对本章内容的总结:

Matplotlib

基础绘图

  • 安装与导入:使用 pip install matplotlib 安装,import matplotlib.pyplot as plt 导入。
  • 基本用法:通过 plt.plot()plt.show() 等函数创建和显示图形。
  • 常用图形:折线图、柱形图、条形图、直方图、散点图、饼图、盒图、小提琴图等。

高级绘图

  • 子图与布局:使用 subplot()add_subplot() 创建多个子图。
  • 双轴图:通过 twinx()twiny() 实现双轴图。
  • 3D 绘图:使用 mpl_toolkits.mplot3d 创建 3D 图形,如线图、散点图、等高线图等。

自定义与美化

  • 文本与注释:通过 text()annotate() 添加文本和注释。
  • 网格与刻度:使用 grid() 添加网格,set_xticks()set_yticks() 设置刻度。
  • 颜色与填充fill_between() 实现区域填充,设置颜色和透明度。

Seaborn

基础绘图

  • 导入与数据集:通过 import seaborn as sns 导入,方便处理 DataFrame 数据。
  • 常用图形:散点图、折线图、直方图、柱形图、盒图、密度图等。

高级绘图

  • 分面与网格:使用 FacetGrid 实现数据按类别分面的可视化。
  • 联合分布图pairplot() 绘制成对变量之间关系的网格。

3.2.3 自定义与美化

  • 颜色与风格:Seaborn 提供多种配色方案和风格选项,便于创建美观的图形。
  • 注释与标签:通过参数如 hueannot 等实现更丰富的图形标注。

总结

Matplotlib 和 Seaborn 各有优势:

  • Matplotlib:更底层,灵活性高,适合需要精细控制的场景。
  • Seaborn:基于 Matplotlib,提供更高级的接口,适合快速绘制美观图形。

通过本章的学习,我们可以更好地利用这两个库进行数据分析和可视化,提升数据洞察力。希望大家在实践中多多练习,熟练掌握这些工具的使用。