NumPy(Numerical Python)是Python中用于科学计算的核心库,其核心是 其强大的N维数组对象ndarray,它比Python内置的列表(list)在处理大量数据时更高效。ndarray支持多种数据类型,包括整数、浮点数、布尔值、复数等;允许不同形状的数组在运算时进行对齐,从而避免了显式地复制数据,提升了效率。NumPy的操作通常是向量化的,即对整个数组进行操作,而不是对数组中的每个元素进行循环操作。这种方式能够极大地提高计算效率。NumPy允许在不同形状的数组之间执行操作,通过广播功能,它可以自动调整数组的形状,以使操作变得有效。NumPy提供了丰富的数学函数和工具来支持高效的数据处理与数值计算。包括线性代数、傅里叶变换、随机数生成等。支持统计函数,如计算均值、标准差、最大值、最小值等。NumPy提供了强大的索引和切片功能,支持布尔索引、花式索引等高级索引操作,使得数据操作更加灵活和方便。NumPy的底层实现是用C语言编写的,因此它在处理大规模数据时非常高效。NumPy可以与许多其他Python库和数据格式(例如Pandas、SciPy、Matplotlib)无缝集成,使得数据科学工作流更加流畅。NumPy可以有效地存储和处理大型多维数组,适用于存储和操作各种类型的数据,包括数字、字符串、布尔值等。通过NumPy的强大的索引和切片功能,可以对数据进行筛选、切片、随机抽样等操作,使得数据清洗和预处理更加灵活。NumPy提供了丰富的数学函数和运算符,可以进行各种数值计算和统计分析,包括求平均值、标准差、相关系数、协方差等。支持线性代数运算,如矩阵乘法、逆矩阵、特征值分解等,为科学研究提供了强大的数学工具。NumPy提供了傅里叶变换等信号处理工具,可以用于分析信号的频率特性、滤波等任务。
Matplotlib 是 Python 中一个功能强大且广泛使用的数据可视化库,支持线图、散点图、柱状图、饼图、直方图、热图、3D 图等,满足不同场景的数据展示需求。用户可自定义颜色、线型、标签、标题、坐标轴范围等,甚至支持 LaTeX 数学公式渲染,提升图表专业性。与 NumPy、Pandas等库紧密协作,简化数据处理到可视化的流程。核心概念为Figure(画布):顶层容器,控制图形大小、分辨率和背景,可包含多个子图(Axes)。Axes(子图):实际绘图区域,包含坐标轴、标签、标题等,支持多子图布局。Axis(坐标轴):控制刻度、标签和范围,支持对数坐标等高级设置。Artist(图形元素):所有可见元素的基类,如线条、标记、文本等,通过修改 Artist 实现精细定制。
以下以一个大学物理电学的题目为例,来演示一下这两个库的使用。
半径为R的均匀带电球面所带电量为+q,试求在球面外任一点产生的电势;请用python解题并绘出示意图。
import numpy as np #导入NumPy 库并简称为np
import matplotlib.pyplot as plt # 导入 Matplotlib 的绘图接口并简称为plt
from matplotlib import cm #从 Matplotlib 导入颜色映射(Colormap)模块
from mpl_toolkits.mplot3d import Axes3D #导入 Matplotlib 的 3D 绘图工具包。
plt.rcParams["font.family"] = ["SimHei"] #设置 Matplotlib 的默认字体为黑体(SimHei)。
plt.rcParams["axes.unicode_minus"] = False # 禁用 Unicode 减号(−),改用 ASCII 减号(-)
# 解决负号(-)显示为方块或乱码的问题。
#部分字体不支持 Unicode 减号,导致负号显示异常。
# 设置参数
R = 1.0 # 球面半径
q = 1.0 # 球面带电量(单位电荷)
k = 1.0 # 1/(4πϵ₀) = 1,简略这样设置,方便计算
# 创建网格
x = np.linspace(-2.5*R, 2.5*R, 100)
y = np.linspace(-2.5*R, 2.5*R, 100)
X, Y = np.meshgrid(x, y)
# 计算到原点的距离
r = np.sqrt(X**2 + Y**2)
# 计算电势分布
V = np.where(r <= R, k * q / R, k * q / r)
# 计算半径为R的均匀带电球面(电量为q)在空间各点的电势V,并根据位置r自动选择
# 不同的计算公式:
# 球面内部(r ≤ R):电势为常数k*q/R
# 球面外部(r > R):电势与距离成反比k*q/r
# 创建三维图形
fig = plt.figure(figsize=(14, 10))
# 使用 Matplotlib 创建了一个图形窗口(Figure),用于后续绘制图表;指定图形窗口的大
# 小,单位为英寸(inch)。元组(14, 10)表示宽度为 14 英寸,高度为 10 英寸。
fig.suptitle('均匀带电球面的电势分布', fontsize=16)
# 1. 三维曲面图
ax1 = fig.add_subplot(221, projection='3d')
‘’‘
在之前创建的fig(图形窗口对象)中添加一个子图(Axes对象),并指定该子图为三维绘图模式。221:这是一种简洁的子图布局参数表示方式,它表示将整个图形窗口划分为 2 行 #2 列(共 4 个子图区域),当前要添加的子图位于第 1 个位置(按从左到右、从上到下的#顺序计数)。等同于使用更详细的参数写法fig.add_subplot(2, 2, 1),这种写法明确指定了行#数、列数和子图序号。projection='3d':表明这个子图是用于绘制三维图形的,启用了三维#坐标系相关的功能,后续可以在这个子图中绘制三维的曲面、散点等图形元素。
’‘’
surf = ax1.plot_surface(X, Y, V, cmap=cm.viridis, rstride=2, cstride=2, alpha=0.8)
#在已创建的三维子图ax1上绘制一个三维曲面。X、Y、V:通常分别代表三维曲面在 x、y、
#z 方向上的坐标数据。X和Y一般是通过 numpy.meshgrid 等函数生成的二维网格数据(形
#状相同且对应的元素构成曲面上点的 x、y 坐标),V 是对应每个 (X, Y) 坐标点处的 z 值(在
#这里代表电势值),用于确定曲面的高度。cmap=cm.viridis:指定了颜色映射(Colormap)
#为 viridis。颜色映射决定了如何根据 z 值(即 V 中的数据)为曲面的不同部分分配颜色,#viridis 是一种常用的、视觉效果较好的顺序性颜色映射,它能将较低值映射到冷色调(如
#蓝色),较高值映射到暖色调(如黄色),便于直观地看出数据的变化趋势。#rstride=2 和 cstride=2:分别控制曲面在行(r 代表 row,对应 y 方向)和列(c 代表 column,
#对应 x 方向)方向上的采样间隔。数值为 2 表示每隔一行(或一列)取一个数据点来绘制
#曲面,这样做可以在一定程度上减少数据量,加快绘图速度,同时在视觉效果上也能避免
#曲面过于密集(如果数据量很大时),让图形更清晰一些。不过取值过大可能会导致曲面看
#起来不够平滑。alpha=0.8:设置曲面的透明度为 0.8(取值范围是 0 到 1),透明度的设置
#可以让图形在视觉上有层次感,例如当有多个图形元素重叠时,通过透明度可以看到后面
#的元素,或者营造出一种半透明的视觉效果,使图形看起来更美观、更易于观察。
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('电势 V(r)')
ax1.set_title('三维电势分布曲面')
fig.colorbar(surf, ax=ax1, shrink=0.5, aspect=5, label='电势')
”””
在整个图形窗口fig中添加一个颜色条(Colorbar),用于展示颜色映射(cmap)与具体数值(在这里就是电势值)之间的对应关系。surf:是之前绘制的三维曲面对象,颜色条会根据这个曲面所使用的颜色映射来生成对应的刻度和颜色区间展示,使其与曲面上的颜色显示相对应。ax=ax1:指定颜色条关联的子图为 ax1,这样颜色条的位置和尺寸等会根据这个子图的布局来合理调整,通常会放置在子图旁边合适的位置。shrink=0.5:设置颜色条的缩放比例为 0.5,即把颜色条的宽度(或高度,取决于布局)缩小为默认大小的一半,以更好地适应图形窗口的空间布局,避免颜色条过大或过小影响整体美观和可读性。aspect=5:调整颜色条的长宽比,这里设置为 5,使得颜色条在外观上更符合视觉需求,比如可以让颜色条看起来更细长或更矮胖一些,具体效果根据实际情况和个人喜好来定。label='电势':为颜色条添加一个标签,说明颜色条所对应的物理量是电势,进一步明确了颜色所代表的含义,方便读者理解图形中颜色与电势值之间的关系。
“””
# 2. 三维等势面图
ax2 = fig.add_subplot(222, projection='3d')
contour = ax2.contourf(X, Y, V, zdir='z', offset=-0.5, cmap=cm.viridis, alpha=0.8)
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('电势 V(r)')
ax2.set_title('三维等势面')
ax2.set_zlim(-0.5, 3.0)
fig.colorbar(contour, ax=ax2, shrink=0.5, aspect=5, label='电势')
# 3. 二维等高线投影
ax3 = fig.add_subplot(223)
contour2d = ax3.contourf(X, Y, V, 20, cmap=cm.viridis)
ax3.set_xlabel('X')
ax3.set_ylabel('Y')
ax3.set_title('电势等高线')
ax3.set_aspect('equal')
‘’’
设置坐标轴的纵横比(aspect ratio),使其保持相等。也就是让 x 轴和 y 轴上的单位长度在图形显示中代表的实际物理长度是一样的,这样绘制出来的图形在形状上不会出现拉伸或压缩变形的情况,能更真实地反映数据的几何特征。例如,绘制一个圆形时,如果不设置 equal 纵横比,在默认的坐标轴比例下可能会显示为椭圆。常用于绘制需要准确体现几何形状的图形,比如地图、几何图形等场景。
‘’’
circle = plt.Circle((0, 0), R, color='red', fill=False, linestyle='--', linewidth=2)
‘’’
创建一个圆形(Circle)对象,用于后续添加到指定的坐标轴(Axes)上进行可视化展示。
(0, 0):指定圆形的圆心坐标,这里表示圆心位于坐标原点 (0, 0) 的位置。R:代表圆的半径大小,通常 R 是之前已经定义好的变量,其值决定了所绘制圆形的大小。color='red':设置圆形的轮廓颜色为红色,通过指定颜色名称(Matplotlib 支持多种常见颜色名称)可以直观地控制图形元素的颜色外观,方便在图形中进行区分和突出显示。fill=False:表示不填充圆形内部,只绘制圆形的轮廓线,常用于绘制空心的图形元素,比如仅展示圆形边界的情况。
linestyle='--':设定圆形轮廓线的样式为虚线,Matplotlib 提供了多种线条样式选项,如实线('-')、虚线('--')、点划线('-.')等,不同的线条样式可以在视觉上进一步区分不同的图形元素或者用于表示不同的含义。linewidth=2:设置圆形轮廓线的宽度为 2 个单位(具体单位根据图形整体的设置和输出情况而定),可以调整线条的粗细程度,使其在图形中更清晰或更突出显示。
‘’’
ax3.add_artist(circle)
#将之前创建好的圆形(circle)对象添加到名为 ax3 的图(Axes)上进行显示。这样,在绘
#制好的图形中就能看到这个圆形了,通过前面设置的圆心坐标、半径、颜色、线条样式等
#参数,它会按照相应的要求呈现出对应的视觉效果。
ax3.text(0, R+0.1, f'球面 (R={R})', color='red', ha='center')
“””
在 ax3 这个坐标轴指定的位置添加文本注释内容,用于对图形中的元素进行说明或标注。
0 和 R + 0.1:分别表示文本在 x 轴和 y 轴方向上的坐标位置,这里将文本放置在 x = 0 以及 y 坐标为圆半径 R 的基础上再向上偏移 0.1 个单位的位置,使其显示在圆形上方合适的位置,便于观看和理解注释与图形元素的关联。f'球面 (R={R})':这是一个格式化字符串(f-string),用于生成要显示的文本内容,其中 {R} 会被替换为实际定义的半径 R 的值,这样文本就能动态显示当前圆形所对应的半径数值,清晰地告知读者图形中这个圆形代表的含义(比如模拟的是半径为 R 的球面)。color='red':设置文本的颜色为红色,与前面圆形的颜色保持一致,使其在视觉上更加协调统一,便于整体观察和识别。ha='center':ha 是 horizontal alignment(水平对齐方式)的缩写,设置为 'center' 表示文本在水平方向上居中对齐,确保文本在指定的 x 坐标位置能够以中心对称的方式显示,看起来更加美观、整齐。
“””
fig.colorbar(contour2d, ax=ax3, label='电势')
# 4. 沿X轴的电势分布
ax4 = fig.add_subplot(224)
r_x = np.linspace(0, 2.5*R, 100)
V_x = np.where(r_x <= R, k * q / R, k * q / r_x)
ax4.plot(r_x, V_x, 'b-', linewidth=2)
ax4.axvline(x=R, color='r', linestyle='--', alpha=0.7)
ax4.set_xlabel('距离 r')
ax4.set_ylabel('电势 V(r)')
ax4.set_title('沿X轴的电势分布')
ax4.grid(alpha=0.3)
ax4.text(R, 0.008+k*q/R, f'球面 (r=R)', color='red', ha='right')
ax4.annotate('球内电势恒定', xy=(0.5*R, k*q/R),
xytext=(0.5*R, 0.6*k*q/R),
arrowprops=dict(arrowstyle='->', color='black'))
ax4.annotate('球外电势按1/r衰减', xy=(1.5*R, k*q/(1.5*R)),
xytext=(1.5*R, 0.8*k*q/R),
arrowprops=dict(arrowstyle='->', color='black'))
“””
这行代码在子图ax4上添加了一个带箭头的文本注释,用于解释电势衰减特性。'球外电势按1/r衰减':注释的文本内容,用于解释图形中的物理规律。xy=(1.5*R, k*q/(1.5*R)):箭头的尖端指向的坐标点。这里选择的是距离球心1.5*R处的电势值(根据公式V = k*q/r计算),正好位于球外的电势曲线上。xytext=(1.5*R, 0.8*k*q/R):注释文本的起始位置。y坐标设为0.8*k*q/R,使文本位于箭头下方,避免与曲线重叠。arrowprops=...:定义箭头的样式。arrowstyle='->':使用简单的箭头样式。color='black':箭头颜色为黑色,确保清晰可见。
“””
plt.tight_layout(rect=[0, 0, 1, 0.95])
“””
这行代码自动调整子图之间的间距,避免元素重叠,并为顶部留出空间。plt.tight_layout():自动计算并调整子图的位置和大小,确保标题、坐标轴标签等元素不会相互重叠。rect=[0, 0, 1, 0.95]:设置布局的边界区域。[0, 0, 1, 0.95]表示整个图形的左下角为原点(0, 0),右上角为(1, 0.95)。这样顶部会留出 5% 的空间,避免标题被遮挡(例如当有全局标题时)。
“””
plt.show() # 将所有已创建的图形窗口显示出来