Matplotlib 实用指南(二)
五、样式和布局
在前一章中,您学习了许多与使用 Matplotlib 创建可视化相关的高级概念。
在这一章中,我们将继续探索更多与可视化相关的概念。具体来说,我们将详细探讨以下主题:
-
风格
-
布局
阅读完本章后,你将能够使用颜色、样式表和自定义布局。
风格
在本节中,您将探索 Matplotlib 中可用的各种样式。到目前为止,我们一直使用默认样式。样式规定了标记大小、颜色和字体等内容。Matplotlib 内置了很多样式。下面是一个应用内置样式的简短示例:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('ggplot')
data = np.random.randn(10)
现在让我们想象一下:
plt.plot(data)
plt.show()
这里我们使用 ggplot2 的风格,它是 R 编程语言的可视化包。图 5-1 显示了输出。
图 5-1
ggplot style(打印样式)
你一定很想知道所有可用款式的名称。您可以使用以下命令打印姓名:
print(plt.style.available)
以下是显示所有可用样式名称的输出:
['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
让我们应用经典的matplotlib风格如下:
plt.style.use('classic')
plt.plot(data)
plt.show()
图 5-2 显示了输出。
图 5-2
古典派风格
请注意,一旦应用了样式,该样式将应用于整个笔记本。因此,如果您想切换回默认样式,可以使用下面的代码:
plt.style.use('default')
让我们用下面的数据来展示一下:
plt.plot(data)
plt.show()
图 5-3 显示了输出。
图 5-3
默认样式
现在让我们演示一下当我们改变样式时颜色是如何受到影响的。让我们定义如下所示的数据:
n = 3
data = np.linspace(0, 2*n*np.pi, 300)
此外,让我们定义一个自定义函数,如下所示:
def sinusoidal(sty):
plt.style.use(sty)
fig, ax = plt.subplots()
ax.plot(data, np.sin(data), label='Sine')
ax.plot(data, np.cos(data), label='Cosine')
ax.legend()
函数是可以被调用来执行某种操作的例程。到目前为止,我们一直在使用 Python 本身自带的库函数以及像 NumPy 和 Matplotlib 这样的库。这里,在代码片段中,我们定义了自己的自定义函数。这个自定义函数接受一个参数。我们使用传递的参数作为可视化的样式。让我们用默认样式调用这个函数,如下所示:
sinusoidal('default')
plt.show()
图 5-4 显示了输出。
图 5-4
默认样式正弦图
让我们如下使用ggplot样式:
sinusoidal('ggplot')
plt.show()
图 5-5 显示了输出。
图 5-5
ggplot 式正弦图
让我们来看看 Seaborn 风格,如下图所示:
sinusoidal('seaborn')
plt.show()
图 5-6 显示了输出。
图 5-6
Seaborn 式正弦图
您已经看到样式应用于整个笔记本,并且您已经学会切换到默认样式。您可以局部更改代码块的样式,如下所示:
with plt.style.context('Solarize_Light2'):
data = np.linspace(0, 6 * np.pi)
plt.plot(np.sin(data), 'g.--')
plt.show()
图 5-7 显示了输出。
图 5-7
临时造型
布局
在本节中,您将学习布局。你已经学习了第四章中的支线剧情,如果你想再次使用默认样式,你可以运行下面一行代码将样式重置为默认样式:
plt.style.use('default')
让我们修改一下,创建一个 2×2 的可视化效果,如下所示:
fig, axs = plt.subplots(ncols=2, nrows=2,
constrained_layout=True)
plt.show()
图 5-8 显示了输出。
图 5-8
支线剧情
你也可以使用gridspec创建支线剧情,如下所示:
import matplotlib.gridspec as gridspec
fig = plt.figure(constrained_layout=True)
specs = gridspec.GridSpec(ncols=2, nrows=2, figure=fig)
ax1 = fig.add_subplot(specs[0, 0])
ax2 = fig.add_subplot(specs[0, 1])
ax3 = fig.add_subplot(specs[1, 0])
ax4 = fig.add_subplot(specs[1, 1])
plt.show()
前面的代码将创建一个类似图 5-8 的子绘图。您必须为输出编写大量代码,而这些代码只需几行代码就可以获得。但是,您可以使用此方法创建更复杂的可视化效果。让我们创建一个 3×3 的可视化,这样一个图就占据了一整行。
fig = plt.figure(constrained_layout=True)
gs = fig.add_gridspec(3, 3)
ax1 = fig.add_subplot(gs[0, :])
ax1.set_title('gs[0, :]')
ax2 = fig.add_subplot(gs[1, :])
ax2.set_title('gs[1, :]')
ax3 = fig.add_subplot(gs[2, :])
ax3.set_title('gs[2, :]')
plt.show()
该代码将产生如图 5-9 所示的输出。
图 5-9
定制支线剧情
您也可以有如下垂直图:
fig = plt.figure(constrained_layout=True)
gs = fig.add_gridspec(3, 3)
ax1 = fig.add_subplot(gs[:, 0])
ax1.set_title('gs[:, 0]')
ax2 = fig.add_subplot(gs[:, 1])
ax2.set_title('gs[:, 1]')
ax3 = fig.add_subplot(gs[:, 2])
ax3.set_title('gs[:, 2]')
plt.show()
图 5-10 显示了输出。
图 5-10
定制支线剧情
让我们看一个更复杂的例子。
fig = plt.figure(constrained_layout=True)
gs = fig.add_gridspec(3, 3)
ax1 = fig.add_subplot(gs[0, :])
ax1.set_title('gs[0, :]')
ax2 = fig.add_subplot(gs[1, :-1])
ax2.set_title('gs[1, :-1]')
ax3 = fig.add_subplot(gs[1:, -1])
ax3.set_title('gs[1:, -1]')
ax4 = fig.add_subplot(gs[-1, 0])
ax4.set_title('gs[-1, 0]')
ax5 = fig.add_subplot(gs[-1, -2])
ax5.set_title('gs[-1, -2]')
plt.show()
图 5-11 显示了输出。
图 5-11
定制支线剧情
这就是你定制支线剧情的方法。
摘要
这一章关注的是风格和支线剧情。在整本书中,你会有节制地使用这些概念。
在下一章,我们将探索一些 Matplotlib 的方法来创建可视化。
六、折线图、条形图和散点图
在前一章中,您学习了许多与 Matplotlib 可视化相关的高级概念。
在本章和接下来的几章中,你将学习一些创建数据可视化的技术。具体来说,在本章中,您将学习如何创建以下数据可视化:
-
线条和日志
-
误差线
-
条形图
-
散点图
阅读本章后,你将能够使用线条、对数、条形图和散点图。
线条和日志
在前面的章节中,你已经看到了如何绘制线条。为了热身,我们再来看一个线条示例,如下所示:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
data = np.linspace(0, 9, 10)
现在让我们想象一下。
plt.plot(data)
plt.show()
图 6-1 显示了输出。
图 6-1
线形图示例
让我们创建一个图表,使 x 轴为对数轴,y 轴为法线轴,如下所示:
t = np.arange(0.01, 10, 0.01)
plt.semilogx(t, np.cos(2 * np.pi * t))
plt.show()
图 6-2 显示了输出。
图 6-2
正常 y 轴和对数 x 轴
同样,you可以create a对数y-轴和a法线x-轴as follows:
plt.semilogy(t, np.cos(2 * np.pi * t))
plt.show()
图 6-3 显示了输出。
图 6-3
正常 x 轴和对数 y 轴
You可以有两个轴be l对数,as shown here:
plt.loglog(t, np.cos(2 * np.pi * t))
plt.show()
图 6-4 显示了输出。
图 6-4
两个对数轴
误差线
您还可以使用可视化来显示数据中的错误。当观测数据存在误差的可能性时,通常要在观测中提及。你会说“有 96%的置信区间。”这意味着给定的数据可能有 4%的误差。这给了人们一个关于量的精度的一般概念。当你想表现这种自信(或缺乏自信)时,你可以使用误差线。
为此,您必须使用函数errorbar()。您可以创建一个数组或列表来存储错误数据。我们可以有真实的数据,也可以模拟如下:
x = np.linspace (0, 2 * np.pi, 100)
y = np.sin(x)
ye = np.random.rand(len(x))/10
plt.errorbar(x, y, yerr = ye)
plt.show()
在本例中,我们在 y 轴上显示误差。图 6-5 显示了输出。
图 6-5
y 轴上的误差
同样,您可以在 x 轴上显示误差数据。
xe = np.random.rand(len(x))/10
plt.errorbar(x, y, xerr = xe)
plt.show()
图 6-6 显示了输出。
图 6-6
x 轴上的误差
You可以显示两个轴上的误差,如下所示:
plt.errorbar(x, y, xerr = xe, yerr = ye)
plt.show()
图 6-7 显示了输出。
图 6-7
两个轴上都有误差
条形图
条形图用条形表示离散和分类数据项。您可以用竖条或横条来表示数据。条形的高度或长度总是与数据量成比例。当您有离散的分类数据时,可以使用条形图或条形图。下面是一个简单的条形图示例:
x = np.arange(4)
y = np.random.rand(4)
plt.bar(x, y)
plt.show()
图 6-8 显示了输出。
图 6-8
条形图
您可以有如下组合条形图:
y = np.random.rand(3, 4)
plt.bar(x + 0.00, y[0], color = 'b', width = 0.25)
plt.bar(x + 0.25, y[1], color = 'g', width = 0.25)
plt.bar(x + 0.50, y[2], color = 'r', width = 0.25)
plt.show()
图 6-9 显示了输出。
图 6-9
组合条形图
前面的图是垂直条形图的例子。类似地,您可以有如下所示的水平条形图:
x = np.arange(4)
y = np.random.rand(4)
plt.barh(x, y)
plt.show()
图 6-10 显示了输出。
图 6-10
水平条形图
您也可以组合水平条形图,如下所示:
y = np.random.rand(3, 4)
plt.barh(x + 0.00, y[0], color = 'b', height=0.25)
plt.barh(x + 0.25, y[1], color = 'g', height=0.25)
plt.barh(x + 0.50, y[2], color = 'r', height=0.25)
plt.show()
图 6-11 显示了输出。
图 6-11
组合水平条形图
散点图
您还可以使用散点图来可视化您的数据。您通常会看到一组带有散点图的两个变量。一个变量分配给 x 轴,另一个分配给 y 轴。然后你为 x-y 对的值画一个点。x 和 y 的大小必须相同(它们总是一维数组)。您可以通过控制点的颜色和大小来显示其他变量。在这种情况下,表示 x、y、颜色和大小的一维数组的大小必须相同。
在下面的示例中,我们将随机的 x 轴和 y 轴值和颜色分配给 1,000 个点。所有点的大小都是 20。
N = 1000
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
size = (20)
plt.scatter(x, y, s=size, c=colors, alpha=1)
plt.show()
图 6-12 显示了输出。
图 6-12
散点图
在这个例子中,点的大小是固定的。您还可以设置图形上每个位置的大小(这取决于 x 和 y 坐标的值)。这里有一个例子:
N = 1000
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
size = (50 * x * y)
plt.scatter(x, y, s=size, c=colors, alpha=1)
plt.show()
图 6-13 显示了输出。
图 6-13
散点图
您刚刚学习了如何创建散点图。
摘要
在这一章中,我们以一个线条图开始了一点预热。然后,您学习了如何创建各种日志图。您还学习了如何显示误差幅度以及如何创建条形图。最后,您学习了如何创建散点图。
在下一章中,您将学习更多创建数据可视化的技术。您将学习如何创建直方图、等值线、流图和热图。
七、直方图、等高线和流图
在前一章中,您学习了许多用线条、条形图和散点图创建可视化效果的方法。
在本章中,我们将继续探索 Matplotlib 的各种可视化。您将学习如何创建直方图和等高线。您还将学习如何用流图绘制矢量。
直方图
在学习如何创建各种类型的直方图之前,您需要了解它们是什么。首先,你需要知道什么是频率表。假设您有一组具有不同值的成员。您可以创建一个表,该表在一列中包含不同的值范围。每个存储桶必须至少有一个值。然后,您可以计算落入该存储桶的成员数量,并根据存储桶记录这些数量。让我们看一个简单的例子。请为此创建一个新笔记本,如下所示:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
现在,让我们手动创建一个数据集,并将存储桶的数量定义为该集的基数(不同元素的数量)。
x = [1, 3, 5, 1, 2, 4, 4, 2, 5, 4, 3, 1, 2]
n_bins = 5
您可以使用以下代码显示输出:
plt.hist(x, bins=n_bins)
plt.show()
图 7-1 显示了输出。
图 7-1
简单直方图
正态(或高斯)分布是一种连续概率分布。通常是钟形曲线。让我们用正态分布曲线创建一个直方图。为了创建数据,我们将使用一个 NumPy 例程。让我们画一个正态分布的随机数据直方图如下:
np.random.seed(31415)
n_points = 10000
n_bins = 15
x = np.random.randn(n_points)
plt.hist(x, bins=n_bins)
plt.show()
图 7-2 显示了输出。
图 7-2
随机数据的简单直方图
一维数据的直方图是一个 2D 图(如图 7-2 )。当您想要创建 2D 数据的直方图时,您必须创建一个 3D 图形,其中数据变量位于 x 轴和 y 轴上,直方图位于 z 轴上。换句话说,您可以使用 2D 坐标来显示这个 3D 可视化,并从顶部(俯视图)查看直方图。这些条可以用颜色编码来表示它们的大小。
y = np.random.randn(n_points)
plt.hist2d(x, y, bins=50)
plt.show()
图 7-3 显示了输出。
图 7-3
2D 数据的简单直方图
您可以通过设置透明度和颜色来自定义直方图,如下所示:
plt.hist(x, 20, density=True,
histtype='stepfilled',
facecolor='g', alpha=0.5)
plt.show()
图 7-4 显示了输出。
图 7-4
定制直方图
您也可以只显示直方图的轮廓,如下所示:
plt.hist(x, 20, density=True,
histtype='step')
plt.show()
图 7-5 显示了输出。
图 7-5
仅带有轮廓的自定义直方图
轮廓
轮廓代表物体的轮廓。轮廓是突出物体形状的连续(在许多情况下是闭合的)线条。等高线在制图学领域很有用,制图学就是制作地图。在地图上,等高线连接等高的点。因此,等高线上的所有点都在相同的高度(从海平面开始)。在我们使用等高线的其他应用中,同一等高线上的所有点具有相同的值(或量值)。
让我们画一个简单的轮廓。我们将通过创建如下圆形轮廓来创建和可视化我们自己的数据:
x = np.arange(-3, 3, 0.005)
y = np.arange(-3, 3, 0.005)
X, Y = np.meshgrid(x, y)
Z = (X**2 + Y**2)
out = plt.contour(X, Y, Z)
plt.clabel(out, inline=True,
fontsize=10)
plt.show()
图 7-6 显示了输出。
图 7-6
简单标记轮廓
您还可以向输出中添加一个颜色条,如下所示:
out = plt.contour(X, Y, Z)
plt.clabel(out, inline=True,
fontsize=10)
plt.colorbar(out)
plt.show()
图 7-7 显示了输出。
图 7-7
带有颜色条的简单标注轮廓
您也可以按如下方式设置轮廓的颜色:
out = plt.contour(X, Y, Z,
colors='g')
plt.clabel(out, inline=True,
fontsize=10)
plt.show()
图 7-8 显示了输出。
图 7-8
带有自定义颜色的简单标注轮廓
您也可以有一个填充的轮廓。这些样式用于高亮显示等高线可视化中的各个区域。让我们如下可视化填充轮廓:
plt.contourf(X, Y, Z,
hatches=['-', '/', '\\', '//'],
cmap='cool',
alpha=0.75)
plt.show()
图 7-9 显示了输出。
图 7-9
填充轮廓
用流图可视化矢量
到目前为止,我们已经可视化了标量实体,它们具有量值。到目前为止,您所学的所有可视化对于标量来说都是非常好的。相反,向量是有大小和方向的实体。例如,力有大小和方向。一个具体的例子是磁力场。您可以用流图可视化矢量。让我们创建自己的数据集来对此进行可视化。我们将用X和Y创建一个网格。然后我们将创建U和V来显示数量级。
Y, X = np.mgrid[-5:5:200j, -5:5:300j]
U = X**2 + Y**2
V = X + Y
您可以创建一个简单的流图,如下所示:
plt.streamplot(X, Y, U, V)
plt.show()
图 7-10 显示了输出。
图 7-10
简单流图
您也可以拥有如下可变密度的流图:
plt.streamplot(X, Y, U, V,
density=[0.5, 0.75])
plt.show()
图 7-11 显示了输出。
图 7-11
可变密度的流图
您也可以按如下方式将颜色分配给流图:
plt.streamplot(X, Y, U, V, color=V,
linewidth=1, cmap='cool')
plt.show()
图 7-12 显示了输出。
图 7-12
可变颜色的流图
您也可以创建具有可变线宽的流图,如下所示:
plt.streamplot(X, Y, U, V,
density=0.6,
color='k',
linewidth=X)
plt.show()
图 7-13 显示了输出。
图 7-13
可变线宽的流图
您也可以使用箭图进行向量可视化,如下所示:
X = np.arange(-5, 5, 0.5)
Y = np.arange(-10, 10, 1)
U, V = np.meshgrid(X, Y)
plt.quiver(X, Y, U, V)
plt.show()
图 7-14 显示了输出。
图 7-14
用颤动图可视化矢量场
摘要
在本章中,您学习了直方图、等值线和流图。
在下一章,你将学习如何可视化图像和音频。您还将学习图像的插值方法。
八、图像和音频可视化
在前一章中,您学习了如何用直方图、等值线和流图创建可视化效果。
在本章中,您将学习如何使用 Matplotlib 处理和可视化图像和音频。具体来说,您将了解本章中的以下主题:
-
可视化图像
-
插值方法
-
音频可视化
-
音频处理
读完这一章,我们将能够用 Matplotlib 可视化图像和音频。
可视化图像
你可以用 Matplotlib 读取数字图像,它支持许多图像格式,尽管你必须安装一个名为 pillow 的库。如下图所示安装枕头:
!pip3 install pillow
我建议您为本章创建一个新的笔记本。使用以下语句导入库:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
您可以使用 Windows 上的功能imread()读取数字图像,如下所示:
img1 = plt.imread("D:/Dataset/4.2.03.tiff")
Linux 和 Mac 的代码类似,如下所示:
img1 = plt.imread("~/Dataset/4.2.03.tiff")
现在让我们看看变量的内容,如下所示:
print(img1)
输出如下所示:
array([[[164, 150, 71],
[ 63, 57, 31],
[ 75, 43, 10],
...,
[ 5, 8, 5],
[ 2, 5, 0],
[ 4, 5, 2]]], dtype=uint8)
为了节省空间,我删除了输出的中间部分,但这毕竟是一个数组。我们可以用下面的代码来确认这一点:
type(img1)
输出如下所示:
numpy.ndarray
要了解有关图像的更多信息,可以检查存储图像数据的 Ndarray 的属性。彩色图像存储为 3D 矩阵,该矩阵的每个维度都用于可视化颜色通道的强度。彩色图像以红、绿、蓝(RGB)格式读取和存储。因为灰度图像中没有颜色,所以只有一个平面(2D 矩阵)存储灰度值的强度。
您可以使用例程imshow()将任何 n 数组显示为图像,如下所示:
plt.imshow(img1)
plt.show()
图 8-1 显示了输出。
图 8-1
可视化图像
这是一幅彩色图像。Matplotlib 库自动检测图像是否有多个通道,并将其显示为彩色图像。然而,当我们显示灰度图像时,它会出错一点。
img2 = plt.imread("D:/Dataset/5.1.11.tiff")
plt.imshow(img2)
plt.show()
图 8-2 显示了输出。
图 8-2
可视化灰度图像
图像数据解释正确,但颜色似乎有些问题。对于灰度图像,Matplotlib 使用默认颜色映射,因此您必须按如下方式手动指定颜色映射:
plt.imshow(img2, cmap = 'gray')
plt.show()
图 8-3 显示了输出。
图 8-3
用正确的颜色映射可视化灰度图像
颜色映射是定义可视化颜色的值矩阵。让我们为图像尝试另一种颜色映射,如下所示:
plt.imshow(img2, cmap = 'cool')
plt.show()
图 8-4 显示了输出。
图 8-4
可视化一张 灰度图像 与一张 冷色图
您可以使用以下语句在当前版本的 Matplotlib 中显示颜色映射列表:
plt.colormaps()
输出如下所示:
['Accent',
'Accent_r',
.........
'twilight_r',
'twilight_shifted',
'twilight_shifted_r',
'viridis',
'viridis_r',
'winter',
'winter_r']
我已经删除了输出的一大部分,以便适合这本书。您可以使用这些彩色地图中的任何一种来满足您的可视化需求。作为练习,尝试一些带有灰度图像的彩色地图。
图像掩蔽
您可以使用圆形遮罩图像区域,如下所示:
import matplotlib.patches as patches
fig, ax = plt.subplots()
im = ax.imshow(img1)
patch = patches.Circle((245, 200),
radius=200,
transform=ax.transData)
im.set_clip_path(patch)
ax.axis('off')
plt.show()
在这个代码示例中,我们用例程Circle()在 XY 坐标 245,200 处创建一个圆。半径为 200 像素。此外,我们正在使用例程set_clip_path()裁剪带有圆圈的图像,并显示它。图 8-5 显示了输出。
图 8-5
用圆形剪裁图像
插值方法
您可以将简单的 NumPy Ndarray 显示为图像,如下所示:
img3 = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]]
plt.imshow(img3)
plt.show()
图 8-6 显示了输出。
图 8-6
numpy ndarray 作为映像
该图像没有使用可视化的插值方法。我们可以演示如下插值方法:
methods = ['none', 'antialiased', 'nearest', 'bilinear',
'bicubic', 'spline16', 'spline36', 'hanning',
'hamming', 'hermite', 'kaiser', 'quadric',
'catrom', 'gaussian', 'bessel', 'mitchell',
'sinc', 'lanczos', 'blackman']
fig, axs = plt.subplots(nrows=4, ncols=6, figsize=(9, 6),
subplot_kw={'xticks': [], 'yticks': []})
for ax, interp_method in zip(axs.flat, methods):
ax.imshow(img3, interpolation=interp_method, cmap='hot')
ax.set_title(str(interp_method))
plt.tight_layout()
plt.show()
在这个代码示例中,我们只是用 Matplotlib 中所有可用的插值方法显示了相同的 Ndarray。图 8-7 显示了输出。
图 8-7
插值方法演示
音频可视化
可以使用 Matplotlib 来可视化音频。您只需要 SciPy 库来读取音频文件并将数据存储到 Ndarray 中。让我们安装它,如下所示:
!pip3 install scipy
让我们导入所有需要的库,如下所示:
%matplotlib inline
import matplotlib.pyplot as plt
from scipy.io import wavfile
现在让我们来读一个音频文件。我正在读取一个 WAV 文件,如下所示:
samplerate, data = wavfile.read('sample.wav')
让我们看看音乐的采样率,如下所示:
print(samplerate)
输出如下所示:
44100
这是一个常见的采样速率(44.1 kHz)。你可以在 https://www.izotope.com/en/learn/digital-audio-basics-sample-rate-and-bit-depth.html 阅读一篇关于音频采样率的资料性文章。
您还可以按如下方式显示数据:
print(data)
数据如下:
[[-204 23]
[-233 32]
[-191 34]
...
[ 646 676]
[ 679 707]
[ 623 650]]
您可以按如下方式检查音频的属性:
print(type(data))
print(data.shape)
print(data.ndim)
print(data.dtype)
print(data.size)
print(data.nbytes)
输出如下所示:
<class 'numpy.ndarray'>
(2601617, 2)
2
int16
5203234
10406468
如您所见,音频数据被检索并存储在 NumPy 中。它存储在 2D 矩阵中。假设音频数据有 N 个数据点(也称为采样点);那么 NumPy 数组的大小就是 N×2。如你所见,音频有两个声道,左声道和右声道。因此,每个通道存储在一个单独的大小为 N 的数组中,因此我们有 N×2。这就是所谓的立体声音频。在本例中,我们有 2,601,617 个点(样本)。每个点或样本用一对 16 位(2 字节)的整数表示。因此,每个样本需要四个字节。因此,我们可以通过将样本大小乘以 4 来计算存储音频数据所需的总原始内存。当我们可视化音频时,我们显示样本的两个声道的值。让我们将前 2000 个数据点形象化如下:
plt.plot(data[:2000])
plt.show()
图 8-8 显示了输出。
图 8-8
音频文件的可视化
您可以按如下方式检查音频样本的数量:
samples = data.shape[0]
print(samples)
输出如下所示:
2601617
您可以创建不同的数据可视化,如下所示:
plt.plot(data[:10*samplerate])
plt.show()
图 8-9 显示了输出。
图 8-9
音频文件的可视化
让我们将两个通道的数据分开,如下所示:
channel1 = data[:, 0]
channel2 = data[:, 1]
print(channel1, channel2)
输出如下所示:
[-204 -233 -191 ... 646 679 623] [ 23 32 34 ... 676 707 650]
让我们将数据可视化如下:
plt.subplot(2, 1, 1)
plt.plot(channel1[:10*samplerate])
plt.subplot(2, 1, 2)
plt.plot(channel2[:10*samplerate], c='g')
plt.show()
图 8-10 显示了输出。
图 8-10
两个音频通道的可视化
音频处理
傅立叶变换将时域中表示为波的数据转换到频域中。因此,当您计算傅里叶变换并将其可视化时,您看到的是频域中的表示。
快速傅立叶变换(FFT)是计算波形数据的傅立叶变换的有效方法。FFT 减少了计算量,这就是它速度快的原因;这就是为什么它被称为快速傅立叶变换。让我们计算音频信号的快速傅立叶变换,如下所示:
import scipy.fftpack
datafft = scipy.fftpack.fft(data)
fftabs = abs(datafft)
print(fftabs)
输出如下所示:
[[ 181\. 227.]
[ 201\. 265.]
[ 157\. 225.]
...
[1322\. 30.]
[1386\. 28.]
[1273\. 27.]]
让我们计算频率并绘制图表如下:
freqs = scipy.fftpack.fftfreq( samples, 1/samplerate )
plt.plot(freqs, fftabs)
plt.show()
图 8-11 显示了输出。
图 8-11
FFT 可视化
摘要
在本章中,您学习了如何为图像和音频创建可视化效果。
在下一章,你将学习如何可视化饼图和极坐标图。
九、饼图和极坐标图
在前一章中,您学习了如何使用 Matplotlib 和 SciPy 可视化和处理图像和音频。
在本章中,你将学习如何用 Matplotlib 创建饼图和极坐标图。
饼图
让我们先学习饼图的基础知识。顾名思义,饼图是一个根据数据放射状划分的圆。想象一个苹果派或者一个切成片的比萨饼。饼状图很符合这种描述;然而,与通常对称划分的比萨饼或馅饼不同,饼图不一定是径向对称的。这完全取决于要可视化的数据。
让我们开始吧。我建议为这个练习创建一个新的笔记本。
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
让我们创建要可视化的数据,如下所示:
data = np.array([35, 25, 25, 15])
让我们用一个简单的饼图来直观显示数据,如下所示:
plt.pie(data)
plt.show()
图 9-1 显示了输出。
图 9-1
简单的饼图
让我们添加如下标签:
mylabels = ['A', 'B', 'C', 'D']
plt.pie(data,
labels = mylabels)
plt.show()
图 9-2 显示了输出。
图 9-2
带标签的简单饼图
您甚至可以将饼图的各个部分分开一点,如下所示:
explode = [0.0, 0.05, 0.1, 0.15]
plt.pie(data,
labels = mylabels,
explode = explode)
plt.show()
输出将按照explode参数中的值将饼图的各个部分分开。图 9-3 显示输出。
图 9-3
带有标签和展开图的简单饼图
您也可以启用阴影,如下所示:
plt.pie(data,
labels = mylabels,
explode = explode,
shadow = True)
plt.show()
图 9-4 显示了输出。
图 9-4
带阴影的简单饼图
您还可以向输出中添加图例,如下所示:
plt.pie(data,
labels = mylabels,
explode = explode,
shadow = True)
plt.legend()
plt.show()
图 9-5 显示了输出。
图 9-5
带有图例的简单饼图
您可以为图例添加标题,如下所示:
plt.pie(data,
labels = mylabels,
explode = explode,
shadow = True)
plt.legend(title='Data :')
plt.show()
图 9-6 显示了输出。
图 9-6
带有图例和图例标题的简单饼图
您刚刚学习了如何创建极坐标图。
极坐标图
您还可以创建饼图形状的极坐标图。然而,与笛卡尔(X-Y)坐标系的一个根本区别是,在极坐标图中,坐标系是径向排列的,因此您需要从原点的角度(θ)和距离( r 是半径)来可视化一个点或一组点。让我们创建一个数据集,如下所示:
N = 20
theta = np.linspace(0.0, 2 * np.pi, N)
r = 10 * np.random.rand(N)
这组点可以被可视化如下:
plt.subplot(projection='polar')
plt.bar(theta, r, bottom=0.0,
color=['r', 'g', 'b'], alpha=0.2)
plt.show()
图 9-7 显示了输出。
图 9-7
简单的极坐标图
你可以看到这创建了一个可视化的条形图,如图 9-7 所示。YouTube 上有一些有用的视频教程,您可以从中了解更多关于在极坐标系统中创建可视化效果的信息。
https://www.youtube.com/watch?v=mDT_DG_A0JA
https://www.youtube.com/watch?v=GMcRqtm4mNo
https://www.youtube.com/watch?v=VmQ1isayjJI
让我们创建一个简单的图表。让我们为它创建数据集,如下所示:
r = np.arange(0, 5, 0.2)
theta = 2 * np.pi * r
plt.subplot(projection='polar')
plt.plot(theta, r)
plt.show()
这在极坐标图上创建了简单的线性可视化。由于这是一个极坐标图,你会看到一个螺旋状的结构,如图 9-8 所示。
图 9-8
极图上的简单线性可视化
这不是一个完美的螺旋,因为连续点之间的距离是 0.2。如果你减少距离,那么你会得到一个完美的螺旋。让我们将数据调整如下:
r = np.arange(0, 5, 0.01)
theta = 2 * np.pi * r
plt.subplot(projection='polar')
plt.plot(theta, r)
plt.show()
这就形成了一个完美的螺旋,如图 9-9 所示。
图 9-9
螺旋形视觉效果
让我们来看几个极坐标图上的散点图示例。首先,准备如下所示的数据:
N = 150
r = np.random.rand(N)
theta = 2 * np.pi * np.random.rand(N)
size = r * 100
您可以这样想象:
plt.subplot(projection='polar')
plt.scatter(theta, r, c=theta,
s=size, cmap='hsv',
alpha=0.5)
plt.show()
图 9-10 显示了输出。
图 9-10
散点图
您也可以通过设置开始和结束角度来显示可视化的一部分,如下所示:
fig = plt.figure()
ax = fig.add_subplot(projection='polar')
c = ax.scatter(theta, r, c=theta,
s=size, cmap='hsv',
alpha=0.5)
ax.set_thetamin(0)
ax.set_thetamax(90)
plt.show()
输出仅显示整个极线图的一部分,如图 9-11 所示。
图 9-11
局部散点图
作为练习,您可能想要创建部分螺旋和条形图。
摘要
在这一章中,详细学习了如何创建饼图和极坐标图。
在下一章中,你将学习如何创建更多的可视化,即使用例程pColor()、pColormesh()和colorbar()。
十、使用颜色
在前一章中,你学习了如何用 Matplotlib 可视化饼图和极坐标图。
在这一章中,你将学习如何使用颜色。以下是您将在本章中学习使用的例程:
-
pcolor() -
pcolormesh() -
colorbar()
读完这一章,我们将能够在 Matplotlib 中使用颜色。
pcolor()
例程pcolor()创建一个带有矩形(非正方形)网格的伪彩色图。伪彩色是指物体或图像呈现的颜色不同于记录时的颜色。让我们为本章创建一个新笔记本,如下所示:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
让我们创建一个非正方形矩阵,并使用例程pcolor()将其可视化,如下所示:
data = np.random.rand(5, 6)
plt.pcolor(data)
plt.show()
图 10-1 显示了输出。
图 10-1
pcolor()的简单演示
您也可以使用自定义颜色映射,如下所示:
plt.pcolor(data, cmap='YlGnBu_r')
plt.show()
图 10-2 显示了输出。
图 10-2
一个简单的 pcolor()演示,带有彩色地图
让我们现在尝试添加阴影。让我们创建一个新的数据集,如下所示:
N = 100
X, Y = np.meshgrid(np.linspace(-5, 5, N),
np.linspace(-4, 4, N))
Z = (X**2 + Y**2)
您可以将其形象化如下:
plt.pcolor(X, Y, Z,
cmap='YlGnBu_r',
shading='auto')
plt.show()
图 10-3 显示了输出。
图 10-3
明暗法
您也可以使用nearest作为着色方法来创建可视化。在这种阴影技术中,每个网格点都有一种居中的颜色,它在相邻网格中心之间延伸。在这种阴影技术中,每个网格点都有一种居中的颜色,它在相邻网格中心之间延伸。示例如下:
plt.pcolor(X, Y, Z,
cmap='YlGnBu_r',
shading='nearest')
plt.show()
图 10-4 显示了输出。
图 10-4
最近阴影
pcolormesh()
例程polormesh()的行为方式与pcolor()相同;但是,它可以更快地渲染大型数据集。让我们创建一个用于图 10-4 的相同数据集的可视化,但是使用了polormesh()。代码如下:
plt.pcolormesh(X, Y, Z,
cmap='YlGnBu_r',
shading='auto')
plt.show()
让我们看一个带有阴影和颜色贴图的示例,如下所示:
nrows = ncols = 5
x = np.arange(ncols + 1)
y = np.arange(nrows + 1)
z = np.arange(nrows * ncols).reshape(nrows, ncols)
plt.pcolormesh(x, y, z,
shading='flat',
cmap='coolwarm')
plt.show()
图 10-5 显示了输出。
图 10-5
将 pcolormesh()与阴影和颜色贴图一起使用
使用不同的参数运行以下示例:
plt.pcolormesh(x, y, z,
shading='auto',
cmap='cool')
plt.show()
您还可以对数据集应用简单的几何变换,如下所示:
z = np.random.rand(6, 10)
x = np.arange(0, 10, 1)
y = np.arange(4, 10, 1)
T = 0.5
X, Y = np.meshgrid(x, y)
X = X + T * Y
Y = Y + T * X
plt.pcolormesh(X, Y, Z,
shading='auto')
plt.show()
图 10-6 显示了输出。
图 10-6
使用 polormesh()进行简单的转换
colorbar()
您还可以添加与可视化中数据点的数量相关的颜色条。例行程序colorbar()起了作用。以下是代码:
N = 100
X, Y = np.meshgrid(np.linspace(-5, 5, N),
np.linspace(-5, 5, N))
Z = (X**2 + Y**2)
img = plt.imshow(Z, cmap='YlGnBu_r')
plt.colorbar(img)
plt.show()
图 10-7 显示了输出。
图 10-7
简单颜色条
您可以缩小颜色栏并按如下方式更改其位置:
img = plt.imshow(Z, cmap='coolwarm')
plt.colorbar(img, location='left', shrink=0.6)
plt.show()
图 10-8 显示了输出。
图 10-8
收缩的颜色条
您也可以按如下方式扩展颜色栏:
img = plt.imshow(Z, cmap='coolwarm')
plt.colorbar(img, extend='both')
plt.show()
图 10-9 显示了输出。
图 10-9
扩展颜色条
摘要
在本章中,您学习了如何使用颜色。在下一章,你将学习如何创建三维可视化。
十一、Matplotlib 中的 3D 可视化
在前一章中,你学习了如何在 Matplotlib 中使用颜色。
在本章中,您将学习如何使用 3D 可视化效果。以下是您将在本章中了解的主题:
-
绘制 3D 线、散点图和等高线
-
使用线框、曲面和样本数据
-
绘制条形图
-
绘制颤图和茎图
-
使用 3D 体积
线框、表面和 3D 轮廓用于显示体积数据。条形图用于显示分类数据。颤动图用于可视化矢量。阅读完本章后,你将能够在 Matplotlib 中使用所有这些 3D 可视化。
做好准备
我建议您为本章中的所有示例创建一个新笔记本。要做好准备,您需要安装一个额外的库,如下所示:
!pip3 install PyQt5
Qt 是一个跨平台的 GUI 库。PyQt5 是 Qt 的 Python 绑定。一旦安装了库,您可以使用以下神奇的命令来强制 Jupyter Notebook 在单独的 QT 窗口中显示可视化效果:
%matplotlib qt
因此,当你创建可视化时,你也能够与它们互动。让我们学习基础知识。首先,我们导入所有需要的库,如下所示:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
然后我们创建一个图形对象,如下所示:
fig = plt.figure()
然后我们创建一个 3D 轴,如下所示:
ax = plt.axes(projection='3d')
在此之后,您必须添加可视化代码。但是,对于此示例,您将使用以下行为空图形和轴创建可视化:
plt.show()
图 11-1 显示了输出。
图 11-1
一个空的交互式三维可视化
您可以使用鼠标与该可视化交互并更改其方向。在继续之前,花时间探索所有的交互可能性。
绘制 3D 线
让我们画一条 3D 线。让我们创建一个图形和轴,如下所示:
fig = plt.figure()
ax = plt.axes(projection='3d')
让我们按如下方式创建 3D 数据:
z = np.linspace(0, 30, 1000)
x = np.sin(z)
y = np.cos(z)
您可以按如下方式创建 3D 图:
ax.plot3D(x, y, z, 'red')
plt.show()
图 11-2 显示了输出。
图 11-2
三维线性图
三维散点图
您可以创建随机点并用 3D 散点图显示它们,如下所示。让我们先创建一个图形和轴,如下所示:
fig = plt.figure()
ax = plt.axes(projection='3d')
您可以按如下方式创建随机数据点:
y = np.random.random(100)
x = np.random.random(100)
z = np.random.random(100)
这些点可以用散点图可视化,如下所示:
ax.scatter3D(x, y, z, cmap='cool');
plt.show()
图 11-3 显示了输出。
图 11-3
三维散点图
三维轮廓
您可以使用功能contour()和contour3D()创建 3D 轮廓。让我们创建一些可视化的数据。
x = np.linspace(-10, 10, 30)
y = np.linspace(-10, 10, 30)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X ** 2 + Y ** 2))
您可以按如下方式创建轮廓:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.contour(X, Y, Z, 50, cmap='coolwarm')
plt.show()
图 11-4 显示了输出。
图 11-4
3D 等高线图
您可以使用以下代码获得类似的输出,如图 11-4 所示:
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.contour3D(X, Y, Z, 40,
cmap='coolwarm')
plt.show()
您也可以使用功能contourf()创建填充轮廓,如下所示:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.contourf(X, Y, Z, 50, cmap='coolwarm')
plt.show()
线框、曲面和样本数据
您可以绘制同一数据集的线框,如下所示:
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_wireframe(X, Y, Z, color='Green')
ax.set_title('wireframe')
plt.show()
图 11-5 显示了输出。
图 11-5
3D 线框
相同的数据可以可视化为 3D 表面,如下所示:
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, color='Blue')
ax.set_title('Surface Plot')
plt.show()
图 11-6 显示了输出。
图 11-6
三维表面
您还可以使用 Matplotlib 库附带的示例数据来演示可视化效果。函数get_test_data()可以如下获取采样数据:
from mpl_toolkits.mplot3d import axes3d
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
X, Y, Z = axes3d.get_test_data(0.02)
ax.plot_wireframe(X, Y, Z,
rstride=10,
cstride=10)
plt.show()
图 11-7 显示了输出。
图 11-7
可视化测试数据
作为练习,尝试使用测试数据创建一个表面和轮廓。
条形图
您可以在三维轴中显示 2D 条形图。让我们创建一个图形和轴,如下所示:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
让我们定义条形的颜色。
colors = ['r', 'g', 'b', 'c', 'm', 'y','k']
yticks = [0, 1, 2, 3, 4, 5, 6]
现在,让我们通过以下循环使用定义的颜色创建条形图:
for c, k in zip(colors, yticks):
x = np.arange(25)
y = np.random.rand(25)
ax.bar(x, y, zs=k, zdir='y',
color=c, alpha=0.8)
plt.show()
图 11-8 显示了输出。
图 11-8
在 3D 坐标中可视化 2D 条形图
你也可以用 Matplotlib 创建一个 3D 条形图。让我们首先创建数据,如下所示:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
x = np.arange(10) * np.arange(10)
y = np.arange(10) * np.arange(10)
x, y = np.meshgrid(x, y)
x, y = x.ravel(), y.ravel()
top = x + y
bottom = np.zeros_like(top)
width = depth = 5
然后,您可以将它显示为三维条形图,如下所示:
ax.bar3d(x, y, bottom, width,
depth, top,
shade=True,
color='g')
plt.show()
图 11-9 显示了输出。
图 11-9
可视化三维条形图
颤图和茎图
颤动图用于表示方向实体(例如,向量)。让我们定义数据,如下所示:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
x = y = z = np.arange(-0.1, 1, 0.2)
X, Y, Z = np.meshgrid(x, y, z)
u = np.cos(np.pi * X) * np.sin(np.pi * Y) * np.sin(np.pi * Z)
v = -np.sin(np.pi * X) * np.cos(np.pi * Y) * np.sin(np.pi * Z)
w = np.sin(np.pi * X) * np.sin(np.pi * Y) * np.cos(np.pi * Z)
最后,您可以将数据可视化,如下所示:
ax.quiver(X, Y, Z, u, v, w,
length=0.1,
normalize=True)
plt.show()
图 11-10 显示了输出。
图 11-10
颤动图
您也可以在可视化中绘制垂直线的位置创建 stem 图。让我们使用三角函数来定义数据,如下所示:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
theta = np.linspace(0, 2 * np.pi)
x = np.sin(theta)
y = np.cos(theta)
z = np.cos(theta)
您可以将 stem 图可视化如下:
ax.stem(x, y, z)
plt.show()
图 11-11 显示了输出。
图 11-11
茎图
3D 体积
可以将 3D 体积数据显示为封闭的曲面。让我们创建如下数据:
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
您可以将此数据显示为球体,如下所示:
ax.plot_surface(x, y, z)
plt.show()
图 11-12 显示了输出。
图 11-12
作为体积的曲面图
您也可以使用功能voxels()来可视化体积,如下所示:
ma = np.random.randint(1, 3, size=(3, 3, 3))
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.voxels(ma, edgecolor='k')
plt.show()
图 11-13 显示了输出。
图 11-13
三维体积图
摘要
在本章中,您学习了如何使用 3D 可视化效果。线框、表面和 3D 轮廓用于显示体积数据。条形图用于显示分类数据。颤动图用于可视化矢量。
在下一章,你将学习如何创建动画。