Python-数据可视化指南-一-

75 阅读40分钟

Python 数据可视化指南(一)

原文:Data Visualization With Python

协议:CC BY-NC-SA 4.0

零、前言

关于

本节简要介绍作者、本书的内容、入门所需的技术技能,以及完成所有附带活动和练习所需的硬件和软件要求。

关于书

您将从 Python 开始数据可视化,首先介绍数据可视化及其重要性。然后,您将通过计算一些数字的平均值、中值和方差,并观察它们值的差异来学习统计学。您还将了解关键的 NumPy 和 Pandas 技术,例如索引、切片、迭代、过滤和分组。接下来,您将研究不同类型的可视化,比较它们,并找出如何使用这种比较来选择特定类型的可视化。你将探索不同的绘图,包括自定义创作。

掌握了各种可视化库之后,您将学会使用 Matplotlib 和 Seaborn 来简化创建可视化的过程。还将向您介绍先进的可视化技术,如地质图和交互式绘图。您将学习如何理解地理空间数据,创建可集成到任何网页中的交互式可视化,并利用任何数据集来构建美观且有洞察力的可视化。您将学习如何使用 Choropleth 绘图在地图上绘制地理空间数据,并学习 Bokeh 的基础知识,通过添加小部件和制作信息显示动画来扩展绘图。

这本书以一个有趣的活动结束,在这个活动中,你将获得一个新的数据集,你必须应用你所学的一切来创建一个有洞察力的顶点可视化。

关于作者

马里奥·德布勒是斯图加特大学专注于深度学习的博士生。他此前曾在硅谷博世人工智能中心实习,从事深度学习领域,使用最先进的算法开发尖端产品。在他的硕士论文中,他致力于将深度学习应用于医学数据,以推动医学应用。

Tim gromann是一名 CS 学生,对从 AI 到 IoT 的各种话题都很感兴趣。他之前在硅谷博世人工智能中心工作,从事大数据工程领域。他高度参与不同的开源项目,并在会议上积极谈论他的项目和经验。

目标

  • 获得各种图及其最佳用例的概述
  • 使用不同的绘图库,了解它们的优缺点
  • 了解如何创建有洞察力的可视化效果
  • 理解什么是好的可视化
  • 提高您的 Python 数据争论技巧
  • 使用真实世界的数据
  • 学习行业标准工具
  • 发展您对数据格式和表示的一般理解

观众

这本书是针对开发人员或科学家谁想进入数据科学或想使用数据可视化来丰富他们的个人和专业项目。不需要数据分析和可视化方面的经验;但是,推荐一些 Python 和高中水平数学的知识。尽管这是一本关于数据可视化的初级书籍,但更有经验的学生将受益于通过处理真实世界的数据来提高他们的 Python 技能。

进场

这本书用通俗易懂的语言彻底解释了这项技术,同时完美地平衡了理论和练习。每章都是在前一章的基础上设计的。这本书还包含多种活动,这些活动使用现实生活中的业务场景,让你在高度相关的环境中练习和应用你的新技能。

最低硬件要求

为了获得最佳的学生体验,我们推荐以下硬件配置:

  • 操作系统:Windows 7 SP1 32/64 位、Windows 8.1 32/64 位或 Windows 10 32/64 位、Ubuntu 14.04 或更高版本、或 macOS Sierra 或更高版本
  • 处理器:双核或更好
  • 内存:4GB 内存
  • 存储:10 GB 可用空间

软件需求

您还需要提前安装以下软件:

  • 浏览器:谷歌 Chrome 还是 Mozilla 火狐
  • 伯爵夫人
  • JupyterLab 和 Jupyter 笔记本
  • 升华文本(最新版本)、原子集成开发环境(最新版本)或其他类似的文本编辑器应用
  • 蟒蛇 3
  • 安装了以下 Python 库:NumPy、pandas、Matplotlib、seaborn、geoplotlib、Bokeh 和 squarify

惯例

文本中的码字、数据库表名、文件夹名、文件名、文件扩展名、路径名、伪 URL、用户输入和 Twitter 句柄如下所示:“axis=0 是水平的,axis=1是垂直的,所以如果我们想要每行都有结果,就需要选择axis=1

代码块设置如下:

# indexing the first value of the second row (1st row, 1st value)
first_val_first_row = dataset[0][0]
np.mean(first_val_first_row)

新术语和重要词汇以粗体显示:

“为了从可视化数据中得出结论,我们需要处理我们的数据,并将其转换为最佳的表示形式。这就是数据角力的用武之地。”

安装和设置

在您开始阅读本书之前,我们将安装 Python 3。 6、pip 以及本书通篇使用的其他库。您可以在这里找到安装它们的步骤。

安装 Python

按照此链接中的说明安装 Python 3.6:realpython.com/installing-…

安装管

  1. 要安装 pip,请转到以下链接并下载get-pip.py文件:pip.pypa.io/en/stable/i…

  2. Then, use the following command to install it:

    python get-pip.py
    

    您可能需要使用python3 get-pip.py命令,因为您的计算机上以前版本的 Python 已经使用了python命令。

安装库

使用 pip 命令,安装以下库:

python -m pip install --user numpy matplotlib jupyterlab pandas squarify bokeh geoplotlib seaborn

使用 JupyterLab 和 Jupyter 笔记本

你将在 JupyterLab 进行不同的练习和活动。这些练习和活动可以从相关的 GitHub 存储库中下载。

从这里下载资源库:https://github . com/trainingypbackt/Data-Visualization-with-Python

您可以使用 GitHub 下载,也可以通过点击右上角的绿色克隆或下载按钮作为压缩文件夹下载。

为了打开 Jupyter 笔记本,你必须用你的终端遍历目录。为此,请键入:

cd Data-Visualization-with-Python/<your current chapter>

例如:

cd Data-Visualization-with-Python/chapter01/

要完成该过程,请执行以下步骤:

  1. 要到达每个活动和练习,您必须再次使用cd进入每个文件夹,如:

    cd Activity01
    
  2. 进入自己选择的文件夹后,只需调用jupyter-lab即可启动 JupyterLab。同样,对于 Jupyter 笔记本,调用jupyter notebook

导入 Python 库

本书中的每一项练习和活动都将利用各种图书馆。将库导入 Python 非常简单,我们是这样做的:

  1. 要导入库,比如 NumPy 和 pandas,我们必须运行以下代码。这会将整个numpy库导入到我们当前的文件中:

    import numpy              # import numpy
    
  2. 在本书练习和活动的第一个单元中,您将看到以下代码。我们可以在代码中使用np代替numpynumpy :

    import numpy as np        # import numpy and assign alias np
    

    调用方法

  3. 在后面的章节中,将会出现部分导入,如下面的代码所示。这只是从库中加载mean方法:

    from numpy import mean    # only import the mean method of numpy
    

安装代码包

将该类的代码包复制到C:/Code文件夹。

附加资源

本书的代码包也托管在 GitHub 上,网址为:https://GitHub . com/trainingypbackt/Data-Visualization-with-Python

我们还有来自 github.com/PacktPublis…

一、数据可视化和数据探索的重要性

学习目标

本章结束时,您将能够:

  • 解释为什么数据可视化很重要
  • 计算基本统计值,如中值、平均值和方差
  • 使用 NumPy 进行数据争论
  • 用熊猫来争论数据

在这一章中,你还将了解 NumPy 和熊猫的基本操作。

简介

与机器不同,人们通常不具备从给定数据中的一组随机数字和信息中解读大量信息的能力。虽然他们可能知道数据的基本组成,但他们可能需要帮助才能完全理解它。在我们所有的逻辑能力中,我们通过视觉信息的处理最能理解事物。当数据被可视化表示时,理解复杂构建和数字的概率会增加。

Python 最近作为一种编程语言出现,在数据分析方面表现良好。Python 有跨数据科学管道的应用,可以将数据转换成可用的格式,对其进行分析,并从数据中提取有用的结论来很好地表示它。它提供了数据可视化库,可以帮助您快速组装图形表示。

在本书中,您将学习如何将 Python 与各种库结合使用,例如 NumPy熊猫Matplotlibseaborngeo lotlib,以使用真实世界的数据创建有影响力的数据可视化。除此之外,你还将了解不同类型图表的特点,并比较它们的优缺点。这将帮助您选择适合可视化数据的图表类型。

一旦我们理解了基础知识,我们就可以涵盖更高级的概念,例如交互式可视化以及如何使用 Bokeh 来创建讲述故事的动画可视化。完成本书后,您将能够执行数据辩论,提取重要信息,并以描述的方式可视化您的见解。

数据可视化简介

电脑和智能手机以数字格式存储姓名和数字等数据。数据表示是指可以存储、处理和传输数据的形式。

陈述可以讲述一个故事,并向你的观众传达重要的发现。如果不适当地对你的信息进行建模,用它来做出有意义的发现,它的价值就会降低。创建表示有助于实现更清晰、更简洁、更直接的信息视角,使任何人都更容易理解数据。

信息并不真正等同于数据。表示是发现隐藏在数据中的见解的有用工具。因此,表示将信息转换成有用的数据。

数据可视化的重要性

与任何其他形式的数据相比,可视化数据非常容易理解。通过使用可视化,我们可以更好地了解数据包含的内容,而不仅仅是查看 Excel 电子表格列中的数据。例如,很容易从下图给出的数字数据中看到一种模式:

Figure 1.1: A simple example of data visualization

图 1.1:数据可视化的一个简单例子

可视化数据有许多优点,例如:

  • 复杂的数据很容易理解
  • 可以创建异常值、目标受众和未来市场的简单可视化表示
  • 讲故事可以用仪表盘和动画来完成
  • 可以通过交互式可视化来探索数据

数据角力

为了从可视化数据中得出结论,我们需要处理我们的数据,并将其转换为最佳的表示形式。这就是数据角力的用武之地。它是以一种允许机器学习算法显示和理解数据的方式来扩充、转换和丰富数据的学科。

查看下面的数据争论流程图,了解如何获得准确且可操作的数据,供业务分析师处理。如您所见,员工敬业度数据最初是原始形式。它将作为数据帧导入,稍后将被清理。然后,清理后的数据被转换成相应的图形,从中可以对见解进行建模。基于这些见解,我们可以交流最终结果。例如,可以根据从反馈调查、员工任期、离职面谈、一对一会议等收集的原始数据来衡量员工敬业度。这些数据经过清理,并根据推荐、对领导的信任和晋升范围等参数制成图表。百分比,即从图表中产生的见解,有助于我们得出结果,从而确定员工敬业度的衡量标准:

Figure 1.2: Data wrangling process to measure employee engagement

图 1.2:衡量员工敬业度的数据争论过程

可视化工具和库

有几种方法可以创建数据可视化。根据您的背景,您可能希望使用非编码工具,如 Tableau ,它使您能够对数据有一个良好的感觉。除了将在本书中使用的 Python 之外, MATLABR 在数据分析中被大量使用。

然而,Python 是业内最流行的语言。它的易用性和您可以操作和可视化数据的速度,加上大量库的可用性,使 Python 成为最佳选择。

注意

MATLAB(www.mathworks.com/products/ma…)、R(www.r-project.org)和 Tableau(www.tableau.com)都不是本书的一部分,所以我们只涵盖重点介绍的 Python 工具和库。

统计概述

统计学是数值数据的分析、收集、解释和表示的组合。概率是对事件发生可能性的度量,量化为 0 到 1 之间的数字。

一个概率分布是一个为每个可能事件提供概率的函数。概率分布经常用于统计分析。概率越高,事件发生的可能性越大。概率分布有两种类型,即离散概率分布和连续概率分布。

一个离散概率分布显示了一个随机变量可以取的所有值,以及它们的概率。下图说明了离散概率分布的一个示例。如果我们有一个 6 面骰子,我们可以在 1 和 6 之间滚动每个数字。根据滚动的数量,我们有六个事件可以发生。滚动任何数字的概率相等,六个事件中任何一个发生的概率为 1/6:

Figure 1.3: Discrete probability distribution for die rolls

图 1.3:模具辊的离散概率分布

A 连续概率分布定义了连续随机变量每个可能值的概率。下图说明了连续概率分布的示例。这个例子说明了开车回家所需时间的分布。在大多数情况下,大约需要 60 分钟,但有时需要更少的时间,因为没有交通,有时需要更多的时间,如果有交通堵塞:

Figure 1.4: Continuous probability distribution for the time taken to reach home

图 1.4:到家时间的连续概率分布

中央趋势的度量

中心趋势的度量通常被称为平均值,描述概率分布的中心值或典型值。我们将在本章中讨论三种平均值:

  • Mean: The arithmetic average that is computed by summing up all measurements and dividing the sum by the number of observations. The mean is calculated as follows:

  • 中值:这是有序数据集的中间值。如果有偶数个观察值,中间值将是两个中间值的平均值。与平均值相比,中位数不太容易出现异常值,因为异常值是数据中的独特值。

  • 模式:我们对中枢倾向的最后一个衡量,模式定义为最频繁值。在多个值同样频繁的情况下,可能有多个模式。

示例:

一个骰子滚动了十次,我们得到了以下数字:4、5、4、3、4、2、1、1、2 和 1。

平均值的计算方法是将所有事件相加,然后除以观察次数:(4+5+4+3+4+2+1+1+2+1)/10=2.7。

为了计算中间值,必须根据模辊的值对其进行排序。有序值如下:1,1,1,2,2,3,4,4,4,5。因为我们有偶数个模辊,我们需要取两个中间值的平均值。两个中间值的平均值为(2+3)/2=2.5。

模式是 1 和 4,因为它们是最常见的两个事件。

离散度的度量

离散度,也称为可变性,是概率分布被拉伸或压缩的程度。

分散的不同度量如下:

  • 方差:方差是偏离均值的平方的期望值。它描述了一组数字离它们的平均值有多远。方差计算如下:

  • 标准差:是方差的平方根。
  • 范围:这是一个数据集中最大值和最小值的差值。
  • 四分位数区间:也叫中间延伸中间 50% ,是第 75 和第 25 个百分位数之间的差值,或上下四分位数之间的差值。

相关性

到目前为止,我们讨论的度量只考虑了单个变量。相比之下,相关性描述了两个变量之间的统计关系:

在正相关中,两个变量都向同一个方向移动

在负相关中,变量向相反的方向移动

在零相关中,变量是不相关的

注意

你应该知道的一件事是,相关性并不意味着因果关系。相关性描述两个或多个变量之间的关系,而因果关系描述一个事件是如何由另一个事件引起的。例如:穿着鞋子睡觉与醒来时头痛有关。这并不意味着穿着鞋子睡觉会导致早上头痛。可能还有第三个隐藏的变量,例如,有人前一天晚上工作到很晚,这导致他们都穿着鞋子睡着了,醒来时头疼。

示例:

你想找一个体面的公寓出租,与你已经找到的其他公寓相比,不要太贵。你在网站上找到的其他公寓价格如下:每月 700 美元、850 美元、1500 美元和 750 美元:

  • 平均值为
  • 中位数为
  • 标准偏差为
  • 范围为
  • 在这种情况下,中位数是一个更好的统计指标,因为它不太容易出现异常值(租金为 1,500 美元)。

数据类型

了解您正在处理的数据类型非常重要,这样您就可以选择正确的统计度量和正确的可视化。我们将数据分为分类/定性和数字/定量。分类数据描述特征,例如,物体的颜色或一个人的性别。我们可以进一步将分类数据分为名义数据和序数数据。与名义数据相反,序数数据是有顺序的。

数值数据可以分为离散数据和连续数据。如果数据只能有某些值,我们就称之为离散数据,而连续数据可以取任何值(有时限于一个范围)。

另一个要考虑的方面是数据是否有一个时间域——换句话说,它是受时间的约束还是随着时间的推移而变化?如果数据绑定到某个位置,显示空间关系可能会很有趣,因此您也应该记住这一点:

Figure 1.5: Classification of types of data

图 1.5:数据类型的分类

汇总统计

在现实应用中,我们经常会遇到巨大的数据集,因此汇总统计用于汇总数据的重要方面。它们是以简洁明了的方式交流大量信息所必需的。

我们已经讨论了中心趋势和离差的度量,它们都是汇总统计。重要的是要知道,中心趋势的度量显示了一组数据值中的中心点,而离差的度量显示了数据值的分布情况。

下表概述了哪种中心趋势度量最适合特定类型的数据:

Figure 1.6: Best suited measures of central tendency for different data types

图 1.6:不同类型数据的中心趋势的最适合度量

NumPy

在处理数据时,我们经常需要一种处理多维数组的方法。正如我们之前讨论的,我们还必须对这些数据应用一些基本的数学和统计运算。这正是 NumPy 定位自己的地方。它支持大型 n 维数组,是许多高级数学和统计运算的内置支持。

注意

在 NumPy 之前,有一个名为 Numeric 的库。然而,它不再被使用,因为 NumPy 的签名 ndarray 允许对大型和高维矩阵进行高效处理。

那些数组是 NumPy 的本质。它们比使用 Python 的内置列表更快。除了内置的列表数据类型之外,ndarrays 还提供了一个跨越式的内存视图(例如,Java 中的int[])。因为它们是均匀类型的,这意味着所有的元素必须是相同的类型,所以步幅是一致的,这导致更少的内存浪费和更好的访问时间。

一个步距是一个数组中两个相邻元素开始之间的位置数。它们通常以字节或数组元素的大小单位来度量。步幅可以大于或等于元素的大小,但不能小于元素的大小,否则它将与下一个元素的内存位置相交。

注意

请记住,NumPy 数组具有“已定义”的数据类型。这意味着您不能将字符串插入整数类型数组。NumPy 主要用于双精度数据类型。

练习 1:加载样本数据集并计算平均值

注意

所有练习和活动都将在 Jupyter 笔记本中开发。请从https://GitHub . com/trainingypbackt/Data-Visualization-with-Python下载带有所有准备好的模板的 GitHub 资源库

在本练习中,我们将加载normal_distribution.csv数据集,并计算其中每行和每列的平均值:

  1. Open the exercise01.ipynb Jupyter Notebook from the Lesson01 folder to implement this exercise.

    为此,您需要导航到该文件的路径。在命令行终端中,键入jupyter-lab.

  2. 现在,您将看到一个浏览器窗口打开,显示您在其中调用上一个命令的目录内容。点击exercise01.ipynb。这将打开笔记本。

  3. 第 01 章的笔记本现在应该已经打开,可以修改了。简短介绍后,您应该会看到一个导入必要依赖项的单元格。在这种情况下,我们将导入别名为

    # importing the necessary dependencies
    import numpy as np
    

    numpy

  4. Look for the cell that has a comment saying, "loading the dataset." This is the place you want to insert the genfromtxt method call. This method helps in loading the data from a given text or .csv file.

    完整的行应该如下所示:

    # loading the dataset
    dataset = np.genfromtxt('./data/normal_distribution.csv', delimiter=',')
    
  5. If everything works as expected, the generation should run through without any error or output. Have a look at the data you just imported by simply writing the name of the ndarray in the next cell. This is implemented in the following code. Simply executing a cell that returns a value such as an ndarray GI will use Jupyter formatting, which looks nicer and, in most cases, displays more information than using print:

    # looking at the dataset
    dataset
    

    前面代码的输出如下:

    Figure 1.7: The first rows of the normal_distribution.csv file

    图 1.7:正态分布. csv 文件的前几行
  6. To get a quick overview of our dataset, we want to print out the "shape" of it.

    这将为我们提供表单的输出(行、列)。使用dataset.shape命令打印出形状。我们也可以将行称为实例,将列称为特征。这意味着我们的数据集有 24 个实例和 8 个特征:

    # printing the shape of our dataset
    dataset.shape
    

    前面代码的输出如下:

    Figure 1.8: Shape of the dataset

    图 1.8:数据集的形状
  7. Calculating the mean is the next step once we've loaded and checked our dataset.

    numpy array中的第一行可以通过简单地用零索引来访问,比如:dataset[0]。正如我们之前提到的,NumPy 有一些用于计算的内置函数,例如 mean。因此,我们可以简单地调用np.mean()并传入数据集行来获得结果。打印输出应该如下所示:

    # calculating the mean for the first row
    np.mean(dataset[0])
    

    前面代码的输出如下:

    Figure 1.9: Mean of elements in the first row

    图 1.9:第一行元素的平均值
  8. We can also do the same for the first column by using np.mean() in combination with the column indexing dataset[:, 0]:

    # calculating the mean for the first column
    np.mean(dataset[:, 0])
    

    前面代码的输出如下:

    Figure 1.10: Mean of elements in the first column

    图 1.10:第一列中元素的平均值
  9. If we want to get the mean for every single row, aggregated in a list, we can make use of the axis tools of NumPy. By simply passing the axis parameter in the np.mean() call, we can define the dimension our data will be aggregated on.

    axis=0是水平的,axis=1是垂直的,所以如果我们想要每行都有结果,我们需要选择axis=1:

    # mean for each row
    np.mean(dataset, axis=1)
    

    前面代码的输出如下:

    Figure 1.11: Mean of elements for each row

    图 1.11:每行元素的平均值

    如果要有每一列的结果,需要选择axis=0

    # mean for each column
    np.mean(dataset, axis=0)
    

    前面代码的输出如下:

    Figure 1.12: Mean of elements for each column

    图 1.12:每列元素的平均值
  10. As the last task of this exercise, we also want to have the mean of the whole matrix. We could sum up all the values we retrieved in the previous steps, but NumPy allows us to simply pass in the whole dataset to do this calculation:

```py
# calculating the mean for the whole matrix
np.mean(dataset)
```

前面代码的输出如下:

![Figure 1.13: Mean of elements for the complete dataset ](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/9a817f6cff18481c9543730a88951544~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1771549303&x-signature=o7VeTeLh81qscxV6bJFiyh9VJ1w%3D)
图 1.13:完整数据集的元素平均值

恭喜你!您已经离将 NumPy 与打印库结合使用并创建有影响力的可视化效果又近了一步。由于我们已经介绍了最基本的内容,并在前面的练习中计算了平均值,现在就看您如何解决即将到来的活动了。

活动 1:使用 NumPy 计算给定数字的平均值、中值、方差和标准差

在本练习中,我们将使用所学的技能导入数据集并执行一些基本计算(平均值、中值、方差和标准差)来计算我们的任务。

我们希望巩固我们的新技能并熟悉 NumPy:

  1. Lesson01文件夹打开activity01.ipynb Jupyter 笔记本,执行本活动。

  2. 现在,import numpy进入你的 Jupyter 笔记本,给它取别名np

  3. 使用numpygenfromtxt方法加载normal_distribution.csv数据集。

  4. 看看数据库,确保一切正常。

  5. 给定数据集,进入并使用内置的numpy方法。

  6. 使用这些方法,首先计算第三行、最后一列以及前 3 行和前 3 列的交集的平均值。

  7. 然后,计算最后一行、最后 3 列和每行的中间值。

  8. 计算每列的方差、最后 2 行和前 2 列的交集。

  9. Calculate the standard deviation for the dataset.

    注意:

    这项活动的解决方案可以在第 244 页找到。

恭喜你!您已经使用 NumPy 完成了第一项活动。在接下来的活动中,这些知识将得到进一步巩固。

基本数值运算

在本节中,我们将学习基本的 NumPy 操作,如索引、切片、拆分和迭代,并在活动中实现它们。

索引

在高级别上,索引 NumPy array中的元素的工作方式与内置 Python 列表相同。因此,我们能够索引多维矩阵中的元素:

dataset[0]       # index single element in outermost dimension
dataset[-1]      # index in reversed order in outermost dimension
dataset[1, 1]    # index single element in two-dimensional data
dataset[-1, -1]  # index in reversed order in two-dimensional data

切片

切片也改编自 Python 的列表。在处理大量数据时,能够轻松地将部分列表分割成新的数组非常有帮助:

dataset[1:3]         # rows 1 and 2
dataset[:2, :2]      # 2x2 subset of the data 
dataset[-1, ::-1]    # last row with elements reversed
dataset[-5:-1, :6:2] # last 4 rows, every other element up to index 6

分裂

拆分数据在许多情况下都是有帮助的,从只绘制一半的时间序列数据到为机器学习算法分离测试和训练数据。

有两种方法可以横向和纵向拆分数据。水平分裂可以用hsplit方法进行。垂直分裂可以用vsplit方法完成:

np.hsplit(dataset, (3))  # split horizontally in 3 equal lists
np.vsplit(dataset, (2))  # split vertically in 2 equal lists

迭代

迭代 NumPy 数据结构 ndarrays 也是可能的。它一个接一个地遍历整个数据列表,访问数组中的每个元素一次。考虑到它们可以有几个维度,索引变得非常复杂。

nditer是在给定数量的数组上迭代的多维迭代器对象:

# iterating over whole dataset (each value in each row)
for x in np.nditer(dataset):
    print(x)

ndenumerate会给我们确切的这个指数,从而为第一行的第二个值返回(01):

# iterating over whole dataset with indices matching the position in the dataset
for index, value in np.ndenumerate(dataset):
    print(index, value) 

活动 2:索引、切片、拆分和迭代

在本练习中,我们将使用 NumPy 的特性来索引、切片、拆分和迭代数组,以巩固我们所学的内容。我们的客户希望我们证明我们的数据集很好地分布在平均值 100 附近:

  1. Lesson01文件夹打开activity02.ipynb Jupyter 笔记本,执行本活动。

  2. 现在,import numpy进入你的 Jupyter 笔记本,给它取别名np

  3. 使用 NumPy 加载normal_distribution.csv数据集。通过查看数据库,确保一切正常,就像在前面的活动中一样。遵循笔记本中的任务描述。

  4. 加载数据集后,使用前面讨论的索引功能对数据集的第二行(第二行)进行索引,对数据集的最后一个元素(最后一行)进行索引,对第二行的第一个值(第二行,第一个值)进行索引,并对倒数第二行的最后一个值进行索引(使用组合访问)。

  5. 创建输入的子列表需要切片。对前两行和前两列的四个元素(2x2)的交集进行切片,选择第五行的每隔一个元素,并颠倒输入顺序,以相反的顺序选择前两行。

  6. 如果我们需要一个更小的数据集,我们也可以使用拆分来有效地划分我们的数据集。使用这个概念将数据集水平分割成三个相等的部分,并在索引 2 上垂直分割数据集。

  7. The last task in this activity will be iterating over the complete dataset. Use the previously discussed methods to iterate over the whole dataset, with indices matching the position in the dataset.

    注意:

    这项活动的解决方案可以在第 248 页找到。

恭喜你!我们已经介绍了 NumPy 的大多数基本数据争论方法。在下一个活动中,我们将了解更高级的功能,这些功能将为您提供更好地了解数据的工具。

高级数字操作

在本节中,我们将学习 GI 高级 NumPy 操作,如过滤、排序、组合和整形,并在活动中实现它们。

过滤

过滤是一个非常强大的工具,如果你想避免异常值,它可以用来清理你的数据。这也有助于更好地了解您的数据。

除了dataset[dataset > 10]简写符号外,我们还可以使用内置的 NumPy extract方法,它使用不同的符号做同样的事情,但是用更复杂的例子给我们更大的控制力。

如果我们只想提取符合我们给定条件的值的索引,我们可以使用内置的where方法。例如,np.where(dataset > 5)将返回初始数据集中大于 5:

dataset[dataset > 10]                   # values bigger than 10
np.extract((dataset < 3), dataset)      # alternative – values smaller than 3
dataset[(dataset > 5) & (dataset < 10)] # values bigger 5 and smaller 10
np.where(dataset > 5)                   # indices of values bigger than 5 (rows and cols)

排序

对数据集的每一行进行排序非常有用。使用 NumPy,我们还能够对其他维度进行排序,例如列。

此外,argsort为我们提供了获得索引列表的可能性,这将产生排序列表:

np.sort(dataset)          # values sorted on last axis
np.sort(dataset, axis=0)  # values sorted on axis 0
np.argsort(dataset)       # indices of values in sorted list

组合

将同一维度的两个数据集保存到不同的文件中时,将行和列堆叠到现有数据集上会很有帮助。

给定两个数据集,我们使用 vstackdataset_2之上“堆叠”dataset_1,这将给我们一个组合数据集,所有行来自dataset_1,然后是所有行来自dataset_2

如果我们使用 hstack ,我们将数据集“一个挨着一个”堆叠,这意味着第一行dataset_1的元素后面将是第一行dataset_2的元素。这将应用于每一行:

np.vstack([dataset_1, dataset_2])        # combine datasets vertically
np.hstack([dataset_1, dataset_2])        # combine datasets horizontally
np.stack([dataset_1, dataset_2], axis=0) # combine datasets on axis 0
注意

结合堆叠可能需要一些时间来适应。更多信息请查看 NumPy 文档中的示例:https://docs . scipy . org/doc/NumPy-1 . 15 . 0/reference/generated/NumPy . hstack . html .

重塑

重塑对于某些算法来说至关重要。根据数据的性质,它可能有助于您降低维度,使可视化更容易:

dataset.reshape(-1, 2)       # reshape dataset to two columns x rows
np.reshape(dataset, (1, -1)) # reshape dataset to one row x columns

这里,-1是 NumPy 自动识别的未知维度。NumPy 将首先计算出任何给定数组的长度和剩余维度,从而确保它满足给定的上述标准。

活动 3:过滤、排序、组合和整形

NumPy 的最后一个活动提供了一些更复杂的任务来巩固我们的学习。它还将结合大部分以前学过的方法作为总结。请执行以下步骤:

  1. Lesson01文件夹打开activity03.ipynb Jupyter 笔记本,执行本活动。

  2. NumPy 将是此活动唯一必需的依赖项,因此请确保导入它。

  3. 再次,使用 NumPy 加载normal_distribution.csv数据集。通过查看数据库,确保一切正常。

  4. 加载数据集后,使用前面讨论的过滤功能过滤大于 105 的值,过滤介于 90 到 95 之间的值,并获取差值小于 1 到 100 的值的索引。

  5. 当试图在序数数据类型列上显示数据时,对数据进行排序是一项重要功能。使用排序对每行的值进行排序,对每列的值进行排序,得到每行的位置索引,得到每行的 3 个最小值(其余值不排序)。

  6. 使用本章练习 02 中的拆分数据,我们还可以使用前面讨论的组合特征将第一列的后半部分重新添加在一起,将第二列添加到我们的组合数据集,并将第三列添加到我们的组合数据集。

  7. Use the reshaping features to reshape the dataset in a one-dimensional list with all the values and reshape the dataset into a matrix with only two columns.

    注意:

    这项活动的解决方案可以在第 252 页找到。

接下来,我们将学习熊猫,这将在处理比简单的多维数字数据更复杂的数据时带来几个优势。pandas 还支持数据集中不同的数据类型,这意味着我们可以有保存字符串的列和其他有数字的列。

正如你所看到的,NumPy 本身有一些非常强大的工具。它们中的一些与熊猫结合时甚至更强大。

熊猫

pandsPython 库提供了数据结构和方法来处理不同类型的数据,例如数值和时间数据。这些操作易于使用,并且针对性能进行了高度优化。

数据格式如 CSVJSON 和数据库可用于数据框的创建。数据帧是数据的内部表示,与表非常相似,但功能更强大。导入和读取文件和内存中的数据被抽象成一个用户友好的界面。在处理丢失的数据时,pandas 提供了内置的解决方案来清理和扩充您的数据,这意味着它会用合理的值来填充丢失的值。

集成的索引和基于标签的切片结合花哨的索引(我们已经在 NumPy 上看到的)使得处理数据变得简单。更复杂的技术,如重塑旋转、融合数据,以及轻松连接合并数据的可能性,为正确处理您的数据提供了强大的工具。

如果你正在处理时间序列数据,诸如日期范围生成频率转换移动窗口统计等操作可以为你的扯皮提供一个高级界面。

注意

熊猫的安装说明可以在这里找到:pandas.pydata.org/

大熊猫相对于 NumPy 的优势

以下是熊猫的一些优点:

  • 高抽象层次 : pandas 比 NumPy 有更高的抽象层次,给了用户更简单的交互界面。它抽象出一些更复杂的概念,使其更容易使用和理解。
  • 少一点直觉:很多方法,比如加入、选择、加载文件,都是可以用的,没有太多的直觉,也没有带走熊猫很多强大的天性。
  • 更快的处理:数据帧的内部表示允许对某些操作进行更快的处理。当然,这总是取决于数据及其结构。
  • 简单的数据框设计:数据框是为大型数据集的操作而设计的。

熊猫的劣势

以下是熊猫的一些缺点:

  • 不太适用:由于抽象程度较高,一般比 NumPy 不太适用。尤其是当超出其使用范围时,操作很快变得非常复杂和困难。

  • 更多的磁盘空间:由于数据帧的内部表示和熊猫为了更高性能的执行而交换磁盘空间的方式,复杂操作的内存使用可能会激增。

  • 性能问题:特别是在执行不推荐的重连接时,内存使用可能会变得很关键,并可能导致性能问题。

  • Hidden complexity: The comparatively simple interface has its downsides too. Less experienced users often tend to overuse methods and execute them several times instead of reusing what they've already calculated. This hidden complexity makes users think that the operations themselves are simple, which is not the case.

    注意

    始终尝试思考如何设计您的工作流,而不是过度使用操作。

练习 2:加载样本数据集并计算平均值

在本练习中,我们将加载world_population.csv数据集,并计算一些行和列的平均值。我们的数据集保存了每个国家的年人口密度。让我们用熊猫来获得一些快速简单的见解:

  1. Lesson01文件夹打开exercise02.ipynb Jupyter 笔记本,执行本练习。

  2. 导入熊猫库:

    # importing the necessary dependencies
    import pandas as pd
    
  3. 导入熊猫后,我们可以使用read_csv方法加载上述数据集。我们希望使用包含国家名称的第一列作为我们的索引。我们将使用index_col参数。完整的一行应该是这样的:

    # loading the dataset
    dataset = pd.read_csv('./data/world_population.csv', index_col=0)
    
  4. As before, have a look at the data you just imported by simply writing the name of the dataset in the next cell. pandas uses a data structure called DataFrames. We want to only print some of the rows to avoid filling the screen. pandas DataFrames come with two methods, head() and tail(), to do this for you. Both take number, n, as a parameter, which describes how many rows should be returned:

    注意

    简单地执行一个返回值的单元格,如数据框,将使用 Jupyter 格式,这看起来更好,在大多数情况下,比使用print显示更多的信息。

    # looking at the dataset
    dataset.head()
    

    前面代码的输出如下:

    Figure 1.14: The first five rows of our dataset

    图 1.14:数据集的前五行
  5. To get a quick overview of our dataset, we want to print out its shape.

    这将以(rows, columns)的形式给出输出。使用dataset.shape命令打印出形状。这与 NumPy ndarrays 的工作原理完全相同:

    # printing the shape of our dataset
    dataset.shape
    

    前面代码的输出如下:

    Figure 1.15: The shape of the dataset

    图 1.15:数据集的形状
  6. Calculating the mean is the next step, once we've loaded and checked our dataset. Indexing rows work a little bit differently and we'll look at this in detail in the activities that follow. For now, we only want to index the column with the year 1961.

    熊猫数据帧有内置的计算功能,如mean。这意味着我们可以简单地调用dataset.mean()来获得结果。

    打印输出应该如下所示:

    # calculating the mean for 1961 column
    dataset["1961"].mean()
    

    前面代码的输出如下:

    Figure 1.16: Mean of elements in the 1961 column

    图 1.16:1961 年栏中元素的平均值
  7. Just to see the difference in population density over the years, we'll do the same with the column for the year 2015 (the population more than doubled in the given time range):

    # calculating the mean for 2015 column
    dataset["2015"].mean()
    

    前面代码的输出如下:

    Figure 1.17: Mean of elements in the 2015 column

    图 1.17:2015 年栏中元素的平均值
  8. If we want to get the mean for every single country (row), we can make use of pandas axis tools. By simply passing the axis parameter in the dataset.mean() call, we define the dimension our data will be aggregated on.

    axis=0是水平的(每列)axis=1是垂直的(每行),所以如果我们想得到每行的结果,我们需要选择axis=1。由于我们的数据集中有 264 行,我们希望将返回国家的数量限制在 10 个。如前所述,我们可以使用参数为 10 的head(10)tail(10)方法:

    # mean for each country (row)
    dataset.mean(axis=1).head(10)
    

    前面代码的输出如下:

    Figure 1.18: Mean of elements in the first 10 countries (rows)

    图 1.18:前 10 个国家(行)元素的平均值

    下面是 tail 方法的代码:

    # mean for each feature (col)
    dataset.mean(axis=0).tail(10)
    

    前面代码的输出如下:

    Figure 1.19: Mean of elements for the last 10 years (columns)

    图 1.19:过去 10 年元素平均值(列)
  9. The last task of this exercise is to calculate the mean of the whole DataFrame. Since pandas DataFrames can have different datatypes in each column, aggregating this value on the whole dataset out of the box makes no sense. By default, axis=0 will be used, which means that this will give us the same result as the cell before:

    # calculating the mean for the whole matrix
    dataset.mean()
    

    前面代码的输出如下:

    Figure 1.20: Mean of elements for each column

图 1.20:每列元素的平均值

恭喜你!我们现在已经看到熊猫的界面有一些类似于 NumPy 的方法,这使得它真的很容易理解。我们现在已经介绍了最基本的内容,这将帮助你解决第一个使用熊猫的活动。在下面的活动中,你将巩固你对熊猫的基本知识,并使用你刚刚学习的方法来解决几个计算任务。

活动 4:用熊猫计算给定数字的平均值、中位数和方差

在本活动中,我们将利用之前学习的导入数据集和进行一些基本计算的技能,并应用它们来解决我们使用熊猫的第一个活动的任务。

我们想巩固我们的新技能,熟悉熊猫:

  1. Lesson01文件夹中打开 Jupyter 笔记本activity04.ipynb执行本活动。

  2. 由于我们现在正在和熊猫一起工作,我们必须在活动开始时导入它,以便能够在笔记本中使用它。

  3. 使用熊猫的read_csv方法加载world_population.csv数据集。

  4. 给定数据集,进入并使用熊猫的内置方法计算第三行、最后一行和国家德国的平均值。

  5. 然后,计算最后一行、最后 3 行和前 10 个国家的中位数。

  6. Last, calculate the variance of the last 5 columns.

    注意:

    这项活动的解决方案可以在第 256 页找到。

恭喜你!您已经完成了与熊猫的第一次活动,这向您展示了与 NumPy 和熊猫合作时的一些相似之处和不同之处。在接下来的活动中,这些知识将得到巩固。你还将被介绍熊猫更复杂的特征和方法。

熊猫的基本操作

在这一节中,我们将学习基本的熊猫操作,如索引、切片和迭代,并通过一个活动来实现它。

索引

用熊猫做索引比用 NumPy 要复杂一点。我们只能访问带有单个括号的列。要使用行的索引来访问它们,我们需要iloc方法。如果我们想通过index_col(在read_csv调用中设置)访问它们,我们需要使用loc方法:

dataset["2000"]                    # index the 2000 col
dataset.iloc[-1]                   # index the last row
dataset.loc["Germany"]             # index the row with index Germany
dataset[["2015"]].loc[["Germany"]] # index row Germany and column 2015

切片

用熊猫切片更有力量。我们可以使用我们已经在 NumPy 中看到的默认切片语法,或者使用多重选择。如果我们想按名称划分不同的行或列,我们可以简单地在括号中传递一个列表:

dataset.iloc[0:10]                 # slice of the first 10 rows
dataset.loc[["Germany", "India"]]  # slice of rows Germany and India
# subset of Germany and India with years 1970/90
dataset.loc[["Germany", "India"]][["1970", "1990"]] 

迭代

迭代数据帧也是可能的。考虑到它们可以有几个维度和数据类型,索引是非常高级的,并且必须分别对每一行进行迭代:

# iterating the whole dataset
for index, row in dataset.iterrows():
    print(index, row)

系列

熊猫系列是一维标签阵列,能够保存任何类型的数据。我们可以通过从. csv 文件、Excel 电子表格或 SQL 数据库中加载数据集来创建系列。有许多不同的方法来创建它们。例如:

  • NumPy 数组:

    # import pandas
    import pandas as pd
    # import numpy
    import numpy as np
    # creating a numpy array
    numarr = np.array(['p','y','t','h','o','n'])
    ser = pd.Series(numarr)
    print(ser)
    
  • 熊猫名单:

    # import pandas
    import pandas as pd
    # creating a pandas list
    plist = ['p','y','t','h','o','n']
    ser = pd.Series(plist)
    print(ser)
    

活动 5:使用熊猫进行索引、切片和迭代

在本练习中,我们将使用前面讨论过的熊猫特征,使用熊猫系列对数据帧进行索引、切片和迭代。为了深入了解数据集,我们需要能够对数据进行显式索引、切片和迭代。例如,我们可以比较几个国家的人口密度增长。

在查看了不同的操作之后,我们想要显示德国、新加坡、美国和印度在 1970 年、1990 年和 2010 年的人口密度:

  1. Lesson01文件夹打开activity05.ipynb Jupyter 笔记本,执行本活动。

  2. 在加载数据集之前,我们需要导入熊猫。我们将再次使用pd别名来指代熊猫。

  3. 使用熊猫加载world_population.csv数据集。查看数据帧,确保一切正常。

  4. 加载数据集后,使用前面讨论的索引功能为美国的行、第二行到最后一行、2000 年的列(系列)和 2000 年的印度人口密度编制索引。

  5. 创建数据集的子列表需要切片。使用此概念将第 2 行到第 5 行中的国家分割开来,将德国、新加坡、美国和印度分割开来,并将德国、新加坡、美国和印度分割成 1970 年、1990 年和 2010 年的人口密度。

  6. The last task in this activity will be iterating over the first three countries in our dataset. Use the previously discussed iteration method to iterate over the whole dataset and print the name, country code, and population for the years 1970, 1990, and 2010.

    注意:

    这项活动的解决方案可以在第 261 页找到。

恭喜你!我们已经介绍了大多数使用熊猫的基本数据争论方法。在下一个活动中,我们将了解更高级的功能,如过滤、排序和整形,为下一章做准备。

先进熊猫行动

在本节中,我们将学习先进的熊猫操作,如过滤、排序和整形,并在活动中实现它们。

过滤

熊猫中的过滤比 NumPy 有更高级别的界面。你仍然可以使用基于“简单”括号的条件过滤。但是,您也可以使用更复杂的查询,例如,基于正则表达式筛选行:

dataset.filter(items=["1990"])      # only column 1994
dataset[(dataset["1990"] < 10)]     # countries'population density < 10 in 1999
dataset.filter(like="8", axis=1)    # years containing an 8
dataset.filter(regex="a$", axis=0)  # countries ending with a

排序

根据给定的行或列对每一行或每一列进行排序将有助于您更好地了解数据,并找到给定数据集的排名。有了熊猫,我们可以很容易地做到这一点。可以使用名为升序的参数进行升序和降序排序。当然,您可以通过在by = [ ]列表中提供多个值来进行更复杂的排序。然后,这些将用于对第一个值相同的值进行排序:

dataset.sort_values(by=["1999"])        # values sorted by 1999
# values sorted by 1999 descending
dataset.sort_values(by=["1994"], ascending=False)

重塑

重塑对于简化可视化和算法至关重要。但是,根据您的数据,这可能会变得非常复杂:

dataset.pivot(index=["1999"] * len(dataset), columns="Country Code", values="1999")
注意

重塑是一个非常复杂的话题。如果你想深入其中,这是一个很好的入门资源:bit.ly/2SjWzaB

活动 6:过滤、排序和整形

熊猫的最后一项活动提供了一些更复杂的任务,也结合了以前学到的大部分方法作为总结。完成这项活动后,学生应该能够阅读最基本的熊猫代码,并理解其逻辑:

  1. Lesson01文件夹打开activity06.ipynb Jupyter 笔记本,执行本活动。有关如何在 JupyterLab 中打开 Jupyter 笔记本的说明,请参考本章的介绍。

  2. 过滤、排序和整形都是熊猫的方法。在我们使用它们之前,我们必须进口熊猫。

  3. Again, load the world_population.csv dataset using pandas and make sure everything works by having a look at the DataFrames:

    Figure 1.21: Looking at the first two columns of our dataset

    图 1.21:查看数据集的前两列
  4. 加载数据集后,使用前面讨论的过滤功能,以列的形式获取 1961 年、2000 年和 2015 年,以及 2000 年人口密度大于 500 的所有国家。此外,使用过滤获得一个新的数据集,该数据集只包含 2000 年及以后的年份、以 A 开头的国家以及包含“土地”一词的国家

  5. 当试图在序数数据类型列上显示数据时,对数据进行排序是一项重要功能。使用排序操作按 1961 年的升序、2015 年的升序和 2015 年的降序对值进行排序。

  6. If our input dataset does not suit our needs, we have to reshape it. Use the reshaping features to reshape the dataset to 2015 as row and country codes as columns.

    注意:

    这项活动的解决方案可以在第 267 页找到。

你现在已经完成了关于熊猫的主题,这一章到此结束。我们已经了解了帮助您争论和处理数据的基本工具。熊猫本身是一个令人难以置信的强大和大量使用的数据争论工具。

总结

NumPy 和熊猫是数据角力的必备工具。它们的用户友好的界面和高性能的实现使数据处理变得容易。尽管它们只对我们的数据集提供了一点点洞察,但它们对于争论、扩充和清理我们的数据集绝对有价值。掌握这些技能将会提高你的可视化质量。

在这一章中,我们学习了 NumPy 和熊猫的基础知识,以及统计学的概念。尽管所涵盖的统计概念非常基本,但它们对于丰富我们的可视化是必要的,因为在大多数情况下,我们的数据集并不直接提供这些信息。这种实践经验将帮助您实施以下章节中的练习和活动。

在下一章中,我们将关注不同类型的可视化,以及如何决定哪种可视化最适合您的情况。这将为您提供理论知识,以便您知道何时使用特定的图表类型以及原因。它还将奠定章节的基础,重点是教你如何使用 Matplotlib 和 seaborn 来创建所讨论的绘图。在我们用 Matplotlib 和 seaborn 介绍了基本的可视化技术之后,我们将深入探讨交互式和动画图表的可能性,这将在我们的可视化中引入讲故事的元素。

二、你需要了解的所有绘图

学习目标

本章结束时,您将能够:

  • 确定给定数据集和场景的最佳绘图类型
  • 解释某些绘图的设计实践
  • 设计出色的有形可视化效果

在本章中,我们将学习不同类型绘图的基础知识。

简介

在本章中,我们将关注各种可视化,并确定哪种可视化最适合显示给定数据集的特定信息。我们将详细描述每一个可视化,并给出实际的例子,例如随着时间的推移比较不同的股票,或者比较不同电影的收视率。从比较图开始,它非常适合于比较多个变量随时间的变化,我们将看看它们的类型,如折线图、条形图和雷达图。关系图便于显示变量之间的关系。我们将介绍显示两个变量之间关系的散点图、三个变量的气泡图、变量对的相关图,最后是热图。

下面将解释组合图,它用于可视化作为整体一部分的变量,以及饼图、堆叠条形图、堆叠面积图和维恩图。为了更深入地了解变量的分布,使用了分布图。作为分布图的一部分,直方图、密度图、箱线图和小提琴图将被涵盖。最后,我们将讨论点地图、连接地图和点地图,它们可以分为地理图。地理图对于可视化地理空间数据非常有用。

对比图

比较图包括非常适合比较多个变量或变量随时间变化的图表。对于项目之间的比较,条形图(也称为柱形图)是最好的方法。折线图非常适合可视化随时间变化的变量。对于某个时间段(比如说,少于十个时间点),也可以使用垂直条形图。雷达图或蜘蛛图非常适合可视化多个组的多个变量。

折线图

折线图用于显示连续时间段内的定量值,并将信息显示为一系列。折线图非常适合由直线段连接的时间序列。

该值位于 y 轴上,而 x 轴是时间刻度。

用途:

  • 折线图非常适合比较多个变量以及可视化单个和多个变量的趋势,尤其是如果数据集有多个时间段(大约超过十个)。
  • 对于较小的时间段,垂直条形图可能是更好的选择。

下图显示了 20 年来房地产价格(百万美元)的趋势。折线图非常适合显示数据趋势:

Figure 2.1: Line chart for a single variable

图 2.1:单一变量的折线图

:

下图是一个多变量折线图,比较了谷歌、脸书、苹果、亚马逊和微软的股票收盘价。折线图对于比较价值和可视化股票趋势非常有用。正如我们所看到的,亚马逊显示了最高的增长:

Figure 2.2: Line chart showing stock trends for the five companies

图 2.2:显示五家公司股票趋势的折线图

设计实践:

  • 避免每个图表有太多线条

  • Adjust your scale so that the trend is clearly visible

    注意

    多变量绘图的设计实践。应该有一个图例来描述每个变量。

条形图

条形长度对值进行编码。条形图有两种变体:垂直条形图和水平条形图。

用途:

  • 虽然它们都用于比较不同类别的数值,但垂直条形图有时也用于显示一段时间内的单个变量。

条形图的注意事项和不注意事项:

  • 不要混淆垂直条形图和直方图。条形图比较不同的变量或类别,而直方图显示单个变量的分布。直方图将在本章后面讨论。
  • 另一个常见的错误是使用条形图来显示组或类别之间的中心趋势。在这些情况下,使用箱线图或小提琴图来显示统计度量或分布。

示例:

下图显示了一个垂直条形图。每个条形显示了五名学生在测试中获得的 100 分中的分数:

Figure 2.3: Vertical bar chart using student test data

图 2.3:使用学生测试数据的垂直条形图

下图显示了一个水平条形图。每个条形显示了五名学生在测试中获得的 100 分中的分数:

Figure 2.4: Horizontal bar chart using student test data

图 2.4:使用学生测试数据的水平条形图

下图比较了电影分级,给出了两个不同的分数。Tomatometer 是对这部电影给予正面评价的认可影评人的百分比。受众分数是 5 分中给出 3.5 分或更高分数的用户的百分比。如我们所见,《火星人》是唯一一部同时获得高分和观众评分的电影。**《霍比特人:意外之旅》**的观众评分相对于 Tomatometer 的评分相对较高,这可能是由于庞大的粉丝群:

Figure 2.5: Comparative bar chart

图 2.5:比较条形图

设计实践:

  • 对应于数值变量的轴应该从零开始。从另一个值开始可能会产生误导,因为它会使小的值差异看起来很大。
  • 使用水平标签,也就是说,只要横条的数量少,图表看起来不会太杂乱。

雷达图

雷达图,也称为蜘蛛网络图,将多个变量可视化,每个变量绘制在自己的轴上,形成一个多边形。所有轴都是径向排列的,从中心开始,彼此之间的距离相等,并且具有相同的刻度。

用途:

  • 雷达图非常适合比较单个组或多个组的多个定量变量。
  • 它们对于显示数据集中哪些变量得分高或低也很有用,是可视化性能的理想选择

示例:

下图显示了单个变量的雷达图。此图表显示学生在不同科目中的分数数据:

Figure 2.6: Radar chart for one variable (student)

图 2.6:一个变量(学生)的雷达图

下图显示了两个变量/组的雷达图。在这里,图表解释了两个学生在不同科目上的分数:

Figure 2.7: Radar chart for two variables (two students)

图 2.7:两个变量(两个学生)的雷达图

下图显示了多个变量/组的雷达图。每个图表显示学生在不同科目中的表现数据:

Figure 2.8: Radar chart with faceting for multiple variables (multiple subjects)

图 2.8:多变量(多主题)面阵雷达图

设计实践:

  • 尽量在一张雷达图上显示十个或更少的因子,以便于阅读。
  • 如上图所示,对多个变量/组使用刻面,以保持清晰。

活动 7:员工技能比较

你会得到四名员工(甲、乙、丙和丁)的五个属性的分数:效率、质量、承诺、负责任的行为和合作。您的任务是比较员工及其技能:

  1. 哪些图表适合这项任务?

  2. You are given the following bar and radar charts. List the advantages and disadvantages for both charts. Which is the better chart for this task in your opinion and why?

    Figure 2.9: Employee skills comparison with a bar chart

    图 2.9:员工技能与条形图的比较

    下图显示了员工技能的雷达图:

    Figure 2.10: Employee skills comparison with a radar chart

    图 2.10:员工技能与雷达图的比较
  3. What could be improved in the respective visualizations?

    注意:

    这项活动的解决方案可以在第 275 页找到。

关系图

关系图非常适合显示变量之间的关系。散点图显示了一个或多个组的两个变量之间的相关性。气泡图可以用来显示三个变量之间的关系。附加的第三个变量由点大小表示。热图对于揭示两个定性变量之间的模式或关联非常有用。相关图是显示多个变量之间相关性的完美可视化。

散点图

散点图显示两个数值变量的数据点,在两个轴上显示一个变量。

用途:

  • 您可以检测两个变量之间是否存在相关性(关系)。
  • 它们允许您使用不同的颜色绘制多个组或类别的关系。
  • 气泡图是散点图的变体,是可视化第三个变量相关性的绝佳工具。

示例:

下图显示了属于单个群体的人的身高体重的散点图:

Figure 2.11: Scatter plot with a single variable (one group)

图 2.11:单变量散点图(一组)

下图显示了与上图相同的数据,但不同组之间有所不同。在这种情况下,我们有不同的组: ABC :

Figure 2.12: Scatter plot with multiple variables (three groups)

图 2.12:多变量散点图(三组)

下图显示了不同种类动物的体重和最大寿命之间的关系。体重和最大寿命之间呈正相关:

Figure 2.13: Correlation between body mass and maximum longevity for animals

图 2.13:动物体重和最大寿命之间的相关性

设计实践:

  • 从零开始两个轴,以准确表示数据。
  • 对数据点使用对比色,避免对具有多个组或类别的散点图使用符号。

变量 : 带有边缘直方图的散点图

除了散点图显示两个数值变量之间的相关性之外,您还可以以直方图的形式绘制每个变量的边际分布,以便更好地了解每个变量的分布情况。

示例:

下图显示了鸟类动物的体重和最大寿命之间的相关性。还显示了边缘直方图,这有助于更好地了解这两个变量:

Figure 2.14: Correlation between body mass and maximum longevity of the Aves class with marginal histograms

图 2.14:体重和边缘直方图 Aves 类最大寿命之间的相关性

气泡图

气泡图通过引入第三个数值变量扩展了散点图。变量值由点的大小表示。圆点的面积与数值成正比。图例用于将点的大小与实际数值联系起来。

用途:

  • 显示三个变量之间的相关性。

:

下图显示了突出人类身高和年龄之间关系的气泡图:

Figure 2.15: Bubble plot showing relation between height and age of humans

图 2.15:显示人类身高和年龄关系的气泡图

设计实践:

  • 散点图的设计实践也适用于气泡图。
  • 不要将它用于非常大量的数据,因为太多的气泡会使图表难以阅读。

相关图

相关图是散点图和直方图的组合。本章稍后将详细讨论直方图。相关图或相关矩阵使用散点图可视化每对数值变量之间的关系。

相关矩阵的对角线以直方图的形式表示每个变量的分布。您还可以使用不同的颜色绘制多个组或类别的关系。相关图是探索性数据分析的一个很好的图表,可以让你对数据有所感觉,尤其是变量对之间的相关性。

示例:

下图显示了人类身高、体重和年龄的相关图。对角线图显示了每个变量的直方图。非对角线元素显示变量对之间的散点图:

图 2.16:单一类别相关图

下图显示了按颜色将数据样本分成不同组的相关图:

Figure 2.17: Correlogram with multiple categories

图 2.17:多类别相关图

设计实践:

  • 从零开始两个轴,以准确表示数据。
  • 对数据点使用对比色,避免对具有多个组或类别的散点图使用符号。

热图

热图是一种可视化,其中包含在矩阵中的值被表示为颜色或颜色饱和度。热图非常适合可视化多元数据,其中分类变量位于行和列中,数字或分类变量表示为颜色或颜色饱和度。

用途:

  • 多元数据的可视化。非常适合在数据中查找模式。

示例:

下图显示了各种电子商务网站电子产品类别页面上最受欢迎产品的热图:

Figure 2.18: Heatmap for popular products in the Electronics category

图 2.18:电子产品类热门产品的热图

变体 : 标注热图

让我们看看之前在带标注的热图中看到的相同示例:

Figure 2.19: Annotated heatmap for popular products in the Electronics category

图 2.19:电子产品类别中受欢迎产品的标注热图

活动 8:二十年来发生的道路事故

您将看到一张图表,其中提供了过去二十年中一月、四月、七月和十月发生的道路事故的相关信息:

  1. 确定道路事故发生次数最少的年份。
  2. 在过去的二十年中,找出事故明显减少的月份:

Figure 2.20: Total accidents over 20 years

图 2.20:20 年间的事故总数
注意:

这项活动的解决方案可以在第 275 页找到。

组成图

构图图如果你把某个事物看成是整体的一部分,那么构图图是理想的。对于静态数据,可以使用饼图、堆积条形图或维恩图。饼图甜甜圈图有助于显示各组的比例和百分比。如果你需要一个额外的维度,堆叠条形图是很好的。维恩图是可视化重叠组的最佳方式,其中每个组由一个圆圈表示。对于随时间变化的数据,可以使用堆积条形图或堆积面积图。

饼图

饼状图通过将一个圆分割成薄片来说明数值比例。每个弧长代表一个类别的一个比例。整圆等于 100%。对于人类来说,比较条比弧长更容易;因此,建议大部分时间使用条形图或堆叠条形图。

用途:

  • 比较作为整体一部分的项目。

示例:

下图显示了一个饼图,显示了板球场地的不同防守位置,如长开、长关、第三人和细腿:

Figure 2.21: Pie chart showing fielding positions in a cricket ground

图 2.21:显示板球场上防守位置的饼图

下图显示了世界各地的用水量:

Figure 2.22: Pie chart for global water usage

图 2.22:全球用水量饼图

设计实践:

  • 按照切片大小的递增/递减顺序排列切片,顺时针或逆时针排列。
  • 确保每个切片都有不同的颜色。

变体 : 甜甜圈图

饼图的另一种选择是环形图。与饼图相比,比较切片的大小更容易,因为读者更关注于阅读弧线的长度,而不是面积。圆环图也更节省空间,因为中心被切掉了,所以它可以用来显示信息或进一步将组分成子组。

下图显示了一个基本的圆环图:

Figure 2.23: Donut chart

图 2.23:圆环图

下图显示了包含子组的圆环图:

Figure 2.24: Donut chart with subgroups

图 2.24:包含子组的圆环图

设计实践:

  • 子类别使用相同的颜色(用于类别)。对不同的子类别使用不同的亮度级别。

堆叠条形图

堆叠条形图用于显示一个类别如何划分为子类别,以及子类别相对于整体类别的比例。您可以比较每个条形的总金额,也可以显示每个组的百分比。后者也被称为 100%堆积条形图,可以更容易地看到各组数量之间的相对差异。

用途:

  • 比较可分为子变量的变量。

示例:

下图显示了包含五个组的通用堆积条形图:

Figure 2.25: Stacked bar chart to show sales of laptops and mobiles

图 2.25:显示笔记本电脑和手机销量的堆积条形图

下图显示了 100%堆叠条形图,其数据与上图中使用的数据相同:

Figure 2.26: 100% stacked bar chart to show sales of laptops, PCs, and mobiles

图 2.26: 100%堆叠条形图,显示笔记本电脑、个人电脑和手机的销售情况

下图说明了一家餐馆几天的每日总销售额。不吸烟者的每日总销售额叠加在吸烟者的每日总销售额之上:

Figure 2.27: Daily total sales of restaurant categorized by smokers and non-smokers

图 2.27:按吸烟者和不吸烟者分类的餐馆每日总销售额

设计实践:

  • 对堆叠的条形使用对比色。
  • 确保横条有足够的间距,以消除视觉混乱。每个条形之间的理想间距是条形宽度的一半。
  • 按字母顺序、顺序或值对数据进行分类,以便统一排序,让您的受众更容易理解。

堆叠面积图

堆叠面积图显示了部分-整体关系的趋势。几个组的值相互叠加。它有助于分析个人和整体趋势信息。

用途:

  • 显示作为整体一部分的时间序列趋势。

示例:

下图显示了谷歌、脸书、推特和 Snapchat 等公司过去十年的净利润堆积面积图:

Figure 2.28: Stacked area chart to show net profits of four companies

图 2.28:显示四家公司净利润的堆叠面积图

设计实践:

  • 使用透明颜色可能会提高信息的可见性。

活动 9:智能手机销售单位

您想比较五大智能手机制造商的智能手机销量,看看是否有任何趋势:

  1. 看下面的折线图,分析每个制造商的销售情况,找出与第三季度相比,第四季度表现优异的制造商。
  2. 分析所有厂商的业绩,对销量单位将呈现下降趋势和上升趋势的两家公司进行预测:

图 2.29:智能手机销售单位折线图
注意:

这项活动的解决方案可以在第 275 页找到。

文氏图

文氏图,也称为集合图,显示不同集合的有限集合之间所有可能的逻辑关系。每一组用一个圆来表示。圆圈的大小说明了一个群体的重要性。重叠的大小表示多个组之间的交集。

用途:

  • 要显示不同集合的重叠

:

  • 将下图的交叉点可视化显示了一个学期中选修同一门课的两组学生的维恩图:

Figure 2.30: Venn diagram to show students taking the same class

图 2.30:显示学生上同一堂课的文氏图

设计实践:

  • 如果您有三个以上的组,不建议使用维恩图。这将变得难以理解。

分布图

分布图深入了解数据是如何分布的。对于单个变量,直方图非常适合。对于多个变量,您可以使用方框图或小提琴图。小提琴图可视化了变量的密度,而箱线图仅可视化了每个变量的中位数、四分位数范围和范围。

直方图

一个直方图可视化了单个数值变量的分布。每个小节代表特定时间间隔的频率。直方图有助于估计统计度量。您可以看到值集中的地方,并且可以轻松检测异常值。您可以用绝对频率值绘制直方图,也可以归一化直方图。如果你想比较多个变量的分布,你可以使用不同的颜色。

用途:

  • 深入了解数据集的底层分布

:

下图显示了测试组的智商分布。实线表示平均值,虚线表示标准偏差:

Figure 2.31: Distribution of Intelligence Quotient (IQ) for a test group of a hundred adults

图 2.31:由一百名成年人组成的测试组的智商分布

设计实践:

  • 尝试不同数量的箱,因为直方图的形状可能会有很大的不同。

密度图

一个密度图显示了一个数值变量的分布。它是直方图的变体,使用核平滑,允许更平滑的分布。与直方图相比,它们的一个优点是密度图在确定分布形状方面更好,因为直方图的分布形状在很大程度上取决于面元的数量(数据间隔)。

用途:

  • 您可以通过在同一轴上绘制密度并使用不同的颜色来比较几个变量的分布。

:

下图显示了基本密度图:

Figure 2.32: Density plot

图 2.32:密度图

下图显示了基本的多密度图:

Figure 2.33: Multi-density plot

图 2.33:多密度图

设计实践:

  • 使用对比色绘制多个变量的密度。

箱线图

方框图显示了多个统计测量值。该框从数据的下四分位数延伸到上四分位数,从而允许我们可视化四分位数之间的范围。方框内的水平线表示中间值。从盒子里伸出的显示了数据的范围。它也是一个显示数据异常值的选项,通常是圆形或菱形,超过胡须的末端。

用途:

  • 如果要比较多个变量或组的统计度量,可以简单地将多个框一个接一个地绘制出来。

示例:

下图显示了一个基本的方框图:

Figure 2.34: Box plot showing single variable

图 2.34:显示单变量的箱线图

下图显示了多个变量的基本方框图:

Figure 2.35: Box plot for multiple variables

图 2.35:多个变量的箱线图

小提琴绘图

小提琴图是方块图和密度图的组合。统计测量和分布都是可视化的。中间粗黑条代表四分位数区间,细黑线表示 95%置信区间,白点表示中位数。在中心线的两侧,密度是可视化的。

用途:

  • 如果您想要比较多个变量或组的统计度量,您可以简单地将多个小提琴一个接一个地绘制出来。

示例:

下图显示了单个变量的小提琴图,并显示了学生在数学中的表现:

Figure 2.37: Violin plot for a single variable (Math)

图 2.36:单一变量的小提琴图(数学)

下图显示了两个变量的小提琴图,并显示了学生在英语数学中的表现:

Figure 2.37: Violin plot for multiple variables (English and math)

图 2.37:多个变量(英语和数学)的小提琴图

下图显示了分成三组的单个变量的小提琴图,并显示了三组学生在英语中的表现:

Figure 2.38: Violin plot with multiple categories (three groups of students)

图 2.38:多类别小提琴绘图(三组学生)

设计实践:

  • 相应地缩放轴,使分布清晰可见且不平坦。

活动 10:不同时间间隔的列车频率

为您提供了一个直方图,说明不同时间间隔到达的列车总数:

  1. 通过看下面的图表,你能确定最多列车到达的时间间隔吗?

  2. How would the histogram change if the number of trains arriving between 4 and 6 pm were to be increased by 50?

    Figure 2.39: Frequency of trains during different time intervals

图 2.39:不同时间间隔的列车频率
注意:

这项活动的解决方案可以在第 276 页找到。

地理绘图

地质图是可视化地理空间数据的好方法。Choropleth 地图可用于比较不同国家、州等的定量值。如果你想显示不同位置之间的连接,连接图是必经之路。

点图

点图中,每个点代表一定数量的观察值。每个点都有相同的大小和值(每个点代表的观察次数)。这些点不是用来计数的——它们只是用来给人一种数量级的印象。大小和价值是可视化效果和印象的重要因素。您可以为点使用不同的颜色或符号来显示多个类别或组。

用途:

  • 为了地理空间数据的可视化

:

下图显示了一个点图,其中每个点代表全世界一定数量的公交站点:

Figure 2.40: Dot map showing bus stops worldwide

图 2.40:显示全球公交站点的点地图

设计实践:

  • 不要显示太多位置。您应该仍然能够看到地图,以获得实际位置的感觉。
  • 选择一个点的大小和值,以便在密集的区域,点开始混合。点地图应该给人一个良好的印象,潜在的空间分布。

氯普勒斯地图

弦贴图中,每个图块都被着色以编码一个变量。图块代表地理区域,例如县和国家。Choropleth 地图提供了一个很好的方法来显示一个变量如何在一个地理区域内变化。对于 choropleth 地图,需要记住的一点是,人眼自然会对更大的区域给予更多的关注,因此您可能希望通过按区域划分地图来标准化您的数据。

用途:

  • 用于地理空间数据的可视化,这些地理空间数据按地理区域分组,例如州或国家

:

下图显示了美国天气预报的地图:

Figure 2.41: Choropleth map showing weather forecast of USA

图 2.41:显示美国天气预报的地图

设计实践:

  • 使用较深的颜色表示较高的值,因为它们被认为是较高的量级。
  • 限制颜色的层次,因为人眼只能分辨出多少种颜色。七个色阶应该足够了。

连接图

连接图中,每条线代表两个位置之间的一定数量的连接。位置之间的链接可以用代表它们之间最短距离的直线或圆角来绘制。

每条线都具有相同的厚度和值(每条线代表的连接数)。这些线不是用来计数的;它们只是为了给人一种巨大的印象。连接线的大小和值是可视化效果和印象的重要因素。

您可以为线条使用不同的颜色来显示多个类别或组,也可以使用颜色映射来编码连接的长度。

用途:

  • 为了连接的可视化

示例:

下图显示了世界各地航班连接的连接图:

Figure 2.42: Connection map showing Flight connections around the world

图 2.42:显示全球航班连接的连接图

设计实践:

  • 不要显示太多的连接。您仍然应该查看地图,以了解起点和终点的实际位置。
  • 选择线条粗细和值,以便线条开始在密集区域混合。连接图应该给出底层空间分布的良好印象。

什么是好的可视化?

一个好的可视化有多个方面:

  • 最重要的是,可视化应该是不言自明的,视觉上有吸引力的。为了使其不言自明,请使用图例、x 轴和 y 轴的描述性标签以及标题。
  • 可视化应该讲述一个故事,并且是为你的观众设计的。在创建可视化之前,请考虑您的目标受众—为非专业受众创建简单的可视化,为专业受众创建更详细的技术可视化。想一个故事,用你的形象化来讲述,这样你的形象化会给观众留下印象。

常见设计实践:

  • 颜色比符号更容易被感知。
  • 要在 2D 图上显示其他变量,请使用颜色、形状和大小。
  • 保持简单,不要给可视化带来太多信息。

活动 11:确定理想的可视化

以下可视化效果并不理想,因为它们不能很好地表示数据。为每个可视化回答以下问题:

  1. 这些可视化有哪些不好的方面?
  2. 我们如何改进可视化?为这两种场景绘制正确的可视化草图。

第一张图片是根据用户数量来展示前 30 名优酷:

Figure 2.43: Pie chart showing Top 30 YouTubers

图 2.43:显示前 30 名优酷的饼图

第二个可视化应该说明两天内在赌场玩某个游戏的人数:

图 2.44:显示两天赌场数据的折线图
注意:

这项活动的解决方案可以在第 277 页找到。

总结

本章讨论了最重要的可视化。可视化分为比较、关系、组成、分布和地质图。对于每个绘图,都给出了描述、实例和设计实践。比较图,如折线图、条形图和雷达图,非常适合于比较多个变量或变量随时间的变化。关系图非常适合显示变量之间的关系。散点图、气泡图是散点图、相关图和热图的延伸。如果你把某件事看作整体的一部分,那么构图是理想的。我们首先介绍了饼图,然后继续介绍堆叠条形图、堆叠面积图和文氏图。对于深入了解数据分布情况的分布图,我们考虑了直方图、密度图、箱线图和小提琴图。关于地理空间数据,我们讨论了点地图、连接地图和点地图。最后,对什么是好的可视化给出了一些评论。在下一章中,我们将深入 Matplotlib 并创建我们自己的可视化。我们将涵盖本章中讨论的所有绘图。

三、深入 Matplotlib

学习目标

本章结束时,您将能够:

  • 描述 Matplotlib 的基本原理
  • 使用 Matplotlib 提供的内置绘图创建可视化效果
  • 自定义您的可视化图
  • 用 TeX 写数学表达式

在本章中,我们将学习如何使用 Matplotlib 自定义您的可视化。

简介

Matplotlib 可能是 Python 最流行的绘图库。它用于世界各地的数据科学和机器学习可视化。约翰·亨特从 2003 年开始开发 Matplotlib。它旨在模拟当时科学标准的 MATLAB 软件的命令。MATLAB 的全局风格等几个特性被引入到 Matplotlib 中,使 MATLAB 用户更容易过渡到 Matplotlib。

在我们开始使用 Matplotlib 创建我们的第一个可视化之前,我们将理解并尝试掌握这些绘图背后的概念。

Matplotlib 中的绘图概述

Matplotlib 中的绘图具有层次结构,嵌套 Python 对象以创建树状结构。每个图都封装在一个Figure对象中。这个Figure是可视化的顶层容器。它可以有多个轴,这些轴基本上是这个顶层容器中的独立图。

再深入一层,我们再次发现控制轴、刻度线、图例、标题、文本框、网格和许多其他对象的 Python 对象。所有这些对象都可以自定义。

绘图的两个主要组成部分如下:

  • Figure

    图形是最外层的容器,用作画布来绘制。它允许您在其中绘制多个图。它不仅保存 Axes 对象,还能够配置标题

  • Axes

    轴是实际的绘图或子绘图,这取决于您想要绘制单个还是多个可视化效果。它的子对象包括 x 轴和 y 轴、脊线和图例。

在更高的层次上观察这个设计,我们可以看到这个层次结构允许我们创建一个复杂的和可定制的可视化。

当我们看一个图形的“解剖”时,如下图所示,我们对一个有洞察力的可视化的复杂性有了一个概念。Matplotlib 通过调整网格xy 刻度、刻度标签图例,不仅让我们能够简单地显示数据,还可以围绕数据设计整个图形。这意味着我们可以修改绘图的每一个细节,从标题和图例开始,一直到脊柱上的大刻度和小刻度,以使其更具表现力:

Figure 3.1: Anatomy of a Matplotlib Figure

图 3.1:Matplotlib 图形的解剖

深入研究图形对象的解剖结构,我们可以观察到以下组件:

  • :连接轴刻度线的线
  • 标题:整个图表对象的文字标签
  • 传说:描述绘图内容
  • 网格:用作刻度线延伸的垂直线和水平线
  • X/Y 轴标签:脊柱下方 X/Y 轴的文字标签
  • 次要刻度:主要刻度之间的小数值指示器
  • 次要刻度标签:将在次要刻度处显示的文本标签
  • 主刻度:脊柱上的主数值指示器
  • 主要刻度标签:将在主要刻度处显示的文本标签
  • 线:用线连接数据点的绘图类型
  • 标记:用定义的标记绘制每个数据点的绘图类型

在本书中,我们将重点介绍 Matplotlib 的子模块 pyplot ,它提供了类似 MATLAB 的绘图。

Pyplot 基础知识

pyplot 包含一个更简单的创建可视化的界面,允许用户绘制数据,而无需明确配置图形本身。它们被隐式和自动地配置以实现期望的输出。使用别名plt引用导入的子模块很方便,如下所示:

import matplotlib.pyplot as plt

以下部分描述了使用 pyplot 时执行的一些常见操作。

创造图表

我们用plt.figure()创建一个新的。这个函数返回一个 Figure 实例,但是它也被传递到后端。接下来的每个与图形相关的命令都应用于当前图形,并且不需要知道图形实例。

默认情况下,该图的宽度为 6.4 英寸,高度为 4.8 英寸,dpi 为 100。要更改图的默认值,我们可以使用参数figsizedpi

下面的代码片段显示了我们如何操作一个图形:

plt.figure(figsize=(10, 5)) #To change the width and the height 
plt.figure(dpi=300) #To change the dpi

收盘数字

不再使用的图形应该通过显式调用plt.close()来关闭,这样也可以有效清理内存。

如果未指定任何内容,当前图形将被关闭。要关闭特定的图形,您可以提供对图形实例的引用或提供图形编号。要找到图形对象的编号,我们可以使用number属性,如下所示:

plt.gcf().number

使用plt.close('all'),所有图形将被关闭。以下示例显示了如何创建和关闭图形:

plt.figure(num=10) #Create Figure with Figure number 10
plt.close(10) #Close Figure with Figure number 10

格式化字符串

在我们实际绘制一些东西之前,让我们快速讨论一下格式字符串。它们是指定颜色标记类型线条样式的简洁方式。格式字符串被指定为“[color][marker][line]”,其中每个项目都是可选的。如果color是格式字符串的唯一参数,您可以使用任何matplotlib.colors。Matplotlib 可以识别以下格式:

  • RGB 或 RGBA 浮点元组(例如,(0.2,0.4,0.3)或(0.2,0.4,0.3,0.5))
  • RGB 或 RGBA 十六进制字符串(例如,' #0F0F0F '或' #0F0F0F ')

下图是如何以一种特定格式表示颜色的示例:

Figure 3.2 Color specified in string format

图 3.2 以字符串格式指定的颜色

下图显示了所有可用的标记选项:

Figure 3.3: Markers in format strings

图 3.3:格式字符串中的标记

下图显示了所有可用的线型:

Figure 3.4: Line styles

图 3.4:线条样式

标绘

使用plt.plot([x], y, [fmt]),可以将数据点绘制为线和/或标记。该函数返回表示打印数据的线 2D 对象列表。默认情况下,如果不提供格式字符串,数据点将使用直线和实线连接。plt.plot([0, 1, 2, 3], [2, 4, 6, 8])生成一个图,如下图所示。由于x是可选的,默认值为[0, …, N-1]plt.plot([2, 4, 6, 8])会产生相同的结果:

Figure 3.5: Plotting data points as a line

图 3.5:将数据点绘制成一条线

如果您想要绘制标记而不是线条,您可以指定任何标记类型的格式字符串。例如,plt.plot([0, 1, 2, 3], [2, 4, 6, 8], 'o')将数据点显示为圆形,如下图所示:

图 3.6:用标记(圆圈)绘制数据点

要绘制多个数据对,可以使用语法plt.plot([x], y, [fmt], [x], y2, [fmt2], …)plt.plot([2, 4, 6, 8], 'o', [1, 5, 9, 13], 's')结果如下图。同样,您可以多次使用plt.plot,因为我们使用的是同一个图形和轴:

Figure 3.7: Plotting data points with multiple markers

图 3.7:用多个标记绘制数据点

可以使用任何线 2D 属性代替格式字符串来进一步自定义绘图。例如,下面的代码片段显示了我们如何额外指定linewidthmarkersize:

plt.plot([2, 4, 6, 8], color='blue', marker='o', linestyle='dashed', linewidth=2, markersize=12)

使用熊猫数据帧绘图

使用pandas.DataFrame作为数据源非常简单。您可以不提供 x 和 y 值,而是在数据参数中提供pandas.DataFrame,并给出xy的键,如下所示:

plt.plot('x_key', 'y_key', data=df)

显示图形

plt.show()用于显示一个图形或多个图形。要在 Jupyter 笔记本中显示数字,只需在代码开头设置%matplotlib inline命令。

保存数字

plt.savefig(fname)保存当前图形。您可以指定一些有用的可选参数,如dpiformattransparent。下面的代码片段给出了一个如何保存图形的示例:

plt.figure()
plt.plot([1, 2, 4, 5], [1, 3, 4, 3], '-o')
plt.savefig('lineplot.png', dpi=300, bbox_inches='tight')
#bbox_inches='tight' removes the outer white margins
注意

所有练习和活动都将在 Jupyter 笔记本中开发。请从https://GitHub . com/trainingypbackt/Data-Visualization-with-Python下载带有所有准备好的模板的 GitHub 资源库。

练习 3:创建简单的可视化

在本练习中,我们将使用 Matplotlib 创建第一个简单的图:

  1. Open the Jupyter Notebook exercise03.ipynb from the Lesson03 folder to implement this exercise.

    导航到该文件的路径,并在命令行中键入以下内容:jupyter-lab.

  2. 导入必要的模块,并在 Jupyter 笔记本中进行绘图:

    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    
  3. 显式创建一个图形,并将 dpi 设置为 200:

    plt.figure(dpi=200)
    
  4. Plot the following data pairs (x, y) as circles, which are connected via line segments: (1, 1), (2, 3), (4, 4), (5, 3) . Then, visualize the plot:

    plt.plot([1, 2, 4, 5], [1, 3, 4, 3], '-o')
    plt.show()
    

    您的输出应该如下所示:

    Figure 3.8: A simple visualization that was created with the help given data pairs connected via line segments

    图 3.8:在给定数据对的帮助下创建的简单可视化,并通过线段连接
  5. 使用plt.savefig()方法保存绘图。这里,我们可以在方法中提供一个文件名,或者指定完整的路径:

    plt.savefig(exercise03.png);
    

基本文本和图例功能

我们在本主题中讨论的所有函数,除了图例之外,都创建并返回一个matplotlib.text.Text()实例。我们在这里提到它,以便您知道所有讨论的属性也可以用于其他功能。所有文本功能如图 3.9 所示。

标签

Matplotlib 提供了一些标签功能,我们可以用它们来设置 x 轴和 y 轴的标签。plt.xlabel()plt.ylabel()功能用于设置当前轴的标签。set_xlabel()set_ylabel()功能用于设置指定轴的标签。

示例:

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')

标题

一个标题描述了一个特定的图表。标题位于中心、左边缘或右边缘的轴上方。标题有两个选项–您可以设置图形标题轴的标题suptitle()功能设置当前指定图形的标题。title()功能有助于设置当前轴和指定轴的标题。

示例:

fig = plt.figure()
fig.suptitle('Suptitle', fontsize=10, fontweight='bold')

这将创建一个粗体数字标题,文本标题和字体大小为 10。

文本

对于文本,有两个选项–您可以将文本添加到图形中,也可以将文本添加到轴中。figtext(x, y, text)text(x, y, text)功能在位置xy为图形添加文本。

示例:

ax.text(4, 6, 'Text in Data Coords', bbox={'facecolor': 'yellow', 'alpha':0.5, 'pad':10})

这将创建一个文本为“数据坐标中的文本”的黄色文本框。

标注

与放置在轴上任意位置的文本相比,标注用于标注绘图的某些特征。在标注中,有两个位置需要考虑:标注的位置xy和标注的位置,文本xytext。指定参数arrowprops非常有用,它会产生一个指向标注位置的箭头。

示例:

ax.annotate('Example of Annotate', xy=(4,2), xytext=(8,4), arrowprops=dict(facecolor='green', shrink=0.05))

这将创建一个指向数据坐标(4,2)的绿色箭头,文本“标注示例”位于数据坐标(8,4)处:

Figure 3.9: Implementation of Text Commands

图 3.9:文本命令的实现

传说

为了给你的轴添加一个传说,我们必须在艺术家创作时指定label参数。为当前轴调用plt.legend()或为特定轴调用Axes.legend()将添加图例。loc参数指定图例的位置。

示例:

…
plt.plot([1, 2, 3], label='Label 1')
plt.plot([2, 4, 3], label='Label 2')
plt.legend()
…

下图说明了该示例:

Figure 3.10: Legend example

图 3.10:图例示例

活动 12:使用线图可视化股票趋势

在本活动中,我们将创建一个折线图来显示股票趋势。让我们看看下面的场景:你对投资股票感兴趣。你下载了“五大巨头”:亚马逊、谷歌、苹果、脸书和微软的股价:

  1. 用熊猫读取位于子文件夹data的数据。
  2. 使用 Matplotlib 创建一个折线图,可视化所有五家公司过去五年的收盘价(整个数据序列)。添加标签、标题和图例,使可视化不言自明。使用plt.grid()给你的图添加一个网格。
  3. 执行上述步骤后,预期输出应该如下:

Figure 3.11: Visualization of stock trends of five companies

图 3.11:五家公司股票趋势的可视化
注意:

这项活动的解决方案可以在第 279 页找到。

基本绘图

在这一节中,我们将探讨不同类型的基本绘图。

条形图

plt.bar(x, height, [width])创建竖条图。对于横条,使用plt.barh()功能。

重要参数:

  • x:指定条的 x 坐标
  • height:指定条的高度
  • width(可选):指定所有条的宽度;默认值为 0.8

示例:

plt.bar(['A', 'B', 'C', 'D'], [20, 25, 40, 10]) 

上面的代码创建了一个条形图,如下图所示:

Figure 3.12: A simple bar chart

图 3.12:一个简单的条形图

如果你想有子类别,你必须多次使用plt.bar()功能,移动 x 坐标。这在下面的示例中完成,并在下面的图表中说明。arange()函数是 NumPy 包中的一种方法,在给定的时间间隔内返回均匀间隔的值。gca()功能有助于获取任何当前图形上的当前轴的实例。set_xticklabels()功能用于设置带有给定字符串标签列表的 x 刻度标签。

示例:

…
labels = ['A', 'B', 'C', 'D']
x = np.arange(len(labels))
width = 0.4
plt.bar(x – width / 2, [20, 25, 40, 10], width=width)
plt.bar(x – width / 2, [30, 15, 30, 20], width=width)
# Ticks and tick labels must be set manually
plt.ticks(x)
ax = plt.gca()	
ax.set_xticklabels(labels)
…

上面的代码创建了一个带有子类别的条形图,如下图所示:

Figure 3.13: Bar chart with subcategories

图 3.13:带有子类别的条形图

活动 13:创建用于电影比较的条形图

在本活动中,我们将使用条形图来比较电影分数。给你五部烂番茄评分的电影。Tomatometer 是对电影给予正面评价的认可 Tomatometer 影评人的百分比。受众分数是 5 分中给出 3.5 分或更高分数的用户的百分比。在五部电影中比较这两个分数:

  1. 使用 pandas 读取位于子文件夹数据中的数据。
  2. 使用 Matplotlib 创建一个视觉上吸引人的条形图,比较所有五部电影的两个分数。
  3. 使用电影标题作为 x 轴的标签。对 y 轴刻度使用 20 的间隔百分比,对 5 的间隔使用次要刻度。给绘图加上一个图例和合适的标题。
  4. 执行上述步骤后,预期输出应该如下:

Figure 3.14: Bar plot comparing scores of five movies

图 3.14:对比五部电影评分的条形图
注意:

这项活动的解决方案可以在第 280 页找到。

饼图

plt.pie(x, [explode], [labels], [autopct])函数创建一个饼图。

重要参数:

  • x:指定切片大小。
  • explode(可选):指定每个切片的半径偏移分数。分解数组的长度必须与 x 数组相同。
  • labels(可选):指定每个切片的标签。
  • autopct(可选):根据指定的格式字符串显示切片内的百分比。示例:“%1.1f%%”。

示例:

…
plt.pie([0.4, 0.3, 0.2, 0.1], explode=(0.1, 0, 0, 0), labels=['A', 'B', 'C', 'D'])
…

下图显示了上述代码的结果:

Figure 3.15: Basic pie chart

图 3.15:基本饼图

练习 4:创建用水量饼图

在本练习中,我们将使用饼图来可视化用水量:

  1. Open the Jupyter Notebook exercise04.ipynb from the Lesson03 folder to implement this exercise.

    导航到该文件的路径,并在命令行中键入以下内容:jupyter-lab.

  2. 导入必要的模块,并在 Jupyter 笔记本中进行绘图:

    # Import statements
    import pandas as pd
    import matplotlib.pyplot as plt
    %matplotlib inline
    
  3. 用熊猫读取位于子文件夹数据中的数据:

    # Load dataset
    data = pd.read_csv('./data/water_usage.csv')
    
  4. 使用饼图来可视化用水量。使用分解参数突出显示您选择的一种用法。显示每个切片的百分比,并添加标题:

    # Create figure
    plt.figure(figsize=(8, 8), dpi=300)
    # Create pie plot
    plt.pie('Percentage', explode=(0, 0, 0.1, 0, 0, 0), labels='Usage', data=data, autopct='%.0f%%')
    # Add title
    plt.title('Water usage')
    # Show plot
    plt.show()
    

下图显示了前面代码的输出:

Figure 3.16: Pie chart for water usage

图 3.16:用水量饼图

堆叠条形图

一个堆叠条形图使用与条形图相同的plt.bar功能。对于每个堆叠条形图,必须调用plt.bar函数,并且必须从第二个堆叠条形图开始指定bottom参数。通过下面的例子,这一点将变得很清楚:

…
plt.bar(x, bars1)
plt.bar(x, bars2, bottom=bars1)
plt.bar(x, bars3, bottom=np.add(bars1, bars2))
…

下图显示了上述代码的结果:

Figure 3.17: Stacked bar chart

图 3.17:堆叠条形图

活动 14:创建堆叠条形图以可视化餐厅表现

在本活动中,我们将使用堆叠条形图来可视化餐厅的表现。让我们看看下面的场景:你是一家餐馆的老板,由于一项新的法律,你必须引入一个禁烟日。为了尽可能减少损失,您需要想象每天有多少销售额,按吸烟者和不吸烟者分类:

  1. 使用给定的数据集并创建一个矩阵,其中的元素包含每天的总账单和吸烟者/不吸烟者的账单。

  2. 创建一个堆积条形图,将吸烟者和非吸烟者每天的总账单堆积在一起。添加图例、标签和标题。

  3. After executing the preceding steps, the expected output should be as follows:

    Figure 3.18: Stacked bar chart showing performance of restaurant on different days

图 3.18:显示餐厅不同日子表现的堆叠条形图
注意:

这项活动的解决方案可以在第 282 页找到。

堆叠面积图

plt.stackplot(x, y)创建堆叠面积图。

重要参数:

  • x:指定数据系列的 x 值。
  • y:指定数据系列的 y 值。对于多个系列,无论是 2d 阵列,还是任意数量的 1D 阵列,调用以下函数:plt.stackplot(x, y1, y2, y3, …).
  • labels(可选):将标签指定为每个数据系列的列表或元组。

示例:

…
plt.stackplot([1, 2, 3, 4], [2, 4, 5, 8], [1, 5, 4, 2])
…

下图显示了上述代码的结果:

Figure 3.19: Stacked area chart

图 3.19:堆叠面积图

活动 15:使用堆叠面积图比较智能手机销量

在本活动中,我们将使用堆叠面积图来比较智能手机的销售单位。让我们看看下面的场景:你想投资五大智能手机制造商之一。将季度销售单位视为整体的一部分可能是投资哪家公司的好指标:

  1. 使用 pandas 读取位于子文件夹数据中的数据。
  2. 创建一个视觉上吸引人的堆叠面积图。添加图例、标签和标题。
  3. 执行上述步骤后,预期输出应该如下:

Figure 3.20: Stacked area chart comparing sales units of different smartphone manufacturers

图 3.20:不同智能手机厂商销量对比的堆叠面积图
注意:

这项活动的解决方案可以在第 283 页找到。

直方图

plt.hist(x)创建直方图。

重要参数:

  • x:指定输入值
  • bins:(可选):将面元数指定为整数,或将面元边指定为列表
  • range:(可选):以元组的形式指定容器的下限和上限
  • density:(可选):如果为真,直方图表示概率密度

示例:

…
plt.hist(x, bins=30, density=True)
…

下图显示了上述代码的结果:

Figure 3.21: Histogram

图 3.21:直方图

plt.hist2d(x, y)创建 2D 直方图。下图显示了 2D 历史图的一个示例:

Figure 3.22: 2D histogram with color bar

图 3.22:带颜色条的 2D 直方图

箱线图

plt.boxplot(x)创建方框图。

重要参数:

  • x:指定输入数据。它为单个框指定一个 1D 数组,或者为多个框指定一系列数组。
  • notch:可选:如果为真,将在图中添加凹口,以指示中位数周围的置信区间。
  • labels:可选:将标签指定为序列。
  • showfliers:可选:默认为真,超出上限绘制异常值。
  • showmeans:可选:如果为真,则显示算术平均值。

示例:

…
plt.boxplot([x1, x2], labels=['A', 'B'])
…

下图显示了上述代码的结果:

Figure 3.23: Box plot

图 3.23:方框图

活动 16:使用直方图和箱线图来可视化智商

在本练习中,我们将使用直方图和方框图来可视化智商。

注意

plt.axvline(x, [color=…], [linestyle=…])x位置画一条垂直线。

  1. 为给定的智商分数绘制一个包含 10 个面元的直方图。智商分数呈正态分布,平均值为 100,标准差为 15。将平均值可视化为垂直的红色实线,用垂直虚线表示标准偏差。添加标签和标题。

  2. 创建一个方框图来可视化相同的智商分数。添加标签和标题。

  3. 为不同测试组的每个智商分数创建一个方框图。添加标签和标题。

  4. The expected output for step 1 is as follows:

    Figure 3.24: Histogram for IQ test

    图 3.24:智商测试直方图
  5. The expected output for step 2 is as follows:

    Figure 3.25: Box plot for IQ scores

    图 3.25:智商分数的方框图
  6. The expected output for step 3 is as follows:

    Figure 3.26: Box plot for IQ scores of different test groups

图 3.26:不同测试组智商分数的箱线图
注意:

这项活动的解决方案可以在第 284 页找到。

散点图

plt.scatter(x, y)创建 y 对 x 的散点图,可选地改变标记大小和/或颜色。

重要参数:

  • xy:指定数据位置。
  • s:可选:以点的平方指定标记大小。
  • c:可选:指定标记颜色。如果指定了数字序列,这些数字将被映射到颜色映射的颜色。

示例:

…
plt.scatter(x, y)
…

下图显示了上述代码的结果:

Figure 3.27: Scatter plot

图 3.27:散点图

活动 17:使用散点图来可视化各种动物之间的相关性

在本练习中,我们将使用散点图来显示数据集中的相关性。让我们看看下面的场景:给你一个包含各种动物信息的数据集。可视化各种动物属性之间的相关性:

注意

Axes.set_xscale('log')Axes.set_yscale('log')分别将 x 轴和 y 轴的刻度改为对数刻度。

  1. 给定的数据集不完整。过滤数据,这样你最终得到的样本就包含了一个体重和最长寿命。根据动物种类对数据进行分类。
  2. 创建散点图,可视化体重和最大寿命之间的相关性。根据数据样本的类别,使用不同的颜色对数据样本进行分组。添加图例、标签和标题。x 轴和 y 轴都使用对数刻度。
  3. 执行上述步骤后,预期输出应该如下:

Figure 3.28: Scatter plot on animal statistics

图 3.28:动物统计的散点图
注意:

这项活动的解决方案可以在第 287 页找到。

气泡图

plt.scatter功能用于创建气泡图。要可视化第三个或第四个变量,可以使用参数s(比例)和c(颜色)。

示例:

…
plt.scatter(x, y, s=z*500, c=c, alpha=0.5)
plt.colorbar()
…

下图显示了上述代码的结果:

Figure 3.29: Bubble plot with color bar

图 3.29:带颜色条的气泡图

布局

在 Matplotlib 中定义可视化布局有多种方法。我们将从子图开始,以及如何使用紧凑布局来创建视觉上吸引人的绘图,然后覆盖 GridSpec ,这为创建多绘图提供了更灵活的方式。

子图

并排显示几个图通常很有用。Matplotlib 提供了子绘图的概念,子绘图是一个图形中的多个轴。这些图可以是网格图、嵌套图等。

探索以下选项来创建子绘图:

  • plt.subplots(nrows, ncols)创建一个图表和一组子图。
  • plt.subplot(nrows, ncols, index)或等效的plt.subplot(pos)给当前图形增加一个子图。指数从 1 开始。plt.subplot(2, 2, 1)相当于plt.subplot(221)
  • Figure.subplots(nrows, ncols)向指定的图形添加一组子绘图。
  • Figure.add_subplot(nrows, ncols, index)或等效的Figure.add_subplot(pos)给指定的图形添加一个子图。

要共享 x 轴或 y 轴,必须分别设置参数sharexsharey。该轴将具有相同的限制、刻度和比例。

plt.subplotFigure.add_subplot可以选择设置投影。对于极坐标投影,设置projection='polar'参数或设置parameter polar=True参数。

例 1:

…
fig, axes = plt.subplots(2, 2)
axes = axes.ravel()
for i, ax in enumerate(axes):
    ax.plot(series[i])
…
…
for i in range(4):
    plt.subplot(2, 2, i+1)
    plt.plot(series[i])
…

两个示例产生相同的结果,如下图所示:

Figure 3.30: Subplots

图 3.30:子图

例 2:

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
axes = axes.ravel()
for i, ax in enumerate(axes):
    ax.plot(series[i])

sharexsharey设置为真,结果如下图所示。这样可以进行更好的比较:

Figure 3.31: Subplots with a shared x and y axis

图 3.31:共享 x 轴和 y 轴的子绘图

紧凑布局

plt.tight_layout()调整子图参数,使子图在图中很好的契合。

示例:

如果不使用plt.tight_layout(),子图可能会重叠:

…
fig, axes = plt.subplots(2, 2)
axes = axes.ravel()
for i, ax in enumerate(axes):
    ax.plot(series[i])
    ax.set_title('Subplot ' + str(i))
…

下图显示了上述代码的结果:

Figure 3.32: Subplots with no layout option

图 3.32:没有布局选项的子图

使用plt.tight_layout()不会导致子绘图重叠:

…
fig, axes = plt.subplots(2, 2)
axes = axes.ravel()
for i, ax in enumerate(axes):
    ax.plot(series[i])
    ax.set_title('Subplot ' + str(i))
plt.tight_layout()
…

下图显示了上述代码的结果:

Figure 3.33: Subplots with a tight layout

图 3.33:布局紧凑的子图

雷达图

雷达图,也称为蜘蛛网络图,可视化多个变量,每个变量绘制在自己的轴上,形成一个多边形。所有轴都是径向排列的,从中心开始,彼此之间的距离相等,并且具有相同的刻度。

练习 5:绘制雷达图

在本练习中,将逐步展示如何创建雷达图:

  1. Open the Jupyter Notebook exercise05.ipynb from the Lesson03 folder to implement this exercise.

    导航到该文件的路径,并在命令行中键入以下内容:jupyter-lab.

  2. 导入必要的模块,并在 Jupyter 笔记本中进行绘图:

    # Import settings
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    %matplotlib inline
    
  3. 以下数据集包含四名员工的五种不同属性的评分:

    # Sample data
    # Attributes: Efficiency, Quality, Commitment, Responsible Conduct, Cooperation
    data = pd.DataFrame({
        'Employee': ['A', 'B', 'C', 'D'],
        'Efficiency': [5, 4, 4, 3,],
        'Quality': [5, 5, 3, 3],
        'Commitment': [5, 4, 4, 4],
        'Responsible Conduct': [4, 4, 4, 3],
        'Cooperation': [4, 3, 4, 5]
    })
    
  4. 创建角度值并关闭绘图:

    attributes = list(data.columns[1:])
    values = list(data.values[:, 1:])
    employees = list(data.values[:, 0])
    angles = [n / float(len(attributes)) * 2 * np.pi for n in range(len(attributes))]
    # Close the plot
    angles += angles[:1]
    values = np.asarray(values)
    values = np.concatenate([values, values[:, 0:1]], axis=1)
    
  5. 用极坐标投影创建子图。设置一个紧凑的布局,这样就不会有任何重叠:

    # Create figure
    plt.figure(figsize=(8, 8), dpi=150)
    # Create subplots
    for i in range(4):
        ax = plt.subplot(2, 2, i + 1, polar=True)
        ax.plot(angles, values[i])
        ax.set_yticks([1, 2, 3, 4, 5])
        ax.set_xticks(angles)
        ax.set_xticklabels(attributes)
        ax.set_title(employees[i], fontsize=14, color='r')
    # Set tight layout
    plt.tight_layout()
    # Show plot
    plt.show()
    

下图显示了前面代码的输出:

Figure 3.34: Radar charts

图 3.34:雷达图

格思特

matplotlib.gridspec.GridSpec(nrows, ncols)指定将放置子图的网格的几何形状。

示例:

…
gs = matplotlib.gridspec.GridSpec(3, 4)
ax1 = plt.subplot(gs[:3, :3])
ax2 = plt.subplot(gs[0, 3])
ax3 = plt.subplot(gs[1, 3])
ax4 = plt.subplot(gs[2, 3])
ax1.plot(series[0])
ax2.plot(series[1])
ax3.plot(series[2])
ax4.plot(series[3])
plt.tight_layout()
…

下图显示了上述代码的结果:

图 3.35: GridSpec

活动 18:创建带有边缘直方图的散点图

在本练习中,我们将使用 GridSpec 可视化带有边缘直方图散点图:

  1. 在之前的活动中已经使用过的给定数据集AnAge不完整。过滤数据,这样你最终得到的样本就包含了一个体重和最长寿命。选择所有体重小于 20,000 的 Aves 类样品。
  2. 创建具有受约束布局的图形。创建一个 4x4 大小的 gridspec。创建大小为 3x3 的散点图和大小为 1x3 和 3x1 的边缘直方图。添加标签和图形标题。
  3. 执行上述步骤后,预期输出应该如下:

图 3.36:带有边缘直方图的散点图
注意:

这项活动的解决方案可以在第 289 页找到。

图像

如果您想在可视化中包含图像,或者您正在处理图像数据,Matplotlib 提供了几个处理图像的功能。在本节中,我们将向您展示如何使用 Matplotlib加载保存绘制图像。

注意

本主题中使用的图像来自unsplash.com/

基本图像操作

以下是用于设计图像的基本操作:

加载图像

如果您遇到 Matplotlib 不支持的图像格式,我们建议使用枕头库加载图像。在 Matplotlib 中,加载图像是图像子模块的一部分。我们使用别名mpimg作为子模块,如下所示:

import matplotlib.image as mpimg

mpimg.imread(fname)读取图像并将其作为numpy.array返回。对于灰度图像,返回的数组有一个形状(高度,宽度),对于 RGB 图像(高度,宽度,3),对于 RGBA 图像(高度,宽度,4)。数组值的范围从 0 到 255。

保存图像

mpimg.imsave(fname, array)numpy.array保存为图像文件。如果没有给出format参数,格式是从文件扩展名推导出来的。通过可选参数vminvmax,可以手动设置颜色限制。对于灰度图像,可选参数cmap的默认值为'viridis';你可能想把它改成'gray'

绘制单个图像

plt.imshow(img)显示图像并返回AxesImage。对于具有形状(高度、宽度)的灰度图像,图像阵列使用颜色图进行可视化。默认的颜色图是'viridis',如图 3.38 所示。为了实际可视化灰度图像,颜色图必须设置为'gray',即plt.imshow(img, cmap='gray'),如下图所示。灰度、RGB 和 RGBA 图像的值可以是floatuint8,范围分别为[0…1][0…255]。要手动定义数值范围,必须指定参数vminvmax。下图显示了 RGB 图像的可视化效果:

Figure 3.37: Grayscale image with default viridis colormap

图 3.37:默认维里迪斯色图的灰度图像

下图显示了带有灰色色图的灰度图像:

Figure 3.38: Grayscale image with gray colormap

图 3.38:带有灰色色图的灰度图像

下图显示了一幅 RGB 图像:

Figure 3.39: RGB image

图 3.39: RGB 图像

有时,深入了解颜色值可能会有所帮助。我们可以简单地在图像图中添加一个颜色条。建议使用高对比度的色彩图,例如,'jet':

…
plt.imshow(img, cmap='jet')
plt.colorbar()
…

下图说明了前面的示例:

Figure 3.40: Image with jet colormap and color bar

图 3.40:带有喷射色图和颜色条的图像

深入了解图像值的另一种方法是绘制直方图,如下图所示。要绘制图像阵列的直方图,必须使用numpy.ravel展平阵列:

…
plt.hist(img.ravel(), bins=256, range=(0, 1))
…

下图显示了前面代码的输出:

Figure 3.41: Histogram of image values

图 3.41:图像值直方图

在网格中绘制多个图像

为了在一个网格中绘制多个图像,我们可以简单地使用plt.subplots并根据轴绘制一个图像:

…
fig, axes = plt.subplots(1, 2)
for i in range(2):
    axes[i].imshow(imgs[i])
…

下图显示了上述代码的结果:

图 3.42:网格中的多个图像

在某些情况下,去掉记号并添加标签是很好的。axes.set_xticks([])axes.set_yticks([])分别去除 x 记号和 y 记号。axes.set_xlabel('label')增加了一个标签:

…
fig, axes = plt.subplots(1, 2)
labels = ['coast', 'beach']
for i in range(2):
    axes[i].imshow(imgs[i])
    axes[i].set_xticks([])
    axes[i].set_yticks([])
    axes[i].set_xlabel(labels[i])
…

下图显示了上述代码的结果:

Figure 3.43: Multiple images with labels

图 3.43:带有标签的多个图像

活动 19:在网格中绘制多个图像

在本练习中,我们将在网格中绘制图像:

  1. 从子文件夹数据加载所有四个图像。
  2. 在 2x2 网格中可视化图像。移除轴并给每个图像一个标签。
  3. 执行上述步骤后,预期输出应该如下:

图 3.44:在 2x2 网格中可视化图像
注意:

这项活动的解决方案可以在第 290 页找到。

写数学表达式

如果需要在代码内编写数学表达式,Matplotlib 支持 TeX 。你可以把你的数学表达式放在一对美元符号中,在任何文本中使用它。没有必要安装 TeX,因为 Matplotlib 自带解析器。

下面的代码给出了一个例子:

…
plt.xlabel('$x$')
plt.ylabel('$\cos(x)$')
…

下图显示了前面代码的输出:

图 3.45:演示数学表达式的图

TeX 示例:

  • '$\alpha_i>\beta_i$'生产
  • '$\sum_{i=0}^\infty x_i$'生产
  • '$\sqrt[3]{8}$'生产
  • '$\frac{3 - \frac{x}{2}}{5}$'生产

总结

在本章中,我们详细介绍了 Matplotlib,这是 Python 最流行的可视化库之一。我们从 pyplot 及其操作的基础开始,然后深入了解有助于丰富文本可视化的众多可能性。本章通过实例介绍了 Matplotlib 提供的最流行的绘图功能,包括比较图、合成图和分布图。这一章以如何形象化图像和写数学表达式为结尾。

在下一章中,我们将了解 Seaborn 图书馆。Seaborn 建立在 Matplotlib 的基础上,提供了更高级别的抽象,使视觉上吸引人的可视化。我们还将讨论高级可视化类型。