Matplotlib 实用指南(四)
十六、使用 Pandas 和 Matplotlib 可视化数据
在前一章中,您学习了如何使用 NumPy、Pandas 和 Matplotlib 将各种文件格式存储的数据读入 Python 变量。
现在,您应该可以轻松处理数据了。在本章中,你将练习编写与数据科学领域另一个重要而实用的方面相关的程序:数据集可视化。这一章包含了许多简短的代码片段来演示如何创建数据集的可视化。因此,让我们通过本章中的以下主题继续我们的数据科学之旅:
-
简单的绘图
-
条形图
-
直方图
-
箱线图
-
面积图
-
散点图
-
六边形箱线图
-
饼图
在本章之后,你将能够用 Pandas 和 Matplotlib 创建令人印象深刻的数据集可视化。
简单的绘图
让我们直接进入数据可视化的实践示例。你将首先学习如何可视化简单的绘图。我建议您为本章中的代码示例创建一个新笔记本。
让我们从导入所有必需库的神奇命令开始,如下所示:
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
让我们使用例程cumsum()创建一些数据,如下所示:
df1 = pd.DataFrame(np.random.randn(100, 2), columns=['B', 'C']).cumsum()
df1['A'] = pd.Series(list(range(100)))
print(df1)
结果数据集将有三列,如下所示:
B C A
0 -0.684779 -0.655677 0
1 -0.699163 -1.868611 1
2 -0.315527 -3.513103 2
3 -0.504069 -4.175940 3
4 0.998419 -4.385832 4
.. ... ... ..
95 1.149399 -1.445029 95
96 2.035029 -1.886731 96
97 0.938699 0.188980 97
98 2.449148 0.335828 98
99 2.204369 -1.304379 99
[100 rows x 3 columns]
让我们使用例程plot()来可视化这些数据。dataframe 对象使用的plot()例程默认调用 Pyplot 的plot()。这里有一个例子:
plt.figure()
df1.plot(x='A', y='B')
plt.show()
这段代码是不言自明的。我们传递包含列名的字符串作为 x 轴和 y 轴的参数。它产生如图 16-1 所示的输出。
图 16-1
想象一个简单的绘图
您也可以在可视化中使用其他列,如下所示:
plt.figure()
df1.plot(x='A', y='C')
plt.show()
运行这个例子来看看结果。这就是如何使用不同的列组合来可视化数据。
条形图
让我们使用相同的数据集创建一个简单的条形图。让我们从该数据帧中选取一条记录,如下所示:
print(df1.iloc[4])
以下是输出:
B 0.998419
C -4.385832
A 4.000000
Name: 4, dtype: float64
让我们使用例程bar()用这些数据画一个简单的条形图。以下是相关的代码片段:
plt.figure()
df1.iloc[4].plot.bar()
plt.axhline(0, color='k')
plt.show()
在这个代码示例中,我们使用axhline()绘制一条对应于 x 轴的水平线。图 16-2 显示输出。
图 16-2
可视化简单的条形图
让我们讨论一个更复杂的条形图的例子。让我们创建一个新的数据集,如下所示:
df2 = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
print(df2)
输出如下所示:
a b c d
0 0.352173 0.127452 0.637665 0.734944
1 0.375190 0.931818 0.769403 0.927441
2 0.830744 0.942059 0.781032 0.557774
3 0.977058 0.594992 0.557016 0.862058
4 0.960796 0.329448 0.493713 0.971139
5 0.364460 0.516401 0.432365 0.587528
6 0.292020 0.500945 0.889294 0.211502
7 0.770808 0.519468 0.279582 0.419549
8 0.982924 0.458197 0.938682 0.123614
9 0.578290 0.186395 0.901216 0.099061
在前面的例子中,我们只可视化了一行。现在,让我们将整个数据集可视化如下:
plt.figure()
df2.plot.bar()
plt.show()
这将为每一行创建一个条形图。图表将按行分组,如图 16-3 所示。
图 16-3
可视化更复杂的条形图
可以看到,x 轴表示指数,y 轴表示幅度。这是一个未堆叠的垂直条形图。您可以通过传递一个简单的参数来创建它的堆叠变体,如下所示:
plt.figure()
df2.plot.bar(stacked=True)
plt.show()
图 16-4 显示了输出。
图 16-4
可视化垂直堆叠条形图
您甚至可以创建水平堆叠和非堆叠条形图。让我们用例程barh()创建一个水平堆叠条形图,如下所示:
plt.figure()
df2.plot.barh(stacked=True)
plt.show()
图 16-5 显示了输出。
图 16-5
可视化水平堆叠条形图
让我们通过省略参数为非堆叠水平条形图编写一段代码,如下所示:
plt.figure()
df2.plot.barh()
plt.show()
图 16-6 显示了输出。
图 16-6
可视化水平未堆叠条形图
您刚刚学习了如何创建各种类型的条形图。
直方图
直方图是数字数据频率分布的直观表示。它首先被卡尔·皮尔逊使用。
我们首先将数据分成不同的桶或箱。箱子的大小取决于要求。对于整数数据集,可以有最小的容器大小,即 1。然后,对于每个库,您可以列出该库下的元素的出现次数。然后,您可以将该表显示为条形图。
你可以用 Pandas 和 Matplotlib 绘制给定数据集的直方图。让我们创建一个数据集,如下所示:
df4 = pd.DataFrame({'a': np.random.randn(1000) + 1,
'b': np.random.randn(1000),
'c': np.random.randn(1000) - 1},
columns=['a', 'b', 'c'])
print(df4)
生成的数据集如下:
a b c
0 1.454474 -0.517940 -0.772909
1 1.886328 0.868393 0.109613
2 0.041313 -1.959168 -0.713575
3 0.650075 0.457937 -0.501023
4 1.684392 -0.072837 1.821190
.. ... ... ...
995 0.800481 -1.209032 -0.249132
996 0.490104 0.253966 -1.185503
997 2.304285 0.082134 -1.068881
998 1.249055 0.040750 -0.488890
999 -1.216627 0.444629 -1.198375
[1000 rows x 3 columns]
让我们使用例程hist()将该数据集可视化为直方图,如下所示:
plt.figure();
df4.plot.hist(alpha=0.7)
plt.show()
图 16-7 显示了输出。
图 16-7
将数据集可视化为直方图
传递给 routine 的参数决定了输出的不透明度(或 alpha 透明度)。在上一个示例中,您必须使其透明,因为直方图未堆叠。让我们创建一个堆叠直方图,桶的大小为 20,如下所示:
plt.figure();
df4.plot.hist(stacked=True, bins=20)
plt.show()
图 16-8 显示了输出。
图 16-8
将同一数据集可视化为非堆叠直方图
让我们创建一个单列的水平累积直方图,如下所示:
plt.figure();
df4['a'].plot.hist(orientation='horizontal', cumulative=True)
plt.show()
图 16-9 显示了输出。
图 16-9
水平累积直方图
相同直方图的垂直版本可创建如下:
plt.figure();
df4['a'].plot.hist(orientation='vertical', cumulative=True)
plt.show()
图 16-10 显示了输出。
图 16-10
垂直累积直方图
接下来让我们尝试一种奇特的直方图。例程diff()计算前一行和当前行之间的数值差。
print(df4.diff())
对于所有列,输出将在第一行填充 NaN(因为在第一行之前没有行)。输出如下所示:
a b c
0 NaN NaN NaN
1 0.431854 1.386333 0.882522
2 -1.845015 -2.827562 -0.823188
3 0.608762 2.417105 0.212552
4 1.034317 -0.530774 2.322213
.. ... ... ...
995 0.411207 -2.847858 0.325067
996 -0.310378 1.462998 -0.936370
997 1.814182 -0.171832 0.116622
998 -1.055230 -0.041384 0.579991
999 -2.465682 0.403880 -0.709485
[1000 rows x 3 columns]
让我们来可视化这个数据集,如下所示:
plt.figure()
df4.diff().hist(color='k', alpha=0.5, bins=50)
plt.show()
图 16-11 显示了输出。
图 16-11
列方向直方图
您刚刚学习了如何将数据集可视化为直方图。
箱线图
您也可以用盒状图来可视化数据。箱线图(也拼写为箱线图)通过四分位数显示数字数据组。让我们创建一个数据集,如下所示:
df = pd.DataFrame(np.random.rand(10, 5),
columns=['A', 'B', 'C', 'D', 'E'])
print(df)
生成的数据集如下:
A B C D E
0 0.684284 0.033906 0.099369 0.684024 0.533463
1 0.614305 0.645413 0.871788 0.561767 0.149080
2 0.226480 0.440091 0.096022 0.076962 0.674901
3 0.541253 0.409599 0.487924 0.649260 0.582250
4 0.436995 0.142239 0.781428 0.634987 0.825146
5 0.804633 0.874081 0.018661 0.306459 0.008134
6 0.228287 0.418942 0.157755 0.561070 0.740077
7 0.699860 0.230533 0.240369 0.108759 0.843307
8 0.530943 0.374583 0.650235 0.370809 0.595791
9 0.213455 0.221367 0.035203 0.887068 0.593629
您可以按如下方式绘制箱形图:
plt.figure()
df.plot.box()
plt.show()
这将把数据集显示为箱形图,如图 16-12 所示。
图 16-12
垂直箱线图
此处显示的颜色是默认值。你可以改变他们。首先,您需要创建一个字典,如下所示:
color = dict(boxes='DarkGreen',
whiskers='DarkOrange',
medians='DarkBlue',
caps='Gray')
print(color)
以下是输出:
{'boxes': 'DarkGreen', 'whiskers': 'DarkOrange', 'medians': 'DarkBlue', 'caps': 'Gray'}
最后,您将这个字典作为参数传递给绘制盒状图的例程,如下所示:
plt.figure()
df.plot.box(color=color, sym='r+')
plt.show()
图 16-13 显示了输出。
图 16-13
带有自定义颜色的垂直方框图
以下示例创建了一个水平方框图可视化:
plt.figure()
df.plot.box(vert=False, positions=[1, 2, 3, 4 , 5])
plt.show()
图 16-14 显示了输出。
图 16-14
水平箱形图
让我们看看另一个例程,boxplot(),它也创建了方框图。为此,让我们创建另一个数据集,如下所示:
df = pd.DataFrame(np.random.rand(10, 5))
print(df)
输出数据集如下所示:
0 1 2 3 4
0 0.936845 0.365561 0.890503 0.264896 0.937254
1 0.931661 0.226297 0.887385 0.036719 0.941609
2 0.127896 0.291034 0.161724 0.952966 0.925534
3 0.938686 0.336536 0.934843 0.806043 0.104054
4 0.743787 0.600116 0.989178 0.002870 0.453338
5 0.256692 0.773945 0.165381 0.809204 0.162431
6 0.822131 0.486780 0.453981 0.612403 0.614633
7 0.062387 0.958844 0.247515 0.573431 0.194665
8 0.453193 0.152337 0.062436 0.865115 0.220440
9 0.832040 0.237582 0.837805 0.423779 0.119027
您可以按如下方式绘制箱形图:
plt.figure()
bp = df.boxplot()
plt.show()
图 16-15 显示了输出。
图 16-15
方框图在起作用
例程boxplot()的主要优点是您可以在单个输出中拥有列级可视化。让我们创建一个适当的数据集,如下所示:
df = pd.DataFrame(np.random.rand(10, 2), columns=['Col1', 'Col2'] )
df['X'] = pd.Series(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'])
print(df)
输出数据集如下所示:
Col1 Col2 X
0 0.469416 0.341874 A
1 0.176359 0.921808 A
2 0.135188 0.149354 A
3 0.475295 0.360012 A
4 0.566289 0.142729 A
5 0.408705 0.571466 B
6 0.233820 0.470200 B
7 0.679833 0.633349 B
8 0.183652 0.559745 B
9 0.192431 0.726981 B
让我们按如下方式创建列级可视化:
plt.figure();
bp = df.boxplot(by='X')
plt.show()
默认情况下,输出会有一个解释数据如何分组的标题,如图 16-16 所示。
图 16-16
带组的盒状图
让我们看一个稍微复杂一点的例子。以下是新数据集的代码:
df = pd.DataFrame(np.random.rand(10,3), columns=['Col1', 'Col2', 'Col3'])
df['X'] = pd.Series(['A','A','A','A','A','B','B','B','B','B'])
df['Y'] = pd.Series(['A','B','A','B','A','B','A','B','A','B'])
print(df)
这段代码创建了以下数据集:
Col1 Col2 Col3 X Y
0 0.542771 0.175804 0.017646 A
1 0.247552 0.503725 0.569475 A B
2 0.593635 0.842846 0.755377 A
3 0.210409 0.235510 0.633318 A B
4 0.268419 0.170563 0.478912 A
5 0.526251 0.258278 0.549876 B
6 0.311182 0.212787 0.966183 B A
7 0.100687 0.432545 0.586907 B
8 0.416833 0.879384 0.635664 B A
9 0.249280 0.558648 0.661523 B
您可以在多个列的组中创建盒图(这意味着分组标准将有多个列)。
plt.figure();
bp = df.boxplot(column=['Col1','Col2'], by=['X','Y'])
plt.show()
图 16-17 显示了输出。
图 16-17
分组的盒状图(分组标准中的多列)
让我们看一个更复杂的例子,数据集有更多的变化。下面的代码创建了这样一个数据集:
np.random.seed(1234)
df_box = pd.DataFrame(np.random.randn(10, 2), columns=['A', 'B'])
df_box['C'] = np.random.choice(['Yes', 'No'], size=10)
print(df_box)
输出是以下数据集:
A B C
0 0.471435 -1.190976 No
1 1.432707 -0.312652 Yes
2 -0.720589 0.887163 No
3 0.859588 -0.636524 Yes
4 0.015696 -2.242685 No
5 1.150036 0.991946 Yes
6 0.953324 -2.021255 No
7 -0.334077 0.002118 No
8 0.405453 0.289092 No
9 1.321158 -1.546906 No
您可以使用 Pandas 中的例程groupby()对数据进行分组,并将其可视化,如下所示:
plt.figure()
bp = df_box.boxplot(by='C')
plt.show()
图 16-18 显示了按列 c 分组的输出。
图 16-18
箱线图 plt.figure()可视化,按列 C 分组
另一个例子如下:
bp = df_box.groupby('C').boxplot()
plt.show()
图 16-19 显示了输出。
图 16-19
按列 C 分组的箱形图可视化
这就是将数据集可视化为箱线图的方式。
面积图
您也可以将数据集可视化为面积图。让我们创建一个包含四列的数据集,如下所示:
df = pd.DataFrame(np.random.rand(10, 4),
columns=['A', 'B', 'C', 'D'])
print(df)
这将创建以下数据集:
A B C D
0 0.982005 0.123943 0.119381 0.738523
1 0.587304 0.471633 0.107127 0.229219
2 0.899965 0.416754 0.535852 0.006209
3 0.300642 0.436893 0.612149 0.918198
4 0.625737 0.705998 0.149834 0.746063
5 0.831007 0.633726 0.438310 0.152573
6 0.568410 0.528224 0.951429 0.480359
7 0.502560 0.536878 0.819202 0.057116
8 0.669422 0.767117 0.708115 0.796867
9 0.557761 0.965837 0.147157 0.029647
您可以使用例程area()可视化所有这些数据,如下所示:
plt.figure()
df.plot.area()
plt.show()
前面的例子创建了一个堆积面积图,如图 16-20 所示。
图 16-20
堆积面积图
您也可以通过向例程area()传递一个参数来创建未堆叠区域图,如下所示:
plt.figure()
df.plot.area(stacked=False)
plt.show()
默认情况下,未堆叠面积图是透明的,因此所有单个面积图都是可见的。图 16-21 显示了输出。
图 16-21
未堆叠面积图
这是创建面积图的方法。
散点图
您还可以将任何数据集可视化为散点图。让我们创建一个数据集,如下所示:
df = pd.DataFrame(np.random.rand(10, 4),
columns=['A', 'B', 'C', 'D'])
print(df)
输出数据集如下所示:
A B C D
0 0.593893 0.114066 0.950810 0.325707
1 0.193619 0.457812 0.920403 0.879069
2 0.252616 0.348009 0.182589 0.901796
3 0.706528 0.726658 0.900088 0.779164
4 0.599155 0.291125 0.151395 0.335175
5 0.657552 0.073343 0.055006 0.323195
6 0.590482 0.853899 0.287062 0.173067
7 0.134021 0.994654 0.179498 0.317547
8 0.568291 0.009349 0.900649 0.977241
9 0.556895 0.084774 0.333002 0.728429
您可以将 A 列和 B 列可视化为散点图,如下所示:
plt.figure()
df.plot.scatter(x='A', y='B')
plt.show()
图 16-22 显示了输出。
图 16-22
简单散点图
您可以可视化多个组,如下所示:
ax = df.plot.scatter(x='A', y='B',
color='Blue',
label='Group 1')
plt.figure()
df.plot.scatter(x='C', y='D',
color='Green',
label='Group 2',
ax=ax)
plt.show()
图 16-23 显示了输出。
图 16-23
多组散点图
让我们看看如何自定义散点图。您可以自定义点的颜色和大小。颜色或尺寸可以是恒定的,也可以是可变的。以下是数据点可变颜色和恒定大小的示例。当颜色可变时,默认情况下会在输出中添加一个颜色条。
plt.figure()
df.plot.scatter(x='A', y='B', c='C', s=40)
plt.show()
图 16-24 显示了输出。
图 16-24
数据点的不同颜色散点图
让我们将大小指定为变量,如下所示:
plt.figure()
df.plot.scatter(x='A', y='B', s=df['C']*100)
plt.show()
图 16-25 显示了输出。
图 16-25
数据点大小不同的散点图
最后,让我们看一个完全定制的可变尺寸和可变颜色的示例,如下所示:
plt.figure()
df.plot.scatter(x='A', y='B', c='C', s=df['D']*100)
plt.show()
图 16-26 显示了输出。
图 16-26
数据点大小不同的散点图
您刚刚学习了如何创建和定制散点图。
六边形箱线图
您也可以用六边形仓(hexbin)图来可视化数据。让我们准备一个数据集如下:
df = pd.DataFrame(np.random.randn(100, 2),
columns=['A', 'B'])
df['B'] = df['B'] + np.arange(100)
print(df)
输出如下所示:
A B
0 0.165445 -1.127470
1 -1.192185 1.818644
2 0.237185 1.663616
3 0.694727 3.750161
4 0.247055 4.645433
.. ... ...
95 0.650346 94.485664
96 0.539429 97.526762
97 -3.277193 95.151439
98 0.672125 96.507021
99 -0.827198 99.914196
[100 rows x 2 columns]
让我们用 hexbin 图来直观显示这些数据,如下所示:
plt.figure()
df.plot.hexbin(x='A', y='B', gridsize=20)
plt.show()
图 16-27 显示了输出。
图 16-27
Hexbin 图示例
如您所见,您可以自定义网格的大小。
饼图
最后,您将学习如何创建饼图来可视化数据集。让我们创建一个数据集,如下所示:
series = pd.Series(3 * np.random.rand(4),
index=['A', 'B', 'C', 'D'],
name='series')
print(series)
这将创建以下数据集:
A 1.566910
B 0.294986
C 2.140910
D 2.652122
Name: series, dtype: float64
您可以将其形象化如下:
plt.figure()
series.plot.pie(figsize=(6, 6))
plt.show()
图 16-28 显示了输出。
图 16-28
简单的饼图
让我们创建一个包含两列的数据集,如下所示:
df = pd.DataFrame(3 * np.random.rand(4, 2),
index=['A', 'B', 'C', 'D'],
columns=['X', 'Y'])
print(df)
这会生成以下数据:
X Y
A 1.701163 2.983445
B 0.536219 0.036600
C 1.370995 2.795256
D 2.538074 1.419990
图 16-29 显示了输出。
图 16-29
多列数据集的简单饼图
您可以自定义饼图。具体来说,您可以自定义字体、颜色和标签,如下所示:
plt.figure()
series.plot.pie(labels=['A', 'B', 'C', 'D'],
colors=['r', 'g', 'b', 'c'],
autopct='%.2f', fontsize=20,
figsize=(6, 6))
plt.show()
图 16-30 显示了输出。
图 16-30
一个简单而定制的饼图
让我们通过传递总和小于 1.0 的值来创建一个部分饼图。以下是这方面的数据:
series = pd.Series([0.1] * 4,
index=['A', 'B', 'C', 'D'],
name='series2')
print(series)
这将创建以下数据集:
A 0.1
B 0.1
C 0.1
D 0.1
Name: series2, dtype: float64
部分饼图可以如下图所示:
plt.figure()
series.plot.pie(figsize=(6, 6))
plt.show()
这就形成了一个局部饼图(或半圆),如图 16-31 所示。
图 16-31
一个简单而定制的饼图
您刚刚学习了如何用饼图可视化数据。
摘要
在本章中,您学习了如何使用各种技术来可视化数据。您可以在实际项目中使用这些可视化技术。在接下来的章节中,我们将探索用 Python 创建数据可视化的其他库。
在下一章中,您将了解如何使用一个名为 Seaborn 的新库来创建数据可视化。
十七、Seaborn 数据可视化简介
在前一章中,您学习了如何可视化存储在 Pandas 系列和 dataframe 中的数据。
在本书的前几章中,您广泛学习了数据可视化库 Matplotlib 以及其他重要的数据科学库 NumPy 和 Pandas。在这一章中,您将暂时脱离 Matplotlib,学习如何使用另一个名为 Seaborn 的相关库进行数据可视化。以下是您将在本章中了解的主题:
-
什么是 Seaborn?
-
绘制统计关系
-
绘制线条
-
可视化数据的分布
读完这一章,你会很容易使用 Seaborn 库,并且能够创建很好的数据集可视化。
什么是 Seaborn?
您已经学习了如何使用 Matplotlib 库进行数据可视化。Matplotlib 并不是 Python 中唯一的数据可视化库。Python 中有许多可以可视化数据的库。科学数据可视化库支持 NumPy 和 Pandas 的数据结构。用于科学 Python 可视化的一个这样的库是 Seaborn ( https://seaborn.pydata.org/index.html )。Seaborn 是基于 Matplotlib 构建的。它为绘制吸引人的图形提供了很多功能。它在 Pandas 中内置了对 series 和 dataframe 数据结构的支持,在 NumPy 中内置了对 Ndarrays 的支持。
让我们为本章中的演示创建一个新笔记本。现在,让我们用下面的命令安装 Seaborn:
!pip3 install seaborn
您可以使用以下语句将库导入到您的笔记本或 Python 脚本中:
import seaborn as sns
你知道 Seaborn 图书馆支持 Pandas 数据帧。Seaborn 库也存储了许多填充了数据的数据帧。所以,我们可以用它们来做演示。让我们看看如何检索这些数据帧。以下命令返回所有内置示例数据帧的列表:
sns.get_dataset_names()
以下是输出:
['anagrams',
'anscombe',
'attention',
'brain_networks',
'car_crashes',
'diamonds',
'dots',
'exercise',
'flights',
'fmri',
'gammas',
'geyser',
'iris',
'mpg',
'penguins',
'planets',
'tips',
'titanic']
您可以将这些数据帧加载到 Python 变量中,如下所示:
iris = sns.load_dataset('iris')
让我们用下面的语句来看看存储在iris数据集中的数据:
iris
图 17-1 显示了输出。
图 17-1
虹膜数据集
绘制统计关系
您可以在 Seaborn 中用各种函数绘制两个变量之间的统计关系。完成这项工作的通用绘图函数是relplot()。您可以使用此功能绘制各种类型的数据。默认情况下,relplot()函数绘制散点图。这里有一个例子:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
sns.relplot(x='sepal_length',
y='sepal_width',
data=iris)
plt.grid('on')
plt.show()
这产生了如图 17-2 所示的散点图。
图 17-2
散点图
您可以明确指定绘图类型,如下所示:
sns.relplot(x='sepal_length', y='sepal_width',
data=iris, kind='scatter')
plt.grid('on')
plt.show()
函数replot()是一个通用函数,可以传递一个参数来指定绘图类型。您也可以使用功能scatterplot()创建散点图。例如,下面的代码创建了如图 17-2 所示的相同结果:
sns.scatterplot(x='sepal_length',
y='sepal_width',
data=iris)
plt.grid('on')
plt.show()
您可以将数据集的一些其他列提供给绘图函数,如下所示:
sns.relplot(x='petal_length',
y='petal_width',
data=iris)
plt.grid('on')
plt.show()
图 17-3 显示了输出。
图 17-3
散点图的另一个例子
您也可以用scatterplot()函数编写如下:
sns.scatterplot(x='petal_length',
y='petal_width',
data=iris)
plt.grid('on')
plt.show()
您可以自定义绘图,并使用颜色编码显示附加列,如下所示:
sns.relplot(x='sepal_length',
y='sepal_width',
hue='species',
data=iris)
plt.grid('on')
plt.show()
图 17-4 显示了输出。
图 17-4
带颜色的散点图
使用以下代码,您会得到如图 17-4 所示的相同结果:
sns.scatterplot(x='sepal_length',
y='sepal_width',
hue='species',
data=iris)
plt.grid('on')
plt.show()
您还可以为散点图数据点(标记)分配样式,如下所示:
sns.relplot(x='sepal_length', y='sepal_width',
hue='petal_length', style='species',
data=iris)
plt.grid('on')
plt.show()
您可以在图 17-5 中看到输出。
图 17-5
带有颜色和自定义样式的散点图
以下代码产生如图 17-5 所示的相同输出:
sns.scatterplot(x='sepal_length', y='sepal_width',
hue='petal_length', style='species',
data=iris)
plt.grid('on')
plt.show()
您也可以调整标记的大小,如下所示:
sns.relplot(x='sepal_length', y='sepal_width',
size='petal_length', style='species',
hue='species', data=iris)
plt.grid('on')
plt.show()
图 17-6 显示了输出。
图 17-6
带有颜色、自定义样式和标记大小的散点图
以下代码产生如图 17-5 所示的相同结果:
sns.scatterplot(x='sepal_length', y='sepal_width',
size='petal_length', style='species',
hue='species', data=iris)
plt.grid('on')
plt.show()
绘制线条
您还可以显示连续数据,如沿线的时间序列数据。时序数据至少在一列中有时间戳数据,或者有一个索引。时间序列的一个很好的例子是每日温度记录表。让我们创建一个时间序列数据框架来演示折线图。
df = pd.DataFrame(np.random.randn(100, 4),
index=pd.date_range("1/1/2020",
periods=100),
columns=list("ABCD"))
df = df.cumsum()
您可以使用功能relplot()绘制如下直线:
sns.relplot(x=df.index, y='A', kind="line", data=df)
plt.xticks(rotation=45)
plt.show()
图 17-7 显示了输出。
图 17-7
时间序列数据的线图
您也可以使用以下代码生成如图 17-7 所示的输出:
sns.lineplot(x=df.index,
y='A', data=df)
plt.xticks(rotation=45)
plt.show()
在下一节中,您将学习如何可视化数据的分布。
可视化数据的分布
可视化数据分布的一个最突出的例子是频率表或频率分布表。您可以创建数据可以具有的值范围的存储桶(域),然后可以列出满足存储桶标准的项目数。您还可以改变存储桶的大小,最小大小为 1。
您可以使用条形图和线条直观地显示频率分布的信息。如果你使用棒线,那么它就是所谓的直方图。您可以使用功能displot()来可视化频率数据。让我们从虚拟的单变量数据开始。
x = np.random.randn(100)
sns.displot(x)
plt.show()
图 17-8 显示了输出。
图 17-8
柱状图
您还可以在输出中明确表示您需要一个直方图,如下所示:
sns.displot(x, kind='hist')
plt.show()
直方图是默认的图表类型。您还可以显示高斯核密度估计(KDE),如下所示:
sns.displot(x, kind='kde')
plt.show()
图 17-9 显示了输出。
图 17-9
KDE 图
您可以将经验累积分布函数(eCDF)可视化如下:
sns.displot(x, kind='ecdf')
plt.show()
图 17-10 显示了输出。
图 17-10
eCDF 图
您可以将直方图和 KDE 组合起来,如下所示:
sns.displot(x, kind='hist', kde=True)
plt.show()
图 17-11 显示了输出。
图 17-11
结合 KDE 的直方图
现在让我们使用一些现实生活中的数据,如下:
tips = sns.load_dataset("tips")
sns.displot(x='total_bill', data=tips, kind='hist')
plt.show()
图 17-12 显示了输出。
图 17-12
现实生活中的数据可视化为直方图
您可以在可视化中自定义容器(或桶)的大小,如下所示:
sns.displot(x='total_bill', data=tips,
kind='hist', bins=30, kde=True)
plt.show()
图 17-13 显示了输出。
图 17-13
直方图中的自定义存储桶
您可以根据您选择的标准调整图的色调,如下所示:
sns.displot(x='total_bill', data=tips,
kind='kde', hue='size')
plt.show()
图 17-14 显示了输出。
图 17-14
KDE 图中的定制颜色
到目前为止,我们已经使用了单个变量来显示该图。当您使用两个变量进行绘图时,它被称为双变量图。这里有一个简单的例子:
sns.displot(x='total_bill',
y='tip', data=tips)
plt.show()
图 17-15 显示了输出。
图 17-15
简单的二元直方图
您可以向此示例添加颜色,如下所示:
sns.displot(x='total_bill', y='tip',
hue='size', data=tips)
plt.show()
图 17-16 显示了输出。
图 17-16
一个简单的带颜色的二元直方图
您还可以自定义框的大小,并在 x 轴和 y 轴上添加记号(称为地毯图),如下所示:
sns.displot(x='total_bill', y='tip',
data=tips, rug=True,
kind='hist', bins=30)
plt.show()
图 17-17 显示了输出。
图 17-17
一个简单的双变量直方图,带有自定义的条块和地毯图
一种更有趣的可视化形式是双变量 KDE 图。它看起来像一个轮廓。代码如下:
sns.displot(x='total_bill', y='tip',
data=tips, kind='kde')
plt.show()
图 17-18 显示了输出。
图 17-18
一个简单的二元 KDE 图
您可以将地毯图添加到输出中,如下所示:
sns.displot(x='total_bill', y='tip',
data=tips, rug=True,
kind='kde')
plt.show()
输出具有 KDE 和 rug 可视化效果,如图 17-19 所示。
图 17-19
带有地毯图的简单二元 KDE 图
基于数据框中的列,您可以创建按行或列排列的单个可视化效果。让我们根据吸头的大小创建一个可视化效果,如下所示:
sns.displot(x='total_bill', y='tip',
data=tips, rug=True,
kind='kde', col='size')
plt.show()
在前面的示例中,我们启用了 rug plot 特性,这些图将根据吸头的大小单独生成。图 17-20 显示了输出。
图 17-20
一个简单的二元 KDE 图,地毯图按列排列
您也可以按如下方式按行排列各个图形:
sns.displot(x='total_bill', y='tip',
data=tips, rug=True,
kind='kde', row='size')
plt.show()
图 17-21 显示了输出。
图 17-21
带有成行排列的地毯图的简单二元 KDE 图
您刚刚学习了如何可视化数据的分布。
摘要
这一章包含了大量的演示。您详细探索了 Python 的 Seaborn 数据可视化库。Seaborn 是一个庞大的库,在这一章中我们仅仅触及了它的皮毛。你可以参考位于 https://seaborn.pydata.org/index.html 的 Seaborn 项目主页,获取 API 文档、教程和示例库。
在本书的下一章也是最后一章,您将学习如何使用 Matplotlib 和 Seaborn 数据可视化库可视化当前正在进行的新冠肺炎疫情的真实数据。
十八、使用 Matplotlib 和 Seaborn 可视化真实数据
在上一章中,您学习了如何使用新的数据可视化库为科学 Python 任务可视化数据。您学习了从以各种格式存储的数据中创建可视化效果。
在本章中,您将利用本书前几章中获得的所有知识,将它们整合在一起,为来自新冠肺炎疫情的真实数据和来自互联网的动物疾病数据集准备可视化。以下是您将在本章中探讨的主题:
-
新冠肺炎疫情数据
-
以编程方式获取疫情数据
-
为可视化准备数据
-
使用 Matplotlib 和 Seaborn 创建可视化
-
创建动物疾病数据的可视化
阅读完本章后,您将能够轻松使用和创建真实数据集的可视化效果。
新冠肺炎疫情数据
在写这篇文章的时候(2021 年 5 月),世界正面临着新冠肺炎疫情。新冠肺炎是由严重急性呼吸综合征冠状病毒 2 型(新型冠状病毒)引起的。症状包括常见的流感样症状和呼吸困难。
世界上有多个组织收集和共享流行病的实时数据。一个是约翰霍普金斯大学( https://coronavirus.jhu.edu/map.html ),一个是 Worldometers ( https://www.worldometers.info/coronavirus/ )。这两个网页都有关于新冠肺炎疫情的数据,并且更新非常频繁。图 18-1 显示了新冠肺炎的约翰霍普金斯页面。
图 18-1
约翰霍普金斯大学新冠肺炎主页
图 18-2 显示了 Worldometers 网站。
图 18-2
世界计量新冠肺炎主页
正如我提到的,数据经常更新,所以这些网站对于最新的信息是相当可靠的。
以编程方式获取疫情数据
在本节中,您将学习如何使用 Python 程序获取两个数据集(约翰霍普金斯大学和世界计量学院)。为此,您需要为 Python 安装一个库。图书馆主页位于 https://ahmednafies.github.io/covid/ ,PyPI 页面为 https://pypi.org/project/covid/ 。使用 Jupyter 笔记本为本章创建一个新笔记本。您可以在笔记本中使用以下命令轻松安装该库:
!pip3 install covid
您可以将库导入笔记本或 Python 脚本/程序,如下所示:
from covid import Covid
您可以创建一个对象来从在线源获取数据。默认情况下,约翰霍普金斯大学的数据源如下:
covid = Covid()
请注意,由于高流量,有时服务器没有响应。这种情况我经历过很多次。
您可以按如下方式明确提及数据源:
covid = Covid(source="john_hopkins")
您可以按如下方式明确指定世界几何:
covid = Covid(source="worldometers")
您可以看到数据的来源如下:
covid.source
根据数据源,这会返回一个相关的字符串,如下所示:
'john_hopkins'
您可以按国家名称获取状态,如下所示:
covid.get_status_by_country_name("italy")
这将返回一个字典,如下所示:
{'id': '86',
'country': 'Italy',
'confirmed': 4188190,
'active': 283744,
'deaths': 125153,
'recovered': 3779293,
'latitude': 41.8719,
'longitude': 12.5674,
'last_update': 1621758045000}
您还可以通过国家 ID 获取状态,尽管只有 Johns Hopkins 数据集有此列,因此代码将为 Worldometers 返回一个错误。
# Only valid for Johns Hopkins
covid.get_status_by_country_id(115)
输出类似于前面的示例,如下所示:
{'id': '115',
'country': 'Mexico',
'confirmed': 2395330,
'active': 261043,
'deaths': 221597,
'recovered': 1912690,
'latitude': 23.6345,
'longitude': -102.5528,
'last_update': 1621758045000}
您也可以获取国家列表,如下所示:
covid.list_countries()
以下是部分输出:
{'id': '179', 'name': 'US'},
{'id': '80', 'name': 'India'},
{'id': '24', 'name': 'Brazil'},
{'id': '63', 'name': 'France'},
{'id': '178', 'name': 'Turkey'},
{'id': '143', 'name': 'Russia'},
{'id': '183', 'name': 'United Kingdom'},
....
在本章中,您将继续使用约翰霍普金斯数据集。
您可以获得如下活动案例:
covid.get_total_active_cases()
输出如下所示:
27292520
您可以按如下方式获得确诊病例总数:
covid.get_total_confirmed_cases()
输出如下所示:
166723247
您可以获得恢复的案例总数,如下所示:
covid.get_total_recovered()
输出如下所示:
103133392
你可以得到总死亡人数如下:
covid.get_total_deaths()
输出如下所示:
3454602
您可以通过函数调用covid.get_data()获取所有数据。这将返回一个字典列表,其中每个字典保存一个国家的数据。以下是输出:
[{'id': '179',
'country': 'US',
'confirmed': 33104963,
'active': None,
'deaths': 589703,
'recovered': None,
'latitude': 40.0,
'longitude': -100.0,
'last_update': 1621758045000},
{'id': '80',
'country': 'India',
'confirmed': 26530132,
'active': 2805399,
'deaths': 299266,
'recovered': 23425467,
'latitude': 20.593684,
'longitude': 78.96288,
'last_update': 1621758045000},
......
为可视化准备数据
您必须准备好这些提取的数据以便可视化。为此,您必须转换 Pandas 数据框架中的词典列表。可以按如下方式完成:
import pandas as pd
df = pd.DataFrame(covid.get_data())
print(df)
图 [18-3 显示了输出。
图 18-3
新冠肺炎数据的 Pandas 数据框架
您可以按如下方式进行排序:
sorted = df.sort_values(by=['confirmed'], ascending=False)
然后,您必须排除世界和各大洲的数据,以便只保留单个国家的数据。
excluded = sorted [ ~sorted.country.isin(['Europe', 'Asia',
'South America',
'World', 'Africa',
'North America'])]
让我们找出十大记录。
top10 = excluded.head(10)
print(top10)
然后,您可以将列分配给各个变量,如下所示:
x = top10.country
y1 = top10.confirmed
y2 = top10.active
y3 = top10.deaths
y4 = top10.recovered
使用 Matplotlib 和 Seaborn 创建可视化
让我们用 Matplotlib 和 Seaborn 将数据可视化。首先导入所有需要的库,如下所示:
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
可以获得如下简单的线性图:
plt.plot(x, y1)
plt.xticks(rotation=90)
plt.show()
图 18-4 显示了输出。
图 18-4
使用 Matplotlib 绘制线性图
你可以给这个绘图加个标题。你也可以使用 Seaborn 库。以下是 Seaborn 的线形图示例:
sns.set_theme(style='whitegrid')
sns.lineplot(x=x, y=y1)
plt.xticks(rotation=90)
plt.show()
在代码示例中,我们使用了函数set_theme()。它为 Matplotlib 和 Seaborn 可视化设置整个笔记本的主题。您可以将字符串'darkgrid'、'whitegrid'、'dark'、'white'或'ticks'中的一个作为参数传递给这个函数。图 18-5 显示了输出。
图 18-5
带有 Seaborn 的线性图
您可以使用 Matplotlib 创建一个简单的条形图,如下所示:
plt.bar(x, y1)
plt.xticks(rotation=45)
plt.show()
图 18-6 显示了输出。
图 18-6
使用 Matplotlib 绘制条形图
同样的可视化也可以用 Seaborn 来实现,它可以生成美观得多的条形图。
sns.barplot(x=x, y=y1)
plt.xticks(rotation=45)
plt.show()
图 18-7 显示了输出。
图 18-7
有 Seaborn 的条形图
您甚至可以按如下方式更改调色板:
sns.barplot(x=x, y=y1,
palette="Blues_d")
plt.xticks(rotation=45)
plt.show()
图 18-8 显示了输出。
图 18-8
使用带有自定义调色板的 Seaborn 的条形图
您可以按如下方式创建多行图形:
labels = ['Confirmed', 'Active', 'Deaths', 'Recovered']
plt.plot(x, y1, x, y2, x, y3, x, y4)
plt.legend(labels, loc='upper right')
plt.xticks(rotation=90)
plt.show()
图 18-9 显示了输出。
图 18-9
多线图
您可以使用 Seaborn 库来创建相同的图形,如下所示:
sns.lineplot(x=x, y=y1)
sns.lineplot(x=x, y=y2)
sns.lineplot(x=x, y=y3)
sns.lineplot(x=x, y=y4)
plt.legend(labels, loc='upper right')
plt.xticks(rotation=45)
plt.show()
图 18-10 显示了输出。
图 18-10
带有 Seaborn 的多线图
现在,您将看到如何使用 Matplotlib 创建多条形图,如下所示:
df2 = pd.DataFrame([y1, y2, y3, y4])
df2.plot.bar()
plt.legend(x, loc='best')
plt.xticks(rotation=45)
plt.show()
图 18-11 显示了输出。
图 18-11
多行条形图
您甚至可以横向显示,如下所示:
df2.plot.barh()
plt.legend(x, loc='best')
plt.xticks(rotation=45)
plt.show()
图 18-12 显示了输出。
图 18-12
多线水平图
您可以使用 Seaborn 创建散点图,如下所示:
sns.scatterplot(x=x, y=y1)
sns.scatterplot(x=x, y=y2)
sns.scatterplot(x=x, y=y3)
sns.scatterplot(x=x, y=y4)
plt.legend(labels, loc='best')
plt.xticks(rotation=45)
plt.show()
图 18-13 显示了输出。
图 18-13
多行水平条形图
您甚至可以使用 Matplotlib 创建面积图,代码如下:
df2.plot.area()
plt.legend(x, loc='best')
plt.xticks(rotation=45)
plt.show()
图 18-14 显示了输出。
图 18-14
堆积面积图
您可以为数据创建未堆叠的透明面积图,如下所示:
df2.plot.area(stacked=False)
plt.legend(x, loc='best')
plt.xticks(rotation=45)
plt.show()
图 18-15 显示了输出。
图 18-15
堆积面积图
您可以按如下方式创建饼图:
plt.pie(y3, labels=x)
plt.title('Death Toll')
plt.show()
图 18-16 显示了输出。
图 18-16
圆形分格统计图表
您也可以使用地毯图创建 KDE 图,但是对于我们在此示例中使用的数据,这可能没有太大意义。
sns.set_theme(style="ticks")
sns.kdeplot(x=y1)
sns.rugplot(x=y1)
plt.show()
图 18-17 显示了输出。
图 18-17
KDE 绘图
创建动物疾病数据的可视化
您也可以为其他真实数据集创建可视化效果。让我们为动物疾病数据创建可视化。让我们首先从一个在线知识库中阅读它。
df = pd.read_csv("https://github.com/Kesterchia/Global-animal-diseases/blob/main/Data/Outbreak_240817.csv?raw=True")
让我们看看前五名的记录。
df.head()
图 18-18 显示了输出。
图 18-18
动物疾病数据
让我们按如下方式获取有关这些列的信息:
df.info()
输出如下所示:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 17008 entries, 0 to 17007
Data columns (total 24 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Id 17008 non-null int64
1 source 17008 non-null object
2 latitude 17008 non-null float64
3 longitude 17008 non-null float64
4 region 17008 non-null object
5 country 17008 non-null object
6 admin1 17008 non-null object
7 localityName 17008 non-null object
8 localityQuality 17008 non-null object
9 observationDate 16506 non-null object
10 reportingDate 17008 non-null object
11 status 17008 non-null object
12 disease 17008 non-null object
13 serotypes 10067 non-null object
14 speciesDescription 15360 non-null object
15 sumAtRisk 9757 non-null float64
16 sumCases 14535 non-null float64
17 sumDeaths 14168 non-null float64
18 sumDestroyed 13005 non-null float64
19 sumSlaughtered 12235 non-null float64
20 humansGenderDesc 360 non-null object
21 humansAge 1068 non-null float64
22 humansAffected 1417 non-null float64
23 humansDeaths 451 non-null float64
dtypes: float64(10), int64(1), object(13)
memory usage: 3.1+ MB
让我们对列country执行“分组”操作,并计算所有案例的总和,如下所示:
df2 = pd.DataFrame(df.groupby('country').sum('sumCases')['sumCases'])
现在我们来排序选出十大案例。
df3 = df2.sort_values(by='sumCases', ascending = False).head(10)
让我们使用以下代码绘制一个条形图:
df3.plot.bar()
plt.xticks(rotation=90)
plt.show()
图 18-19 显示了输出。
图 18-19
条形图
您可以将索引转换为列,如下所示:
df3.reset_index(level=0, inplace=True)
df3
输出如下所示:
country sumCases
0 Italy 846756.0
1 Iraq 590049.0
2 Bulgaria 453353.0
3 China 370357.0
4 Taiwan (Province of China) 296268.0
5 Egypt 284449.0
6 Iran (Islamic Republic of) 225798.0
7 Nigeria 203688.0
8 Germany 133425.0
9 Republic of Korea 117018.0
我们做一个饼状图如下:
plt.pie(df3['sumCases'],
labels=df3['country'])
plt.title('Death Toll')
plt.show()
图 18-20 显示了输出。
图 18-20
圆形分格统计图表
您可以使用 Seaborn 创建更加美观的条形图,如下所示:
sns.barplot(x='country',
y='sumCases',
data=df3)
plt.xticks(rotation=90)
plt.show()
图 18-21 显示了输出。
图 18-21
带 Seaborn 的条形图
您刚刚学会了可视化现实生活中的动物疾病数据。
摘要
在本章中,您探索了 Seaborn 数据可视化库的更多功能,它是科学 Python 生态系统的一部分。您还学习了如何将真实数据导入 Jupyter 笔记本。您使用了 Matplotlib 和 Seaborn 库来可视化数据。
如你所知,这是本书的最后一章。虽然我们非常详细地探讨了 Matplotlib,但我们只是触及了大量知识和编程 API 的皮毛。现在,您已经掌握了自己进一步探索 Matplotlib 和其他数据可视化库的知识。Python 有许多科学数据的数据可视化库。示例包括 Plotly、Altair 和 Cartopy。掌握了数据可视化的基础知识,就可以愉快地继续深入数据科学和可视化的旅程了!