Py学习  »  Python

太酷了!又一个Python数据可视化神器

CDA数据分析师 • 1 年前 • 199 次点击  

作者:云朵君 本文转自公众号:数据STUDIO 

本文重点和大家一起学习可视化库 plotnine,因为它是最成熟的一个。plotnine 是基于 R 编程语言中的 ggplot2[1],所以如果我们有 R 的背景,那么我们可以把 plotnine 视为 Python 中 ggplot2 的等价物。

plotnine 绘图

本文中我们将一起学习:

  • 结合图形语法的不同元素
  • 使用 plotnine创建可视化高效又一致
  • 将数据可视化导出到文件

设置环境

这里我们将一起学习如何设置我们的环境。

  1. 创建一个虚拟环境
  2. 安装plotnine
  3. 安装Juptyer笔记本

虚拟环境使我们能够在隔离的环境中安装软件包。当我们想尝试一些软件包或项目,而又不想搞乱已配置好的系统安装时,这是非常有用的。

运行以下命令,创建一个名为data-visualization的目录,并在其中创建一个虚拟环境。

$ mkdir data-visualization
$ cd data-visualization
$ python3 -m venv venv

运行上述命令后,会在 data-visualization 目录中找到我们的虚拟环境。运行下面的命令来激活虚拟环境并开始使用它。

$ source ./venv/bin/activate

当我们激活一个虚拟环境时,安装的任何软件包都将被安装在环境内,而不影响原有系统范围的安装。

接下来,使用 pip 包在虚拟环境中安装 plotnine。通过运行此命令安装 plotnine

$ python -m pip install plotnine

最后,安装 Jupyter Notebook。虽然这不是使用 plotnine 的严格必要条件,但 Jupyter Notebook 在处理数据和建立可视化时超级有用。

要安装Jupyter笔记本,使用以下命令。

$ python -m pip install jupyter

现在有了一个安装了 plotnine 和 Jupyter 笔记本的虚拟环境!有了这个设置,接下来就可以继续本文的学习了。

其实还有另一种创建虚拟环境的方法,如果你已经安装了anaconda,用它来创建虚拟环境,也不失为一种好的方法,由于该方法我们之前已经介绍了,此处不做过多介绍,

建立第一个图表

在本节中,我们将学习如何在Python中使用ggplot建立我们的第一个数据可视化。我们还将学习如何检查和使用 plotnine 附带的示例数据集。

当我们熟悉 plotnine 了功能时,这些例子数据集确实很方便。每个数据集都是以 pandas DataFrame 的形式提供的,它是一种用来保存数据的二维的表格数据结构。

我们将使用下列数据集做演示。可以在plotnine参考资料[2]中找到完整的示例数据集列表。

  • **economics**:美国经济数据的时间序列
  • **mpg**:一系列车辆的燃油经济性数据
  • **Huron**:休伦湖在1875年至1972年间的水位。

我们可以使用Jupyter笔记本来检查任何数据集。用以下命令启动 Jupyter 笔记本。

$ source ./venv/bin/activate
$ jupyter-notebook

然后,一旦进入Jupyter笔记本,运行下面的代码就可以看到经济学数据集中的原始数据。

from plotnine.data import economics
economics

该代码从 plotnine.data 导入经济学数据集,并在一个表格中显示。

      date      pce      pop   psavert uempmed  unemploy
0 1967-07-01 507.4 198712 12.5 4.5 2944
1 1967-08-01 510.5 198911 12.5 4.7 2945
... ... ... ... ... ... ...
572 2015-03-01 12161.5 320707 5.2 12.2 8575
573 2015-04-01 12158.9 320887 5.6 11.7 8549

如表所示,该数据集包括1967年至2015年间每个月的经济信息。每一行都有以下字段。

  • date:收集数据的月份
  • pce:个人消费支出(以十亿美元计)
  • pop:总人口(以千计)
  • psavert:个人储蓄率
  • uempmed:失业时间的中位数(以周计)
  • unemploy:失业人数(以千计)

现在,使用plotnine,我们可以创建一个图来显示人口历年的演变。




    
from plotnine.data import economics
from plotnine import ggplot, aes, geom_line

(
    ggplot(economics)  # 使用什么数据?
    + aes(x="date", y="pop")  # 使用什么变量
    + geom_line()  # 用来绘图的几何对象
)

该代码例子从economics数据集中创建了一个图。

  1. 第1行 导入的是经济学数据集。
  2. 第2行 导入了 ggplot() 类,以及plotnine的一些有用的函数:aes() 和geom_line()
  3. 第5行 使用 ggplot() 创建一个绘图对象,并将DataFrame传递给构造函数。
  4. 第6行 添加 aes() 来设置每个轴使用的变量,在这里是 date 和 pop
  5. 第7行 添加了geom_line()来指定图表应该被绘制成线形图。

运行上述代码产生的输出结果如下。

一个显示种群随时间演变的图

这里使用图形语法时需要指定的三个必要的组件。

  1. 想要绘制的数据
  2. 每个轴上要使用的变量
  3. 绘图时使用的几何对象

注意到,不同的组件是用 + 运算符组合的。

在下面的章节中,我们将更深入地了解图形语法以及如何使用 plotnine 创建数据可视化。

了解图形语法

我们可以在文档中查阅很多有用的信息:

https://plotnine.readthedocs.io/en/stable/index.html

图形语法是一种高级工具,它描述图形的组成部分,将在画布上实际绘制像素的低层次细节中抽象出来。

称之为语法,是因为它定义了组件和规则,该规则定义了如何组合组件以创建图形,就像语言语法定义了如何组合单词和标点符号以形成句子。

有许多不同的图形语法,它们在使用的组件和规则方面都有所不同。plotnine实现的图形语法是基于R编程语言中的ggplot2。这种特定的语法在Hadley Wickham的论文 ["A Layered Grammar of Graphics "](http://vita.had.co.nz/papers/layered-grammar.pdf ""A Layered Grammar of Graphics "")中提出。

下面,我们将了解 plotnine 的图形语法的主要组成部分和规则,以及如何使用它们来创建数据可视化。首先,回顾一下创建绘图的三个必要组成部分

  1. 数据 是在创建绘图时要使用的信息。
  2. Aesthetics (aes) 提供了数据变量和底层绘图系统使用的aesthetic,或图形变量之间的映射。在上一节中,我们将日期和人口的数据变量映射到X轴和Y轴的aesthetic变量。
  3. 几何对象 (geoms 定义了绘图中使用的几何对象的类型。可以使用点、线、条和许多其他东西。

如果没有这三个组成部分中的任何一个,plotnine就不知道如何绘制图形。

接下来了解可以使用的可选组件

  • 统计转换指定了在绘制数据之前对其进行的计算和汇总。
  • 在从dataaes的映射过程中,轴刻度应用了一些转换。例如,可以使用一个对数log刻度来更好地反映数据的某些方面。
  • Facets 根据一些属性将数据分为几组,然后在同一个图形中把每组绘制成一个单独的面板。
  • 坐标系统将对象的位置映射到图中的二维图形位置。例如,我们可以选择翻转纵轴和横轴,如果这在我们建立的可视化中更有意义。
  • 主题允许我们控制视觉属性,如颜色、字体和形状。

上面概括性地介绍了绘图所需要用的组件,有个简单直观印象,接下来我们将逐个学习。

绘制数据图

在本节中,我们将了解更多关于使用 plotnine 创建数据可视化的三个必要组件。

  1. Data
  2. Aesthetics
  3. Geometric objects

我们还会看到它们是如何被组合起来,从数据集中创建一个图。

Data -- 信息的来源

当创建一个数据可视化时,第一步是指定要绘制的数据。在plotnine中,可以通过创建一个ggplot对象并将我们想使用的数据集传递给构造函数来完成。

下面的代码使用plotnine的燃油经济性示例数据集mpg创建了一个ggplot对象。

from plotnine.data import mpg
from plotnine import ggplot

ggplot(mpg)

这段代码使用mpg数据集创建了一个属于ggplot类的对象。注意,由于我们还没有指定aesgeoms,上面的代码将生成一个空白的画布。接下来,我们将一块一块地构建这个绘图。

导入并检查数据集

from plotnine.data import mpg
mpg

这两行代码导入并显示了数据集,显示了以下输出。

  manufacturer  model  displ  year  cyl  trans      drv  cty  hwy  fl  class
0 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
1 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
2 audi a4 2.0 2008 4 manual(m6) f 20 31 p compact
...

输出是一个包含1999年至2008年234辆汽车的油耗数据的表格。排量( displ )字段是发动机的大小,单位是升。cty 和 hwy 是城市和公路驾驶的燃油经济性,单位是英里/加仑。

下面我们将学习使用 plotnine 将这些原始数据变成图形的步骤。

Aesthetics -- 为每个轴定义变量

在指定了可视化的数据后,下一步是定义在绘图中的每个轴上使用的变量。DataFrame 中的每一行都可以包含许多字段,所以我们必须告诉 plotnine 我们想在图形中使用哪些变量。

Aes将数据变量映射为图形属性,如2D位置和颜色。例如,下面的代码创建了一个图形,在X轴上显示车辆类别,在Y轴上显示公路油耗。

from plotnine.data import mpg
from plotnine import ggplot, aes

ggplot(mpg) + aes(x="class", y="hwy")

以上一节中的ggplot对象作为可视化的基础,将车辆类别属性映射到水平图轴上,将hwy燃油经济性映射到垂直轴上。

到这里,生成的图仍然是空白的,因为它缺少代表每个数据元素的几何对象。

Geoms -- 选择不同的图类型

在定义了数据和图形中使用的属性后,我们需要指定一个几何对象来告诉 plotnine 如何绘制数据点。

plotnine 提供了很多几何对象,均可以开箱即用,比如线、点、条、多边形等等。所有可用的几何对象的列表可在 plotnine 的 geoms API 参考[3]中找到。

下面的代码说明了如何使用点的几何对象来绘制数据。

from plotnine.data import mpg
from plotnine import ggplot, aes, geom_point

ggplot(mpg) + aes(x="class", y="hwy") + geom_point()

在上面的代码中,geom_point() 选择了点的几何对象。运行该代码会产生以下输出。

如图所示,生成的数据可视化对数据集中的每辆车都有一个点。轴显示了车辆类别和公路燃油经济性。

还有许多其他的几何对象,可以用它们来可视化同样的数据集。例如,下面的代码使用条形几何对象来显示每个类别的车辆数量。




    
from plotnine.data import mpg
from plotnine import ggplot, aes, geom_bar

ggplot(mpg) + aes(x="class") + geom_bar()

这里,geom_bar() 将几何对象设置为bar。由于代码中没有为Y轴指定任何属性,geom_bar() 隐含地将数据点按X轴所用的属性分组,然后将每组中的点的数量用于Y轴。

运行该代码,我们会看到以下输出。

图中每个条形的高度代表属于相应车辆类别的车辆数量。我们将在后面的章节中了解更多关于数据聚合和分组的信息。

接下来我们将了解到一些可选的组件,可以用来创建更复杂和漂亮的图形。

加强数据可视化

在本节中,我们将了解到在用 plotnine 构建数据可视化时可以使用的可选组件。这些组件可以分为五类。可以用它们来创建更丰富、更美丽的图表。

  1. Statistical transformations 统计转换
  2. Scales 刻度
  3. Coordinates systems 坐标轴系统
  4. Facets 分面
  5. Themes 主体

统计转换 -- 汇总和转换数据

统计转换在绘制数据之前对其进行一些计算,例如,显示一些统计指标而不是原始数据。

柱状图

假设创建一个柱状图来显示 Lake Huron 从1875年到1975年的水位分布情况。导入并检查数据集。




    
#导入休伦湖1875-1975年水位的示例数据集
from plotnine.data import huron
huron

该代码导入并显示了数据集。

    year  level   decade
0 1875 580.38 1870
1 1876 581.86 1870
...
96 1971 579.89 1970
97 1972 579.96 1970

正如我们所看到的,该数据集包含三列。

  1. year
  2. level
  3. decade

现在可以分两步建立直方图。

  1. 将水位测量值分组到bins中。
  2. 用柱状图显示每个bin的测量数量。

代码

from plotnine.data import huron
from plotnine import ggplot, aes, stat_bin, geom_bar

ggplot(huron) + aes(x="level") + stat_bin(bins=10) + geom_bar()

在上面的代码中,stat_bin() 将水平范围划分为十个大小相等的bin。然后用条形图画出落入每个仓的测量值的数量。

这张图显示了每个湖泊水位范围的测量次数。大部分时间的水位都在578和580之间。

对于大多数常见的任务,如构建直方图,plotnine 中的函数非常方便,代码很简洁。例如,使用 geom_histogram()建立上述直方图。

from plotnine.data import huron
from plotnine import ggplot, aes, geom_histogram

ggplot(Huron) + aes(x="level") + geom_histogram(bins=10)

使用 geom_histogram() 与使用 stats_bin() 然后 geom_bar() 是一样的。运行这段代码会生成上面相同图形。

箱形图

现在看看统计转换的另一个例子。箱形图是一个非常流行的统计工具,用于显示数据集的最小值、最大值、中位数、第一和第三四分位数以及离群值

假设在同一个数据集上建立一个可视化,以显示每个十年的水平测量的箱形图。我们可以分两步建立这个图。

  1. 按年代对测量结果进行分组。
  2. 为每组创建一个箱形图。

可以使用美学规范中的 factor() 来完成。 factor() 将所有对指定属性有相同值的数据点组合在一起。

然后把数据按年代分组就可以用 geom_boxplot() 为每组数据画一个箱形图。

下面的代码使用上述步骤创建了一个绘图。




    
from plotnine.data import huron
from plotnine import ggplot, aes, geom_boxplot

(
  ggplot(huron)
  + aes(x="factor(decade)", y="level")
  + geom_boxplot()
)

该代码使用 factor() 将数据行按年代分组,然后使用 geom_boxplot() 来创建箱形图。

其实一些几何对象有隐含的统计变换,这可以使我们的代码更加简洁。使用geom_boxplot() 等同于 stat_boxplot(),它负责计算四分位数和离群值。

运行上述代码,我们会得到以下图形。

该箱形图显示了每个十年的水位分布情况

还有其他的统计转换,可以用Python中的ggplot来构建数据的可视化。

刻度 -- 改变数据尺度

刻度是另一种转换,可以在从dataaes的映射中应用,可以帮助可视化更容易理解。

这里看到了一个显示1970年以来各年人口的图。下面的代码显示了如何使用标尺,而不是原始日期,来显示自1970年以来的历年情况。

from plotnine.data import economics
from plotnine import ggplot, aes, scale_x_timedelta, labs, geom_line

(
    ggplot(economics)
    + aes(x="date", y="pop")
    + scale_x_timedelta(name="Years since 1970")
    + labs(title="Population Evolution", y="Population")
    + geom_line()
)

使用 scale_x_timedelta() 通过计算每个点与数据集中最早日期的差值来转换每个点的x值。注意,代码还使用labs()y轴和标题设置了一个更具描述性的标签。

运行该代码显示了这个图。

在不改变数据的情况下,我们已经使可视化更容易理解,对读者更友好。该图现在有更好的描述,X轴显示了自1970年以来的经过的年数,而不是日期。

plotnine 提供了大量的标度转换供你选择,包括对数和其他非线性标度。

坐标系统 -- 映射数据到二维空间

坐标系统定义了数据点如何被映射到图中的二维图形位置。可以把它看作是一个从数学变量到图形位置的映射。选择正确的坐标系统可以提高数据可视化的可读性。

再来看看前面的例子,即用条形图来统计属于不同类别的车辆。用下面的代码创建了该图。

from plotnine.data import mpg
from plotnine import ggplot, aes, geom_bar

ggplot(mpg) + aes(x="class") + geom_bar()

该代码使用 geom_bar() 为每一个车辆类别绘制一个条形图。由于没有设置特定的坐标系,因此使用了默认的坐标系。

运行该代码会产生以下图。

图中每个条形的高度代表一个班级的车辆数量

虽然上述图形没有什么问题,但如果将轴线翻转,显示水平条而不是垂直条,同样的信息就会更直观。

plotnine 提供了几个函数,可以修改坐标系统,可以使用 coord_flip() 翻转坐标轴。

from plotnine.data import mpg
from plotnine import ggplot, aes, geom_bar, coord_flip

ggplot(mpg) + aes(x="class") + geom_bar() + coord_flip()

该代码使用 coord_flip() 翻转了x轴和y轴。运行该代码,我们会看到以下图形。

这个图形显示了在前一个图中看到的相同信息。通过翻转坐标轴,它更容易理解和比较不同的条形。

关于哪个坐标系更好,没有硬性规定。我们应该选择最适合我们的问题和数据的那个。给他们一个尝试,做一些实验,以了解什么对每个案例有效。

分面 -- 同一画布绘制多个数据子集

Facets 是 plotnine 最酷的功能之一,facets允许我们按一些属性对数据进行分组,然后在同一张画布中单独绘制每组数据。当我们想在同一个图形中显示两个以上的变量时,这一点特别有用。

例如利用燃油经济性数据集(mpg),并建立一个图表,显示每年每类车辆的每个发动机尺寸(排量)的每加仑里程。在这种情况下,我们的图需要显示四个变量的信息。

  1. hwy 每加仑英里数
  2. displ 发动机尺寸
  3. class 车辆类别
  4. year 模型年

这里有个问题,我们的变量多于图形的维度。如果必须显示三个变量,我们可以使用三维视角,但四维图形甚至很难想象。

此时可以使用一个两步技巧来解决该问题。

  1. 首先,将数据划分为若干组,其中一组中的所有数据点在某些属性上有相同的值。
  2. 对每个组进行单独绘图,只显示分组中未使用的属性。

回到这个例子,可以按级别和年份对车辆进行分组,然后绘制每组的排量和每加仑英里数。下面的可视化图是用这种技术生成的。

如图所示,每组都有一个面板。每个面板都显示了属于该车辆类别和年份的不同发动机排量的每加仑英里数。

代码

from plotnine.data import mpg
from plotnine import ggplot, aes, facet_grid, labs, geom_point

(
    ggplot(mpg)
    + facet_grid(facets="year~class")
    + aes(x="displ", y="hwy")
    + labs(
        x="Engine Size",
        y="Miles per Gallon",
        title="Miles per Gallon for Each Year and Vehicle Class",
    )
    + geom_point()
)

代码使用 facet_grid() 按年份和车辆类别划分数据,并通过传递给它参数 facet="year~class" 用于划分的属性。对于每个数据分区,使用诸如aes、geomlabs() 等组件来构建绘图。

facet_grid() 在一个网格中显示分区,用一个属性表示行,另一个属性表示列。plotnine 提供了其他分面方法,我们可以用两个以上的属性来划分我们的数据。

主题 -- 改善可视化外观

另外选择一个非默认的主题,可使图表更加美观和充满活力。

plotnine 包括几个主题,这里我们选用黑暗主题绘制同上面一样内容的图表。

from plotnine.data import mpg
from plotnine import ggplot, aes, facet_grid, labs, geom_point, theme_dark

(
    ggplot(mpg)
    + facet_grid(facets="year~class")
    + aes(x="displ", y="hwy")
    + labs(
        x="Engine Size",
        y="Miles per Gallon",
        title="Miles per Gallon for Each Year and Vehicle Class",
    )
    + geom_point()
    + theme_dark()
)

在上面的代码中,指定 theme_dark() 告诉 plotnine 使用黑暗主题来画图。下面是由这段代码生成的图形。

如图所示,设置主题会影响颜色、字体和形状样式。

theme_xkcd() 是另一个常用的主题,一个非常酷的漫画式的外观——它使数据可视化看起来像漫画。

选择新颖的主题可以帮助吸引观众的注意力。

到这里我们已经了解了图形语法的主要内容,以及如何使用 plotnine 来构建数据可视化。在Python中使用ggplot可以逐步建立可视化,首先添加数据,然后添加和调整组件以改善其图形外面表现。

在下文中,云朵君将和大家一起学习如何使用颜色以及如何导出可视化图表

多维度数据可视化

前面我们已经了解到,显示两个以上的变量的数据会比较困难。那如何同时显示三个变量,并用颜色来表示数值,接下来我们一起学习吧。

回到燃油经济性数据集(mpg),需要把发动机汽缸数和燃油效率之间的关系可视化,但也需要在同一个图中包括车辆类别的信息。

作为分面的替代方法,可以用颜色来表示第三个变量的值。那我们就必须把发动机气缸数映射到X轴上,把每加仑的里程数映射到Y轴上,然后用不同的颜色来代表车辆的等级。

下面的代码创建了所述的数据可视化。

from plotnine.data import mpg
from plotnine import ggplot, aes, labs, geom_point

(
    ggplot(mpg)
    + aes(x="cyl", y="hwy", color="class")
    + labs(
        x="Engine Cylinders",
        y="Miles per Gallon",
        color="Vehicle Class",
        title="Miles per Gallon for Engine Cylinders and Vehicle Classes",
    )
    + geom_point()
)

通过在aes定义中传递 color="class",车辆类别被映射到图形颜色。

运行该代码会显示这个图形。

不同类别的车辆显示不同的颜色

前文中,我们学习了另一种方法,即使用 Python 中的 ggplot 在图形中显示两个以上的变量。当有三个变量时,应该在使用 facets 和 colors 之间做出选择,这取决于哪种方法使数据的可视化更容易理解。

导出图表文件

在某些情况下,需要以编程方式将生成的绘图保存为图像文件,而不是在Jupyter Notebook 中实时显示它们。

plotnine 提供了一个非常方便的 save() 方法,可以将绘图导出为图像并保存到一个文件。例如,将图形保存到一个名为 myplot.png 的文件中。

from plotnine.data import economics
from plotnine import ggplot, aes, geom_line

myPlot = ggplot(economics) + aes(x="date", y="pop") + geom_line()
myPlot.save("myplot.png", dpi=600)

这里将数据可视化对象存储在myPlot中,然后调用save()将图形导出为图像并存储为myplot.png

在使用save()时,我们可以调整一些图像设置,如图像的每英寸点数(dpi)。当需要高质量的图像来包含在演示文稿或文章中时,这真的很有用。

plotnine 还包括一个将各种绘图保存在单个PDF 文件中的方法。我们可以在 plotnine 的 save_as_pdf_pages 文档中了解它并看到一些很酷的例子。

总结

在 Python 中使用 ggplot 可以让我们以一种非常简洁和一致的方式建立数据可视化。使用 plotnine 只需几行代码就可以做出复杂而漂亮的图。

最后,如果你对该图库感兴趣,可以看看 plotnine 的文档[4],继续深入 Python 中的 ggplot,还可以访问 plotnine 的图库[5] 以获得更多的想法和灵感。

https://plotnine.readthedocs.io/en/stable/gallery.html


 


 

点这里👇关注我,记得标星哦~

推荐阅读


 


CDA课程咨询

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/147809
 
199 次点击