%matplotlib inline
import numpy as np
from matplotlib_inline import backend_inline
from d2l import torch as d2l
def f(x):
return 3 * x ** 2 - 4 * x
-
%matplotlib inline
:这是一个Jupyter Notebook的魔法命令,它告诉Jupyter Notebook在输出结果中显示Matplotlib绘图的结果,并将这些图形嵌入到Notebook中。 -
import numpy as np
:这是导入NumPy库,并将其命名为np
,以便在代码中使用NumPy的函数和方法。 -
from matplotlib_inline import backend_inline
:这是从matplotlib_inline
库中导入backend_inline
模块。backend_inline
模块提供了在Jupyter Notebook中绘制Matplotlib图形的功能。 -
from d2l import torch as d2l
:这是从d2l
库中导入torch
模块,并将其命名为d2l
。d2l
库是《动手学深度学习》一书的配套代码库,提供了一些用于深度学习的实用函数和工具。 -
def f(x):
:这是一个函数定义,它定义了一个名为f
的函数,该函数接受一个参数x
。 -
return 3 * x ** 2 - 4 * x
:这是函数体,它使用输入的x
计算一个值,并将其作为函数的返回值。在这个例子中,函数计算了3 * x的平方减去4 * x的值,并将结果返回。
这段代码的作用是定义了一个简单的二次函数f(x)
,并导入了一些常用的库和模块,以便在后续的代码中使用它们。
def numerical_lim(f, x, h):
return (f(x + h) - f(x)) / h
h = 0.1
for i in range(5):
print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')
h *= 0.1
-
def numerical_lim(f, x, h):
:这是一个函数定义,它定义了一个名为numerical_lim
的函数,该函数接受三个参数f
、x
和h
。 -
return (f(x + h) - f(x)) / h
:这是函数体,它使用输入的f
、x
和h
计算一个值,并将其作为函数的返回值。在这个例子中,函数计算了f(x + h) - f(x)
除以h
的值,并将结果返回。 -
h = 0.1
:这是一个赋值语句,它将0.1
赋值给变量h
。 -
for i in range(5):
:这是一个循环语句,它会执行下面缩进的代码块5次。 -
print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')
:这是一个打印语句,它会将一些文本和变量的值打印到控制台。在这个例子中,它打印了h
的值和通过调用numerical_lim
函数计算得到的数值极限值。 -
h *= 0.1
:这是一个赋值语句,它将h
乘以0.1
的值再赋给h
。这个操作会使h
的值逐渐减小,用于计算不同步长下的数值极限值。
这段代码的作用是计算一个函数在不同步长下的数值极限值。它首先定义了一个函数numerical_lim
,然后使用一个循环来计算并打印不同步长下的数值极限值。
def use_svg_display(): #@save
"""使用svg格式在Jupyter中显示绘图"""
backend_inline.set_matplotlib_formats('svg')
-
backend_inline.set_matplotlib_formats('svg')
:这是一个函数调用语句,它调用了backend_inline
模块的set_matplotlib_formats
函数,并将字符串'svg'
作为参数传递给该函数。这个函数调用的作用是设置Matplotlib绘图库在Jupyter Notebook中使用SVG格式显示图形。 - 注意,注释
#@save
是一个特殊的标记,会将对应的函数、类或语句保存在d2l
包中。 因此,以后无须重新定义就可以直接调用它们(例如,d2l.use_svg_display()
)。def set_figsize(figsize=(3.5, 2.5)): #@save """设置matplotlib的图表大小""" use_svg_display() d2l.plt.rcParams['figure.figsize'] = figsize
我们定义
set_figsize
函数来设置图表大小。 注意,这里可以直接使用d2l.plt
,因为导入语句from matplotlib import pyplot as plt
已标记为保存到d2l
包中。
d2l.plt.rcParams
是 Matplotlib 的全局配置对象,用于设置各种默认参数。['figure.figsize']
是配置对象中的一个属性,用于设置图表的大小。=
是赋值操作符,将figsize
的值赋给d2l.plt.rcParams['figure.figsize']
。
这行代码将 figsize
的值设为了 d2l.plt.rcParams['figure.figsize']
,即将默认图表大小设置为 figsize
。这样,在后续的绘图操作中,如果没有显式指定图表大小,就会使用这个默认值。
#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
"""设置matplotlib的轴"""
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_xlim(xlim)
axes.set_ylim(ylim)
if legend:
axes.legend(legend)
axes.grid()
axes.set_xlabel(xlabel)
:设置X轴的标签。axes.set_ylabel(ylabel)
:设置Y轴的标签。axes.set_xscale(xscale)
:设置X轴的刻度。axes.set_yscale(yscale)
:设置Y轴的刻度。axes.set_xlim(xlim)
:设置X轴的范围。axes.set_ylim(ylim)
:设置Y轴的范围。if legend:
:检查legend
是否为真。axes.legend(legend)
:显示图例。axes.grid()
:显示网格线
#@save
def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
ylim=None, xscale='linear', yscale='linear',
fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):
"""绘制数据点"""
if legend is None:
legend = []
set_figsize(figsize)
axes = axes if axes else d2l.plt.gca()
# 如果X有一个轴,输出True
def has_one_axis(X):
return (hasattr(X, "ndim") and X.ndim == 1 or isinstance(X, list)
and not hasattr(X[0], "__len__"))
if has_one_axis(X):
X = [X]
if Y is None:
X, Y = [[]] * len(X), X
elif has_one_axis(Y):
Y = [Y]
if len(X) != len(Y):
X = X * len(Y)
axes.cla()
for x, y, fmt in zip(X, Y, fmts):
if len(x):
axes.plot(x, y, fmt)
else:
axes.plot(y, fmt)
set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
1.
- `X`:数据点的x坐标,可以是一个列表或者一个数组。
- `Y`:数据点的y坐标,可以是一个列表或者一个数组。如果`Y`为`None`,则默认使用`X`作为y坐标。
- `xlabel`:x轴的标签。
- `ylabel`:y轴的标签。
- `legend`:图例的标签,可以是一个列表。
- `xlim`:x轴的取值范围。
- `ylim`:y轴的取值范围。
- `xscale`:x轴的缩放类型,默认为线性缩放。
- `yscale`:y轴的缩放类型,默认为线性缩放。
- `fmts`:数据点的样式,可以是一个字符串或者一个字符串的列表。默认为`('-', 'm--', 'g-.', 'r:')`。
- `figsize`:图表的大小,用一个元组表示,默认为`(3.5, 2.5)`。
- `axes`:绘图的`Axes`对象。如果为`None`,则默认使用当前的`Axes`对象。
2.
如果legend
参数为None
,则将其设置为空列表。
3.
axes
参数表示绘图的Axes
对象,如果为None
,则默认使用当前的Axes
对象。
接下来,代码使用了一个三元表达式来判断axes
参数是否为None
。如果axes
不为None
,则将axes
赋值给axes
,即axes = axes
;如果axes
为None
,则调用d2l.plt.gca()
函数获取当前的Axes
对象,并将其赋值给axes
。
d2l.plt.gca()
函数是matplotlib.pyplot
模块中的一个函数,用于获取当前的Axes
对象。gca
是"get current axes"的缩写。当我们在绘图时没有指定Axes
对象时,matplotlib
会自动创建一个Axes
对象,并将其设置为当前的Axes
对象。因此,gca
函数可以获取到当前的Axes
对象。
最终,通过这行代码,我们可以获取到一个有效的Axes
对象,用于后续的绘图操作
4.
has_one_axis
函数用于判断一个对象X
是否只有一个轴。
首先,函数使用了一个条件表达式来判断X
是否具有属性ndim
,并且ndim
的值是否为1。ndim
是numpy
中的一个属性,用于表示数组的维度数。如果X
是一个numpy
数组,并且它的维度数为1,则条件表达式的值为True
;否则为False
。
接下来,函数使用了一个条件表达式来判断X
是否为一个列表,并且列表的第一个元素不具有属性__len__
。__len__
是一个特殊方法,用于返回对象的长度。如果X
是一个列表,并且列表的第一个元素不具有__len__
属性,则条件表达式的值为True
;否则为False
。
最终,函数的返回值为两个条件表达式的逻辑或运算结果。如果其中任意一个条件表达式的值为True
,则函数返回True
;否则返回False
。
通过这个函数,我们可以判断一个对象是否只有一个轴,即判断它是否为一维数组或列表中的一个元素
5.
if has_one_axis(X):
X = [X]
如果X
只有一个轴,将其转换为一个列表。
6.
if Y is None:
X, Y = [[]] * len(X), X
elif has_one_axis(Y):
Y = [Y]
如果Y
为None
,则将X
转换为一个空列表的列表,并将X
赋值给Y
;如果Y
只有一个轴,则将其转换为一个列表。
7.
if len(X) != len(Y):
X = X * len(Y)
如果X
和Y
的长度不相等,则将X
复制多次,使其长度与Y
相等
8.
axes.cla()
清除当前的Axes
对象。
9.
for x, y, fmt in zip(X, Y, fmts):
if len(x):
axes.plot(x, y, fmt)
else:
axes.plot(y, fmt)
代码使用zip()
函数将X
、Y
和fmts
三个列表的对应元素进行配对,得到一个迭代器。zip()
函数将每个列表的第i
个元素组合成一个元组(X[i], Y[i], fmts[i])
,并返回一个包含这些元组的迭代器。
接下来,代码使用for
循环遍历这个迭代器中的每个元组,依次赋值给变量x
、y
和fmt
。
在每次循环中,代码使用一个条件语句判断x
的长度是否大于0,即len(x)
是否为非零值。如果x
的长度大于0,则说明x
是一个非空列表,可以直接使用axes.plot(x, y, fmt)
来绘制线图。其中,x
和y
分别表示横坐标和纵坐标的数据,fmt
表示线图的格式。
如果x
的长度为0,则说明x
是一个空列表,无法用作横坐标数据。此时,代码使用axes.plot(y, fmt)
来绘制线图,将y
作为纵坐标数据,fmt
作为线图的格式。
通过这段代码,可以根据给定的数据和格式,在指定的Axes
对象上绘制线图。如果x
不为空,则绘制x
和y
的线图;如果x
为空,则只绘制y
的线图
10.
代码使用np.arange()
函数创建一个从0到3(不包括3),步长为0.1的一维数组,并将其赋值给变量x
。这个数组包含了从0到2.9的一系列数值。
接下来,代码调用plot()
函数,传入三个参数:x
、[f(x), 2 * x - 3]
和'x'
。其中,x
是横坐标数据,[f(x), 2 * x - 3]
是纵坐标数据,'x'
是线图的格式。这个函数调用的目的是绘制x
和f(x)
的线图,以及x
和2 * x - 3
的线图。
最后,代码使用legend
参数来添加图例。legend
参数是一个列表,包含了两个字符串:'f(x)'
和'Tangent line (x=1)'
。这个参数的作用是为绘制的线图添加图例,分别表示f(x)
和在点(1, f(1))
处的切线。
通过这段代码,我们可以在一个图中同时绘制函数f(x)
和它在点(1, f(1))
处的切线,并添加相应的图例。