1. 基本概念和历史背景
Matplotlib核心概念详解
Matplotlib 是 Python 中最流行的数据可视化库之一,它提供了一系列强大且灵活的工具,用于创建各种类型的图表和图形。无论你是数据科学家、工程师还是研究人员,理解 Matplotlib 的核心概念都能帮助你更高效地可视化数据。本文将详细介绍 Matplotlib 的核心概念,包括图形对象(Figure)、子图(Axes)、坐标轴(Axis)、刻度和刻度标签(Ticks and Tick Labels)、标注(Annotations)、图例(Legend)、样式(Styles)、图像(Images)、子图布局(Subplot Layouts)、交互和动画(Interactivity and Animation)、以及保存图形(Saving Figures)。
图形对象(Figure)
图形对象是 Matplotlib 中的顶层容器,它包含了所有的绘图元素。一个图形对象可以包含一个或多个子图(Axes)。每个图形对象可以看作是一个独立的绘图窗口或画布。
创建图形对象
你可以使用 plt.figure()
创建一个新的图形对象,并指定图形的大小和分辨率等属性。
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 6), dpi=100) # 创建一个宽8英寸,高6英寸,分辨率为100的图形对象
子图(Axes)
子图是图形对象中的实际绘图区域。每个子图包含了坐标系和绘制的图形元素。你可以在一个图形对象中创建多个子图,以便在同一个窗口中展示多个图形。
创建子图
你可以使用 fig.add_subplot()
或 plt.subplots()
创建子图。
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1) # 创建一个2行2列的子图网格,当前激活第一个子图
ax2 = fig.add_subplot(2, 2, 2)
或者使用更高级的 plt.subplots()
方法:
fig, axs = plt.subplots(2, 2, figsize=(10, 8)) # 创建一个2行2列的子图网格
坐标轴(Axis)
坐标轴是子图中的一个重要组成部分,它定义了数据的范围和刻度。每个子图通常包含两个坐标轴:x 轴和 y 轴。你可以通过坐标轴对象来设置刻度、标签、网格等属性。
ax.set_xlabel('x axis') # 设置 x 轴标签
ax.set_ylabel('y axis') # 设置 y 轴标签
ax.set_title('Sine Wave') # 设置图形标题
ax.grid(True) # 显示网格
刻度和刻度标签(Ticks and Tick Labels)
刻度和刻度标签用于标识坐标轴上的数值。你可以自定义刻度的位置和标签,以便更好地表示数据。
ax.set_xticks([0, 2, 4, 6, 8, 10]) # 设置 x 轴刻度位置
ax.set_xticklabels(['zero', 'two', 'four', 'six', 'eight', 'ten']) # 设置 x 轴刻度标签
标注(Annotations)
标注用于在图形中添加文本、箭头等注释,以便更好地解释数据。
ax.annotate('Max Point', xy=(np.pi/2, 1), xytext=(np.pi/2, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05))
图例(Legend)
图例用于标识图形中的不同数据系列。你可以通过 ax.legend()
方法来自动生成图例。
ax.plot(x, y, label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.legend() # 显示图例
样式(Styles)
Matplotlib 提供了一系列预定义的样式,你可以通过 plt.style.use()
方法来应用这些样式。
plt.style.use('ggplot')
图像(Images)
Matplotlib 还支持显示图像数据,你可以使用 imshow()
方法来显示二维图像。
image = np.random.rand(10, 10)
fig, ax = plt.subplots()
ax.imshow(image, cmap='gray')
子图布局(Subplot Layouts)
除了常规的子图布局,Matplotlib 还支持更复杂的布局,如 GridSpec
和 subplot2grid
。
import matplotlib.gridspec as gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 3)
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :-1])
ax3 = fig.add_subplot(gs[1:, -1])
ax4 = fig.add_subplot(gs[-1, 0])
ax5 = fig.add_subplot(gs[-1, -2])
plt.tight_layout()
plt.show()
交互和动画(Interactivity and Animation)
Matplotlib 支持交互和动画,你可以使用 FuncAnimation
类来创建动画。
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
line, = ax.plot(x, np.sin(x))
def update(frame):
line.set_ydata(np.sin(x + frame / 10.0))
return line,
ani = FuncAnimation(fig, update, frames=100, blit=True)
plt.show()
保存图形(Saving Figures)
你可以使用 savefig()
方法将图形保存为文件。
fig.savefig('sine_wave.png', dpi=300, bbox_inches='tight')
2. 安装
Matplotlib 可以通过 Python 的包管理工具 pip 进行安装:
pip install matplotlib
3. Ubuntu 中文字体安装和配置
为了在 Matplotlib 中正确显示中文字符,你可能需要在你的系统上安装中文字体,并进行相应的配置。
3.1 安装中文字体
在 Ubuntu 系统上,可以使用以下命令安装常见的中文字体:
sudo apt-get update
sudo apt-get install -y fonts-wqy-zenhei fonts-wqy-microhei
3.2 检查已安装的字体
安装完成后,可以使用 fc-list
命令来检查系统中是否有中文字体:
fc-list :lang=zh
你应该能看到类似下面的输出,这表明字体已经成功安装:
/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc: WenQuanYi Zen Hei,文泉驛正黑,文泉驿正黑:style=Regular
/usr/share/fonts/truetype/wqy/wqy-microhei.ttc: WenQuanYi Micro Hei,文泉驛微米黑,文泉驿微米黑:style=Regular
3.3 在 Matplotlib 中使用中文字体
找到字体文件路径后,可以在 Matplotlib 中使用这些字体。以下是如何在 Matplotlib 中设置字体的示例代码:
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# 示例数据
x = [1, 2, 3, 4]
y = [1, 4, 9, 16]
# 设置中文字体
font_path = '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc' # 替换为你找到的字体文件路径
font_prop = FontProperties(fname=font_path)
# 创建图形
plt.plot(x, y)
plt.xlabel('X 轴标签', fontproperties=font_prop)
plt.ylabel('Y 轴标签', fontproperties=font_prop)
plt.title('简单的线性图', fontproperties=font_prop)
# 保存图形为 JPG 文件
plt.savefig('my_plot.jpg', format='jpg')
# 如果仍然希望在屏幕上显示图形,可以保留 plt.show()
plt.show()
4. 主要功能和特点
4.1 图表类型
Matplotlib 支持多种图表类型,包括但不限于:
- 线性图(Line Plot)
- 散点图(Scatter Plot)
- 柱状图(Bar Chart)
- 直方图(Histogram)
- 饼图(Pie Chart)
- 箱线图(Box Plot)
- 极坐标图(Polar Plot)
- 三维图(3D Plot)
下面为每种图表类型提供一个示例:
线性图(Line Plot)
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [1, 4, 9, 16]
plt.plot(x, y)
plt.xlabel('X 轴标签')
plt.ylabel('Y 轴标签')
plt.title('简单的线性图')
plt.show()
散点图(Scatter Plot)
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [1, 4, 9, 16]
plt.scatter(x, y)
plt.xlabel('X 轴标签')
plt.ylabel('Y 轴标签')
plt.title('简单的散点图')
plt.show()
柱状图(Bar Chart)
import matplotlib.pyplot as plt
x = ['A', 'B', 'C', 'D']
y = [1, 4, 9, 16]
plt.bar(x, y)
plt.xlabel('分类')
plt.ylabel('值')
plt.title('简单的柱状图')
plt.show()
直方图(Histogram)
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randn(1000)
plt.hist(data, bins=30)
plt.xlabel('值')
plt.ylabel('频率')
plt.title('简单的直方图')
plt.show()
np.random.randn(1000)
是 NumPy 库中的一个函数调用,用于生成从标准正态分布(均值为0,标准差为1)中抽取的随机数。具体来说,这个函数会生成一个包含 1000 个随机数的一维数组。
bins=30
参数指定了将数据分成 30 个区间(也叫做桶),以便更好地可视化数据的分布。
饼图(Pie Chart)
import matplotlib.pyplot as plt
labels = ['A', 'B', 'C', 'D']
sizes = [15, 30, 45, 10]
plt.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.title('简单的饼图')
plt.show()
箱线图(Box Plot)
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.randn(100) for _ in range(4)]
plt.boxplot(data)
plt.xlabel('分类')
plt.ylabel('值')
plt.title('简单的箱线图')
plt.show()
python data = [np.random.randn(100) for _ in range(4)]
这行代码使用列表解析生成一个包含 4 个数组的列表。每个数组都包含 100 个从标准正态分布中抽取的随机数。具体来说,这个列表解析的执行过程如下:
- np.random.randn(100)
被调用 4 次,每次生成一个包含 100 个随机数的数组。
- 这 4 个数组被添加到一个列表中,最终形成 data
。
箱线图(Box Plot),又称盒须图或盒形图,是一种统计图表,用于展示数据分布的五个主要特征:最小值、第一四分位数(Q1)、中位数(第二四分位数,Q2)、第三四分位数(Q3)和最大值。箱线图还可以显示异常值(outliers)。它通过简单的图形方式展示数据的分布情况、中心趋势和离散程度。
箱线图的组成
-
箱体(Box):
- 下边缘(Lower Quartile, Q1):第一四分位数,即数据的下四分位数,表示数据的 25% 位点。
- 中位数(Median, Q2):第二四分位数,即数据的中位数,表示数据的 50% 位点。
- 上边缘(Upper Quartile, Q3):第三四分位数,即数据的上四分位数,表示数据的 75% 位点。
-
须(Whiskers):
- 下须(Lower Whisker):通常表示数据中的最小值,或者比 Q1 小 1.5 倍四分位距(IQR)的最小数据点。
- 上须(Upper Whisker):通常表示数据中的最大值,或者比 Q3 大 1.5 倍四分位距(IQR)的最大数据点。
- 四分位距(IQR, Interquartile Range):Q3 和 Q1 之间的距离,表示中间 50% 数据的范围。
-
异常值(Outliers):超出上下须范围的数据点,通常使用单独的标记(如圆点)表示。
箱线图的意义
- 数据的分布情况:通过箱体和须的长度,可以直观地了解数据的分布范围和离散程度。
- 中心趋势:中位数显示了数据的中心位置,可以反映数据的中心趋势。
- 对称性:箱体相对于中位数的对称性可以显示数据是否对称分布。
- 离群值:异常值可以快速识别数据中的离群点,有助于数据清洗和异常检测。
- 比较多个数据集:通过并排绘制多个箱线图,可以方便地比较不同数据集的分布情况。
极坐标图(Polar Plot)
import matplotlib.pyplot as plt
import numpy as np
theta = np.linspace(0, 2*np.pi, 100)
r = np.abs(np.sin(theta))
plt.polar(theta, r)
plt.title('简单的极坐标图')
plt.show()
极坐标图是一种使用极坐标系(角度和半径)来展示数据的图表类型。
-
生成角度数据:
theta = np.linspace(0, 2*np.pi, 100)
np.linspace
是 NumPy 中的一个函数,用于生成一个线性空间的数组。0
和2*np.pi
分别是数组的起始值和终止值。100
是生成的数组中的元素数量。theta
是一个包含从 0 到 2π 的 100 个等间距值的数组,表示角度数据。
-
计算半径数据:
r = np.abs(np.sin(theta))
np.sin(theta)
计算theta
数组中每个角度的正弦值,结果是一个数组。np.abs
计算数组中每个元素的绝对值,结果是一个非负数组。r
是一个包含theta
对应的正弦值绝对值的数组,表示半径数据。
-
使用极坐标绘制图形:
plt.polar(theta, r)
plt.polar
是 Matplotlib 中用于绘制极坐标图的函数。theta
是角度数据数组。r
是半径数据数组。- 这行代码使用极坐标系绘制了一个极坐标图,图形的每个点由对应的
theta
和r
值确定。
图表解释
- 极坐标图:极坐标图使用极坐标系来展示数据。极坐标系中的每个点由一个角度和一个半径确定。
- 角度(theta):从 0 到 2π 的 100 个等间距值,表示从 0 到 360 度的角度。
- 半径(r):
sin
函数的绝对值,表示每个角度对应的半径长度。
在这个示例中,极坐标图展示了 sin
函数的绝对值在从 0 到 2π 角度范围内的变化情况。由于 sin
函数在 0 和 π 处取值为 0,在 π/2 和 3π/2 处取值为 1 和 -1,因此图形呈现出一个对称的波形。
通过这段代码,你可以直观地了解 sin
函数在极坐标系中的表现形式。极坐标图特别适用于展示具有周期性和对称性的数据。
三维图(3D Plot)
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
x, y = np.meshgrid(x, y)
z = np.sin(np.sqrt(x**2 + y**2))
ax.plot_surface(x, y, z, cmap='viridis')
plt.title('简单的三维图')
plt.show()
-
创建一个新的图形对象:
fig = plt.figure()
plt.figure
创建一个新的图形对象,用于包含一个或多个子图。
-
添加一个三维坐标轴:
ax = fig.add_subplot(111, projection='3d')
fig.add_subplot(111, projection='3d')
在图形对象中添加一个子图,111
表示图形是 1 行 1 列的网格中的第一个子图。projection='3d'
参数指定这个子图是一个三维坐标轴。
-
生成 x 和 y 的数据:
x = np.linspace(-5, 5, 100) y = np.linspace(-5, 5, 100)
np.linspace
是 NumPy 中的一个函数,用于生成一个线性空间的数组。-5
和5
分别是数组的起始值和终止值。100
是生成的数组中的元素数量。x
和y
是包含从 -5 到 5 的 100 个等间距值的数组。
-
创建网格:
x, y = np.meshgrid(x, y)
np.meshgrid
是 NumPy 中的一个函数,用于从一维数组生成二维网格坐标。x
和y
是网格坐标的二维数组,表示每个点的 x 坐标和 y 坐标。
-
计算 z 的数据:
z = np.sin(np.sqrt(x**2 + y**2))
x**2 + y**2
计算每个点的平方和。np.sqrt
计算平方和的平方根。np.sin
计算平方根的正弦值。z
是一个二维数组,表示每个点的 z 坐标。
-
绘制三维曲面:
ax.plot_surface(x, y, z, cmap='viridis')
ax.plot_surface
是用于绘制三维曲面的函数。x
、y
和z
是网格坐标的二维数组,表示每个点的 x 坐标、y 坐标和 z 坐标。cmap='viridis'
指定了颜色映射(colormap),viridis
是一种常用的颜色映射方案。
-
设置图表标题:
plt.title('简单的三维图')
plt.title
设置图表的标题。'简单的三维图'
是图表的标题文本。
-
图表解释:
- 三维曲面图:三维曲面图展示了一个函数在二维平面上的值。每个点由三个坐标(x, y, z)确定。
- x 和 y 数据:从 -5 到 5 的 100 个等间距值,表示二维平面上的坐标。
- z 数据:
z = np.sin(np.sqrt(x**2 + y**2))
表示每个点的 z 坐标,函数的形式决定了曲面的形状。 - 颜色映射:
cmap='viridis'
指定了颜色映射方案,用于根据 z 值为曲面着色,帮助更好地理解数据的变化。
5 简洁模式与面向对象模式
Matplotlib 提供了两种主要的 API:面向对象的 API(Object-Oriented API)和 Pyplot API(即简洁模式)。以下是对这两种 API 的介绍:
Pyplot API(简洁模式)
Pyplot API 提供了一组类似于 MATLAB 的命令式函数,使得绘图过程更加简洁和直观。这种方法适合快速创建简单的图形,非常适合初学者和简单的绘图需求。
- 函数调用:通过直接调用
matplotlib.pyplot
模块中的函数来进行绘图和设置属性。 - 自动管理对象:Pyplot 会自动创建和管理
Figure
和Axes
对象,因此你不需要手动创建它们。
示例代码:
import matplotlib.pyplot as plt
# 直接使用 pyplot 的函数进行绘图
plt.plot([1, 2, 3], [4, 5, 6])
# 设置标题和标签
plt.title('标题')
plt.xlabel('X轴标签')
plt.ylabel('Y轴标签')
# 显示图形
plt.show()
面向对象的 API(Object-Oriented API)
面向对象的 API 提供了更灵活和强大的方式来创建和管理图形和子图。通过直接操作图形对象和轴对象,你可以更精细地控制绘图的各个方面。这种方法适合复杂的绘图需求,尤其是当你需要创建多个子图或在同一图中进行多次绘制时。
- 创建图形和轴对象:你首先需要创建一个
Figure
对象和一个或多个Axes
对象。 - 方法调用:通过调用这些对象的方法来进行绘图和设置属性。
示例代码:
import matplotlib.pyplot as plt
# 创建一个 Figure 对象和一个 Axes 对象
fig, ax = plt.subplots()
# 使用 Axes 对象进行绘图
ax.plot([1, 2, 3], [4, 5, 6])
# 设置标题和标签
ax.set_title('标题')
ax.set_xlabel('X轴标签')
ax.set_ylabel('Y轴标签')
# 显示图形
plt.show()
- 面向对象的 API:提供更多控制和灵活性,适合复杂绘图。
- Pyplot API:更简洁直观,适合快速创建简单图形。
根据你的需求和复杂度,可以选择合适的 API 来进行绘图。
6 多图管理
Matplotlib 支持在一个图形窗口中绘制多个子图(subplot),可以使用 subplot
函数或者 GridSpec
模块进行更复杂的布局管理。下面是一个完整的示例,展示如何在一个图形窗口中绘制多个子图。
示例代码
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
z = np.random.randn(100)
# 创建一个 2x2 的子图网格
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
# 子图1:线性图
axs[0, 0].plot(x, y, color='blue')
axs[0, 0].set_title('子图1: 线性图')
axs[0, 0].set_xlabel('X 轴')
axs[0, 0].set_ylabel('Y 轴')
# 子图2:散点图
axs[0, 1].scatter(x, y, color='red')
axs[0, 1].set_title('子图2: 散点图')
axs[0, 1].set_xlabel('X 轴')
axs[0, 1].set_ylabel('Y 轴')
# 子图3:柱状图
axs[1, 0].bar(np.arange(10), np.random.randint(1, 10, size=10), color='green')
axs[1, 0].set_title('子图3: 柱状图')
axs[1, 0].set_xlabel('分类')
axs[1, 0].set_ylabel('值')
# 子图4:直方图
axs[1, 1].hist(z, bins=20, color='purple')
axs[1, 1].set_title('子图4: 直方图')
axs[1, 1].set_xlabel('值')
axs[1, 1].set_ylabel('频率')
# 调整子图布局,避免重叠
plt.tight_layout()
# 显示图形
plt.show()
- 子图1:线性图:展示了
x
和y
的线性关系,y
是x
的正弦值。 - 子图2:散点图:展示了
x
和y
的散点分布,y
是x
的正弦值。 - 子图3:柱状图:展示了 10 个分类的随机值。
- 子图4:直方图:展示了
z
数据的频率分布,z
是从标准正态分布中抽取的随机数。
11. 面向对象的 API进一步的示例
直线图展示销量关系
import matplotlib.pyplot as plt
y = [1, 4, 9, 16, 25, 36, 49, 64]
x1 = [1, 16, 30, 42, 55, 68, 77, 88]
x2 = [1, 6, 12, 18, 28, 40, 52, 65]
# 创建图形和轴
fig, ax = plt.subplots()
l1 = ax.plot(x1, y, 'ys-') # 使用简写的形式color/标记符/线型
l2 = ax.plot(x2, y, 'go--')
ax.legend(labels=('tv', 'Smartphone'), loc='lower right') # legend 放置在右下角
ax.set_title("Advertisement effect on sales")
ax.set_xlabel('medium')
ax.set_ylabel('sales')
plt.show()
# 创建图形和轴
fig, ax = plt.subplots()
- 创建一个图形(
fig
)和一个子绘图区域(轴,ax
),用于在其上进行绘图。
l1 = ax.plot(x1, y, 'ys-') # 使用简写的形式color/标记符/线型
- 在轴上绘制第一条线,使用
x1
作为横坐标,y
作为纵坐标,'ys-'
表示颜色为黄色(y
),标记符为正方形(s
),并使用实线(-
)。
l2 = ax.plot(x2, y, 'go--')
- 在轴上绘制第二条线,用
x2
作为横坐标,y
作为纵坐标,'go--'
表示颜色为绿色(g
),标记符为圆圈(o
),并使用虚线(--
)。
ax.legend(labels=('tv', 'Smartphone'), loc='lower right') # legend 放置在右下角
- 添加图例,标识两条线所代表的广告媒介,
labels
参数用于指定图例中显示的名称,loc
参数用来设定图例的位置,这里为右下角。
新建的子图与现有的子图重叠
import matplotlib.pyplot as plt
plt.figure(1)
plt.plot([1, 2, 3])
# 现在创建一个子图,它表示一个有2行1列的网格的顶部图。
# 因为这个子图将与第一个重叠,所以之前创建的图将被删除
plt.subplot(211)
plt.plot(range(12))
# 创建带有黄色背景的第二个子图
plt.subplot(212, facecolor='y')
plt.plot(range(12))
plt.show()
通过给画布添加 axes
对象可以实现在同一画布中插入另外的图像
import matplotlib.pyplot as plt
import numpy as np
import math
# 生成 x 数据,从 0 到 2π,步长为 0.05
x = np.arange(0, math.pi * 2, 0.05)
# 创建一个新的图形对象
fig = plt.figure()
# 添加主绘图区域(Axes 对象)
axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 主图
# 添加内嵌绘图区域(Axes 对象)
axes2 = fig.add_axes([0.55, 0.55, 0.3, 0.3]) # 内嵌图
# 生成 y 数据,即 x 的正弦值
y = np.sin(x)
# 在主绘图区域中绘制 x 和 y 的关系,颜色为蓝色
axes1.plot(x, y, 'b')
# 在内嵌绘图区域中绘制 x 和余弦值的关系,颜色为红色
axes2.plot(x, np.cos(x), 'r')
# 设置主绘图区域的标题为 "sine"
axes1.set_title('sine')
# 设置内嵌绘图区域的标题为 "cosine"
axes2.set_title("cosine")
# 显示图形
plt.show()
添加主绘图区域(Axes 对象):
python axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 主图
- fig.add_axes([0.1, 0.1, 0.8, 0.8])
在图形对象中添加一个主绘图区域(Axes 对象)。
- 参数 [0.1, 0.1, 0.8, 0.8]
定义了主绘图区域在图形中的位置和大小,分别表示左边距、底边距、宽度和高度,取值范围为 0 到 1,表示相对于图形的百分比。
添加内嵌绘图区域(Axes 对象):
python axes2 = fig.add_axes([0.55, 0.55, 0.3, 0.3]) # 内嵌图
- fig.add_axes([0.55, 0.55, 0.3, 0.3])
在图形对象中添加一个内嵌绘图区域(Axes 对象)。
- 参数 [0.55, 0.55, 0.3, 0.3]
定义了内嵌绘图区域在图形中的位置和大小,分别表示左边距、底边距、宽度和高度,取值范围为 0 到 1,表示相对于图形的百分比。
显示坐标轴刻度
import matplotlib.pyplot as plt
import numpy as np
# 创建一个包含 1 行 2 列的子图网格,并设置图形大小为 (10, 4) 英寸
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
# 生成 x 数据,从 1 到 4 的数组
x = np.arange(1, 5)
# 子图1:绘制 x 与 e^x 和 x^2 的关系,使用普通尺度
axes[0].plot(x, np.exp(x))
axes[0].plot(x, x**2)
axes[0].set_title("Normal scale")
# 子图2:绘制 x 与 e^x 和 x^2 的关系,使用对数尺度
axes[1].plot(x, np.exp(x))
axes[1].plot(x, x**2)
axes[1].set_yscale("log")
axes[1].set_title("Logarithmic scale (y)")
# 设置子图1的 x 轴和 y 轴标签
axes[0].set_xlabel("x axis")
axes[0].set_ylabel("y axis")
axes[0].xaxis.labelpad = 10 # 设置 x 轴标签与轴线的距离
# 设置子图2的 x 轴和 y 轴标签
axes[1].set_xlabel("x axis")
axes[1].set_ylabel("y axis")
# 显示图形
plt.show()
- 图形对象:创建了一个新的图形对象,并在其中添加了两个子图。
- 数据生成:生成了从 1 到 4 的 x 数据。
- 绘图:在第一个子图中绘制了 x 与 e^x 和 x^2 的关系,使用普通尺度。在第二个子图中绘制了相同的数据,但使用对数尺度来展示 y 轴的变化。
- 自定义标签和标题:为每个子图设置了 x 轴和 y 轴的标签以及图形标题。
坐标轴颜色显示
import matplotlib.pyplot as plt
# 创建一个包含单个子图的图形对象
fig, ax = plt.subplots()
# 设置底部轴的颜色为蓝色
ax.spines['bottom'].set_color('blue')
# 设置左侧轴的颜色为红色
ax.spines['left'].set_color('red')
# 设置左侧轴的线宽为 2
ax.spines['left'].set_linewidth(2)
# 隐藏右侧轴
ax.spines['right'].set_color(None)
# 隐藏顶部轴
ax.spines['top'].set_color(None)
# 在子图中绘制数据 [1, 2, 3, 4, 5]
ax.plot([1, 2, 3, 4, 5])
# 显示图形
plt.show()
Matplotlib 设置坐标轴
import matplotlib.pyplot as plt
import math
# 生成信号
fs = 1000 # 采样频率,一秒1000个点
f = 10 # 信号频率,一秒10个波形
t = list(range(0, 1000)) # 时间序列,0-999
t = [x / fs for x in t] # 将时间序列归一化,实际是1秒内的1000个时间点
a = [math.sin(2 * math.pi * f * x) for x in t] # 生成正弦信号
# 作图
plt.figure() # 创建一个新的图形对象
# 子图1
plt.subplot(2, 2, 1) # 创建一个2行2列的子图网格,当前激活第一个子图
plt.plot(a) # 绘制正弦信号
plt.title('Figure-1') # 设置子图标题
# 子图2
plt.subplot(2, 2, 2) # 当前激活第二个子图
plt.plot(a) # 绘制正弦信号
plt.xticks([]) # 隐藏x轴刻度
plt.title('Figure-2') # 设置子图标题
# 子图3
plt.subplot(2, 2, 3) # 当前激活第三个子图
plt.plot(a) # 绘制正弦信号
plt.yticks([]) # 隐藏y轴刻度
plt.title('Figure-3') # 设置子图标题
# 子图4
plt.subplot(2, 2, 4) # 当前激活第四个子图
plt.plot(a) # 绘制正弦信号
plt.axis('off') # 隐藏所有轴线和刻度
plt.title('Figure-4') # 设置子图标题
# 显示图形
plt.show()
- 图形对象:创建了一个新的图形对象,并在其中添加了四个子图。
- 信号生成:生成了从 0 到 999 的时间序列,并计算了对应的正弦信号。
- 绘图:在每个子图中绘制了相同的正弦信号,但在坐标轴的显示方式上有所不同:
- 第一个子图显示完整的坐标轴和刻度。
- 第二个子图隐藏了 x 轴刻度。
- 第三个子图隐藏了 y 轴刻度。
- 第四个子图隐藏了所有轴线和刻度。
- 显示图形:最终显示了生成的图表。
刻度和标签的使用
import matplotlib.pyplot as plt
import numpy as np
import math
# 生成 x 数据,从 0 到 2π,步长为 0.05
x = np.arange(0, math.pi * 2, 0.05)
# 创建一个新的图形对象
fig = plt.figure()
# 添加一个绘图区域(Axes 对象)
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
# 生成 y 数据,即 x 的正弦值
y = np.sin(x)
# 在绘图区域中绘制 x 和 y 的关系
ax.plot(x, y)
# 设置 x 轴标签
ax.set_xlabel('angle')
# 设置图形标题
ax.set_title('sine')
# 设置 x 轴刻度位置
ax.set_xticks([0, 2, 4, 6])
# 设置 x 轴刻度标签
ax.set_xticklabels(['zero', 'two', 'four', 'six'])
# 设置 y 轴刻度位置
ax.set_yticks([-1, 0, 1])
# 显示图形
plt.show()
- 自定义轴标签和刻度:设置了 x 轴和 y 轴的标签,并自定义了 x 轴的刻度位置和标签,以及 y 轴的刻度位置。
这种方法非常适合用于生成和自定义各种类型的图表,帮助更好地理解和展示数据。
grid()
设置网格格式
import matplotlib.pyplot as plt
import numpy as np
# 创建一个包含 1 行 3 列的子图网格,并设置图形大小为 (12, 4) 英寸
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
# 生成 x 数据,从 1 到 10 的数组
x = np.arange(1, 11)
# 子图1:绘制 x 与 x^3 的关系,并设置默认网格
axes[0].plot(x, x**3, 'g', lw=2) # 'g' 表示绿色,lw=2 表示线宽为 2
axes[0].grid(True) # 开启默认网格
axes[0].set_title('default grid') # 设置子图标题
# 子图2:绘制 x 与 e^x 的关系,并设置自定义网格
axes[1].plot(x, np.exp(x), 'r') # 'r' 表示红色
axes[1].grid(color='b', ls='-.', lw=0.25) # 设置网格颜色为蓝色,线型为点划线,线宽为 0.25
axes[1].set_title('custom grid') # 设置子图标题
# 子图3:绘制 x 与 x 的关系,不设置网格
axes[2].plot(x, x)
axes[2].set_title('no grid') # 设置子图标题
# 调整子图布局,避免重叠
fig.tight_layout()
# 显示图形
plt.show()
12. 总结
在本篇文档中,我们详细介绍了如何使用 Matplotlib 进行数据可视化,从基础的安装和配置到各种复杂的图表类型和高级功能。通过这些示例,你可以掌握 Matplotlib 的基本用法,并在实际项目中灵活运用它来进行数据可视化。
12.1 基础示例
我们首先展示了如何绘制简单的线性图、散点图、柱状图、直方图、饼图、箱线图、极坐标图和三维图。每种图表类型都有对应的示例代码,帮助你快速上手。
12.2 高级功能
我们还介绍了如何生成动画、创建三维图形,以及管理多个子图。通过这些高级功能,你可以创建更加复杂和动态的图表。
12.3 进一步的示例
我们提供了一系列进一步的示例,包括如何设置坐标轴、添加网格、显示坐标轴刻度、以及如何在同一画布中插入多个图像。这些示例展示了 Matplotlib 的强大功能和灵活性。