0%

matplotlib入门与实战

在机器学习中为了便于理解,我们经常要绘制各种图形,如:散点图、折线图、柱状图等,matplotlib是一个非常强大的绘图库,今天咱们就来看看如何使用matplotlib绘制各种图形。

matplotlib中的重要概念

想要快速入门matplotlib,我们必须先了解matplotlib的几个基本概念:

  • Figure(画布):Figure是matplotlib中绘制图形的基本单位,它相当于一块画布,在画布中可以放置多个子图,每个子图都是一个Axes对象。
  • Axes(坐标轴):axes对象是matplotlib中另一个重要对象,在axes中可以绘制各种图形,如散点图、折线图、柱状图等。
  • Axis(坐标轴范围):坐标轴范围是axes对象中绘制图形的边界,如x轴范围、y轴范围等。

接下来咱们来看看matplotlib的绘制流程:

  • 在使用matplotlib绘制图形时,首先需要创建一个Figure对象,并设置其大小。
  • 之后,在Figure对象中创建一个Axes对象,并设置其坐标轴范围。
  • 接下来,你就可以在Axes对象中绘制图形啦,如散点图、折线图、柱状图等。

了解了这些matplotlib的基本概念之后,咱们就来看看每个对象都能做哪些事儿吧!

Figure对象

首先,咱们先来看看figure对象。如我们上面所介绍了,figure就是一张画布,在开始使用画布之前,我们需要先创建一个figure对象。代码如下:

1
2
import matplotlib.pyplot as plt
fig = plt.figure()

上面代码中非常简单,我就不做解释了。

默认情况下,figure的大小为为6英寸宽、4英寸高。如果你想设置画布的大小,可以用下面的方式实现:

1
2
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 6))

代码中,我们使用figsize参数设置了画布的大小,其为8英寸宽、6英寸高。

注意,画布的单位是英寸,而不是像素。 英寸和像素之比是1:72,所以8英寸宽、6英寸高的画布,实际大小为8*72=576、6*72=432。

除了上面创建Figure对象之外,还有一种创建Figure对象的方式,代码如下:

1
fig, ax = plt.subplots(2,1,figsize=(8, 6))

上述代码中,同时创建了一个Figure对象和一个Axes对象数组,在Axes数组中,保存了两个Axes对象,分别为ax[0]和ax[1]。同时,在创建Figure对象时,为其设置了大小,宽8英寸、高6英寸。

当然,除了可以通过Figure设置画布大小外,我们还可以为其设置背景颜色,来看个例子:

1
2
3
...
fig = plt.figure(figsize=(8, 6), facecolor='#f0f0f0')
...

上面代码中,我们设置了画布的背景颜色为#f0f0f0,也就是浅灰色。

Axes对象

下面咱们来看看Axes对象。Axes对象可做的事儿要比Figure对象多得多,如绘制各种图形,设置坐标轴范围,设置坐标轴标签等。

我们先来看看如何通过Axes对象为图形设置title,代码如下:

1
2
3
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_title('my title')

代码中,我们通过ax.set_title()方法为图形设置了title。

那么,如何为Axes对象设置坐标轴范围呢?其实也很简单,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)

代码中,我们通过ax.set_xlim()和ax.set_ylim()方法为x轴和y轴设置了范围,范围为0到10。

接下来,我们看看如何为Axes对象设置坐标轴标签,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xlabel('x')
ax.set_ylabel('y')

代码中,我们通过ax.set_xlabel()和ax.set_ylabel()方法为x轴和y轴设置了标签,分别为xy

再下来,我们看看如何为Axes对象设置坐标轴刻度,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xticks([0, 2, 4, 6, 8, 10])
ax.set_yticks([0, 2, 4, 6, 8, 10])

代码中,我们通过ax.set_xticks()和ax.set_yticks()方法为x轴和y轴设置了刻度,分别为0、2、4、6、8、10。

再下来,我们看看如何为Axes对象设置坐标轴刻度标签,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_xticklabels(['0', '2', '4', '6', '8', '10'])
ax.set_yticklabels(['0', '2', '4', '6', '8', '10'])

代码中,我们通过ax.set_xticklabels()和ax.set_yticklabels()方法为x轴和y轴设置了刻度标签,分别为0、2、4、6、8、10。

最后,我们看看如何为Axes对象设置坐标轴刻度标签的格式,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 6))
ax.xaxis.set_major_formatter(plt.FormatStrFormatter('%.2f'))
ax.yaxis.set_major_formatter(plt.FormatStrFormatter('%.2f'))

代码中,我们通过ax.xaxis.set_major_formatter()和ax.yaxis.set_major_formatter()方法为x轴和y轴设置了刻度标签的格式,为%.2f。

绘制图形

上面都是一些开胃菜,接下来的内容才是我们的重点。来看看如何通过matplotlib绘制各种图形,如散点图、折线图、柱状图等。

先来看看如何绘制散点图,代码如下:

1
2
3
4
5
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.scatter(x, y)
plt.show()

代码中,我们通过plt.scatter()方法绘制了散点图,x坐标从0到10,y坐标由sin(x)指定。

非常简单对吧,再来看如何绘制直线图,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
points = [(1, 2), (7, 8)]
plt.plot(*points)
plt.show()

代码中,我们通过plt.plot()方法绘制了直线图,起始点为(1, 2),终止点为(7, 8)。

那么如何绘制柱状图呢?代码如下:

1
2
3
4
5
import matplotlib.pyplot as plt
x = [1, 5, 9, 13, 17, 21]
y = [10, 8, 6, 15, 20, 30]
plt.bar(x, y)
plt.show()

代码中,我们通过plt.bar()方法绘制了柱状图,x坐标从1到21,y坐标从10到30。

再接下来,我们看看如何绘制折线图,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
m = [2, 3, -1, 1, -2]
plt.plot(m)
plt.show()

与绘制直线图类似,绘制折线图也是通过plt.plot()方法,其中 m 代表的是 Y 值。当你使用 plt.plot() 函数且只提供一个列表或数组时,matplotlib 会默认这个列表或数组是 Y 坐标的数据,而 X 坐标的数据会自动设置为 Y 数据的索引(从 0 开始的整数序列)

当然,我们也可以直接为折线图提供 X 的数据和 Y 数据,代码如下:

1
2
3
4
5
import matplotlib.pyplot as plt
n = [0, 1, 2, 3, 4]
m = [2, 3, -1, 1, -2]
plt.plot(n, m)
plt.show()

代码中,我们通过plt.plot()方法绘制了折线图,x轴的坐标从n列表中取,y轴的坐标从m列表中取。

我们还可以对折线做更细致的控制,如线型、颜色等等,代码如下:

1
2
3
...
plt.plot(n, m, color='k', linestyle='-.', linewidth=3, marker='p', markersize=15, markeredgecolor='b', markerfacecolor='r')
plt.show()

代码中,我们通过plt.plot()方法绘制了折线图,x轴的坐标从n列表中取,y轴的坐标从m列表中取,颜色为黑色,线型为虚线,线宽为3,标记为五角星形状,标记大小为15,标记边框颜色为蓝色,标记填充颜色为红色。

除了上面的图型外,我们还可以使用matplotlib绘制饼图,代码如下:

1
2
3
4
5
import matplotlib.pyplot as plt
labels = ['A', 'B', 'C']
sizes = [30, 20, 50]
plt.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.show()

代码中,我们通过plt.pie()方法绘制了饼图,labels为标签,sizes为数据,autopct为百分比格式。

也可以使用matplotlib绘制直方图,代码如下:

1
2
3
4
import matplotlib.pyplot as plt
x = np.random.randn(1000)
plt.hist(x, bins=30)
plt.show()

上面是最简单的直方图,下面这个直方图就比较复杂了,代码如下:

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

# 创建两个具有不同均值的正态分布数据集
data1 = np.random.normal(loc=-2.0, scale=1.0, size=1000)
data2 = np.random.normal(loc=2.0, scale=1.0, size=1000)

# 合并数据集
data = np.concatenate((data1, data2))

# 绘制直方图
plt.hist(data, bins=50, alpha=0.7, color='skyblue', edgecolor='black', histtype='bar', orientation='vertical', rwidth=0.8, log=False)

# 添加标题和轴标签
plt.title('Bimodal Distribution Histogram')
plt.xlabel('Value')
plt.ylabel('Frequency')

# 显示图形
plt.show()

这个例子中,我们创建了两个具有不同均值的正态分布数据集,然后将它们合并为一个数据集,最后绘制出直方图。

hist函数中每个参数的含义如下:

  • bins:直方图的条数,默认值为10
  • alpha:透明度,默认值为1
  • color:颜色,默认值为’b’
  • edgecolor:边框颜色,默认值为’k’
  • histtype:直方图的类型,默认值为’bar’
  • orientation:直方图的方向,默认值为’vertical’
  • rwidth:直方图的宽度,默认值为1
  • log:是否使用对数坐标轴,默认值为False

matplotlib除了可以绘制上面这些基本图形外,还可以在同一张图上绘制多个图形,这个功能对于我们分析数据特别有帮助,接下来我们就来看看如何在一张图中绘制多个子图。

绘制子图

在同一个Figure上绘制多个子图,需要使用plt.subplot函数,该函数在创建Figure对象的同时创建一个Axes对象数组,其中每一个Axes对象负责一个子图的绘制。

下面我们看看如何绘制一个包含两个子图的figure,代码如下:

1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt
import numpy as np
fig, axs = plt.subplots(2, 1)

x = np.linspace(0, 10, 10)
y = np.sin(x)

axs[0].plot(x, y)
axs[1].scatter(x, y)
plt.show()

代码中,我们通过plt.subplots()函数创建了一个Figure对象和一个Axes对象数组,Axes数组中包括两个Axes对象,其中axs[0]负责绘制第一幅子图,axs[1]负责绘制第二幅子图,而且创建的是两行一列的两个子图。

另外,我们还可以为每个子图单独设置标题,代码如下:

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
fig, axs = plt.subplots(2, 1)
plt.suptitle("Figure Title")

x = np.linspace(0, 10, 10)
y = np.sin(x)

axs[0].plot(x, y)
axs[0].set_title('Subplot 1')

axs[1].scatter(x, y)
axs[1].set_title('Subplot 2')

plt.tight_layout()
plt.show()

代码中,我们通过plt.suptitle()函数为整个Figure设置一个标题,通过axs[0].set_title()和axs[1].set_title()函数为每个子图设置标题。同时使用plt.tight_layout()函数来调整子图之间的间距,避免出现重叠的情况。

如何绘制更加复杂的子图呢? 代码如下:

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
32
33
import matplotlib.pyplot as plt
from matplotlib import gridspec

# 创建 figure
fig = plt.figure(figsize=(10, 8))

# 创建一个 GridSpec 对象
gs = gridspec.GridSpec(2, 2, figure=fig)

# 创建一个大的子图占据整个网格
ax_big = fig.add_subplot(gs[:, :])

# 在大的子图中创建四个小的子图
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, 0])
ax4 = fig.add_subplot(gs[1, 1])

# 可以在每个小的子图中绘制内容
# 例如,在 ax1 中绘制一个线图
ax1.plot([1, 2, 3], [1, 2, 3])

# 在大的子图上设置标题
ax_big.set_title('Big Title', fontsize=14)

# 隐藏大子图的坐标轴,只显示小子图的坐标轴
ax_big.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False)

ax_big.set_frame_on(False)
ax_big.set_ylabel('Y', fontsize=14)
ax_big.set_xlabel('X', fontsize=14)

plt.show()

上述代码创建了一个 2x2 的网格,即GridSpec对象,然后根据gs对象创建了五个子图,其中 ax_big 占据了整个网格,而ax[1-4]用于绘制四个子图的内容。另外,代码中还隐藏了大子图的坐标轴,只显示小子图的坐标轴。

以上就是通过matplotlib绘制多个子图的例子,当然matplotlib还支持绘制3D图形,我们简要的了解一下吧。

绘制3D图

如上所述,matplotlib 不仅可以绘制2D图形,而且还支持绘制3D图形,我们来看一个具体的例子:

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.arange(-5, 5, 0.25)
y = np.arange(-5, 5, 0.25)
x, y = np.meshgrid(x, y)
z = np.sin(np.sqrt(x**2 + y**2))
ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap='viridis')
plt.show()

这个例子中,首先创建了一个Figure对象,然后添加了一个Axes对象,并指定了投影为3D。然后我们创建了一个三维的x、y、z坐标,并通过plot_surface()方法绘制了曲面图。

相对来说,matplotlib绘制3D要比绘制2D图形复杂一些,最主要的是你要了解3D图型的一些公式和知识,否则的话很难绘制出你想要的图型,对于更多的3D图绘制,可以参考matplotlib的官方文档

小结

以上就是matplotlib入门的一些例子,希望对大家有所帮助!

欢迎关注我的其它发布渠道