Python数据分析利器:NumPy、pandas与Matplotlib库---之Matplotlib
第1行代码中的plt.subplots(nrows=2,ncols=2)(也可以简写为plt.subplots(2,2))就表示绘制2行2列共4张子图,它会返回两个内容:fig(画布)和axes(子图集合,以数组形式存储各张子图)。例如,subplot(221)表示绘制2行2列的子图(共4张子图),当前绘制的是第1张子图,如下图所示。从前面的介绍可知,可以在一张图表里绘制两条线,但如果两条线的取值
2.3 Matplotlib库基础
Matplotlib库是一个非常出色的数据可视化工具包,它也是Anaconda自带的,无须单独安装。本节就来讲解Matplotlib库的基本用法和常用技巧。
2.3.1 基本图表绘制
在绘制图表之前要先引入Matplotlib库,相应的代码通常写成“import matplotlib.pyplotas plt”,这是为了给库设置简称,之后使用plt作为前缀调用所需函数即可绘制图表。
例如,plt.plot()函数用于绘制折线图,plt.bar()函数用于绘制柱形图,plt.pie()函数用于绘制 饼图等。本小节以折线图、柱形图、散点图和直方图为例讲解图表的基本绘制方法。
1.绘制折线图
使用plt.plot()函数可以绘制折线图,演示代码如下。
import matplotlib.pyplot as plt
x = [1, 2, 3]
y = [2, 4, 6]
plt.plot(x, y) # 绘制折线图
plt.show() # 展示图形 注意最后要用plt.show()来展示绘制效果
如果想让x和y之间在数学上存在关联,但列表又不太容易进行数学运算,就可以通过NumPy库引入一维数组进行数学运算,代码如下
import numpy as np
import matplotlib.pyplot as plt
x1 = np.array([1, 2, 3])
# 第1条线:y = x + 1
y1 = x1 + 1
plt.plot(x1, y1) # 使用默认参数绘制
# 第2条线:y = x*2
y2 = x1 * 2
# color为颜色;linewidth为线宽,单位为像素;linestyle为线型,默认为实线,“--”表示虚线
plt.plot(x1, y2, color='red', linewidth=3, linestyle='--')
plt.show()
这里利用NumPy库生成一个一维数组x1,并利用数组的可运算性生成y1和y2,将两条线绘制在一张图表上
2.绘制柱形图
使用plt.bar()函数可以绘制柱形图,演示代码如下。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [5, 4, 3, 2, 1]
plt.bar(x, y)
plt.show()
3.绘制散点图
使用plt.scatter()函数可以绘制散点图,演示代码如下。
import matplotlib.pyplot as plt
import numpy as np
x = np.random.rand(10)
y = np.random.rand(10)
plt.scatter(x, y)
plt.show()
4.绘制直方图
直方图分为频数直方图和频率直方图,横坐标为相关数据,纵坐标为该数据出现的频数或频率。使用plt.hist()函数可以绘制直方图,演示代码如下。
import matplotlib.pyplot as plt
import numpy as np
# 随机生成10000个服从标准正态分布的数据
data = np.random.randn(10000)
# 绘制频数直方图:bins为颗粒度,即直方图的柱形数量;edgecolor为柱形的边框颜色
plt.hist(data, bins=40, edgecolor='black')
plt.show()
其中x轴表示随机生成的数据,y轴则表示该数据出现的次数,即频数。
此外,若想绘制频率直方图,可以设置density参数为1。
补充知识点:用pandas库绘制图表对于用pandas库创建的数据表,有更便捷的方法来绘制图表,不过这种方法在本质上还是通过pandas库调用Matplotlib库,演示代码如下。
# 这种方法只适用于pandas库创建的DataFrame,不适用于NumPy库创建的数组
import pandas as pd
df = pd.DataFrame(data) # 将前面绘制直方图时使用的data数组转换成DataFrame格式
df.hist(bins=40, edgecolor='black')
array([[<Axes: title={'center': '0'}>]], dtype=object)
这种方法可以快速绘制和之前一样的直方图。因为这里的df只有一列,所以可以直接写df,如果df有多列,那么就需要指明用哪一列绘制直方图,写成df['列名'].hist()。该技巧在14.3.2小节中绘制电影评分频数直方图时会用到。
除了df.hist()函数,还可以使用pandas库中的通用绘图代码绘制图表,代码如下。
df.plot(kind='hist')
这里通过设置kind参数为hist来绘制直方图。通过更改kind参数,还可以快速绘制其他类型的图表。先创建一个DataFrame格式的二维表格df,代码如下。
import pandas as pd
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用于正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False
df = pd.DataFrame([[8000, 6000], [7000, 5000], [6500, 4000]],
columns=['人均收入', '人均支出'], index=['北京', '上海', '广州'])
df
同时绘制折线图和柱形图的代码如下。
df['人均收入'].plot(kind='line') # 设置kind为line表示绘制折线图,不设置则默认绘制折线图
df['人均收入'].plot(kind='bar') # 设置kind为bar表示绘制柱形图
因为df有多列,所以要先通过df['列名']的方式指明需要绘图的列数据
此外,设置kind参数为pie,则可以绘制饼图,如下左图所示;设置kind参数为box,则可以绘制箱体图,如下右图所示。
2.3.2 数据可视化
常用技巧本小节主要讲解数据可视化过程中常用的一些技巧,包括添加文字说明、添加图例、设置双坐标轴、设置图表大小、设置x轴刻度的角度、解决中文显示问题、绘制多图。
1.添加文字说明
使用plt.title()函数为图表添加标题,使用plt.xlabel()和plt.ylabel()函数分别为x轴和y轴添加标签,代码如下。
import matplotlib.pyplot as plt
x = [1, 2, 3]
y = [2, 4, 6]
plt.plot(x, y)
plt.title('TITLE') # 添加图表标题
plt.xlabel('X') # 添加x轴标签
plt.ylabel('Y') # 添加y轴标签
plt.show() # 显示图表
2.添加图例
使用plt.legend()函数给图表添加图例,添加前需要设置好label(标签)参数,代码如下。
import numpy as np
import matplotlib.pyplot as plt
# 第1条线:设置label(标签)为“y = x + 1”
x1 = np.array([1, 2, 3])
y1 = x1 + 1
plt.plot(x1, y1, label='y = x + 1')
# 第2条线:设置label(标签)为“y = x*2”
y2 = x1*2
plt.plot(x1, y2, color='red', linestyle='--', label='y = x*2')
plt.legend(loc='upper left') # 设置图例位置为左上角
plt.show()
若要修改图例的位置,可以修改loc参数的值,如'upperright'代表右上角,'lower right'代表右下角。
3.设置双坐标轴
从前面的介绍可知,可以在一张图表里绘制两条线,但如果两条线的取值范围相差较大,那么绘制出的图表效果会不美观,此时需要采用双坐标轴来呈现图表,即为两条线各自绘制y轴。在绘制第1条线的代码之后添加如下代码,即可设置双坐标轴。 plt.twinx()
需要注意的是,如果设置了双坐标轴,那么每绘制一次图表就得添加一次图例,而不能在最后统一添加图例。这里以y=x和y=x2为例,演示如何设置双坐标轴,代码如下。
import numpy as np
import matplotlib.pyplot as plt
# 第1条线:设置label(标签)为“y = x”
x1 = np.array([10, 20, 30])
y1 = x1
plt.plot(x1, y1, color='red', linestyle='--', label='y = x')
plt.legend(loc='upper left') # 设置该图表图例在左上角
plt.twinx() # 设置双坐标轴
# 第2条线:设置label(标签)为“y = x^2”
y2 = x1*x1
plt.plot(x1, y2, label='y = x^2')
plt.legend(loc='upper right') # 设置该图表图例在右上角
plt.show()
4.设置图表大小
plt.rcParams['figure.figsize'] = (8, 6)
第1个元素代表长,第2个元素代表宽,这里的数字8和6分别代表800像素和600像素。
5.设置x轴刻度的角度
如果x轴因为刻度内容较多,导致刻度太密,不便于阅读,可以通过设置刻度的角度来进行调节,代码如下。其中45表示45°,可以根据需要更改为其他数值。
plt.xticks(rotation=45)
6.解决中文显示问题
注意:在使用 Matplotlib 绘图时,出现“UserWarning: Glyph missing from font”警告,通常是因为默认字体不支持中文字符。由于更改字体会导致显示不出负号“-”,需要将配置文件中的axes.unicode_minus参数设置为False。为了解决这个问题,可以通过以下几种方法设置合适的字体:
- 设置全局字体:在绘图代码中添加以下两行代码,以设置中文字体为黑体(SimHei)并解决负号显示问题:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用于正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用于正常显示负号,解决负号“-”显示为方块的问题
- 修改配置文件:如果希望永久解决这个问题,可以直接修改 Matplotlib 的配置文件
matplotlibrc
。找到该文件并将font.family
设置为SimHei
,这样每次绘图时都能自动使用该字体。
- 找到配置文件: 首先,你需要找到当前使用的
matplotlibrc
文件的位置。
import matplotlib
print(matplotlib.matplotlib_fname())
- 备份配置文件: 在修改之前,建议备份原有的
matplotlibrc
文件,以防需要恢复到原始设置。 - 修改配置文件: 打开
matplotlibrc
文件,你可以使用任何文本编辑器进行修改。在文件中找到以下行:
#font.family: sans-serif
去掉前面的 #
号(如果有的话),然后将其修改为:
font.family: SimHei
另外,为了确保中文字符和负号能够正确显示,也可以添加或修改以下行:
font.sans-serif: SimHei, DejaVu Sans, Liberation Sans, Arial, sans-serif
axes.unicode_minus: False
- 保存并关闭文件: 保存修改后的
matplotlibrc
文件并关闭文本编辑器。 - 测试修改效果: 在 Python 环境中运行一段绘图代码,检查中文是否能够正确显示。例如:
python
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [4, 5, 6])
plt.title("测试标题")
plt.xlabel("横轴")
plt.ylabel("纵轴")
plt.show()
通过以上步骤,你可以将 Matplotlib 的默认字体设置为黑体,从而解决中文显示问题。如果你使用的是非 Windows 系统,可能需要将 SimHei
替换为系统中可用的其他中文字体。
- 安装中文字体:如果系统中没有 SimHei 字体,可以下载并安装该字体。将字体文件放入 Matplotlib 的字体库路径中,通常路径为:
<your_python_env>/Lib/site-packages/matplotlib/mpl-data/fonts/ttf
通过以上方法,应该能够解决中文字符显示的问题,避免出现方框或乱码的情况。
7.绘制多图
有时我们需要在一张画布上绘制多个图表,如下图所示。这种效果可以利用Matplotlib库的当前图形(figure)和当前轴(axes)概念来实现,这两个概念对应的就是当前画布及当前子图,在一张画布(figure)上可以绘制多张子图(axes)。绘制多图通常采用subplot()函数或subplots()函数。
首先讲解subplot()函数,它的参数通常表示为一个3位整数,该整数的各位数字分别代表子图的行数、列数及当前子图的序号。例如,subplot(221)表示绘制2行2列的子图(共4张子图),当前绘制的是第1张子图,如下图所示。
import matplotlib.pyplot as plt
# 绘制第1张子图:折线图
ax1 = plt.subplot(221)
plt.plot([1, 2, 3], [2, 4, 6])
# 绘制第2张子图:柱形图
ax2 = plt.subplot(222)
plt.bar([1, 2, 3], [2, 4, 6])
# 绘制第3张子图:散点图
ax3 = plt.subplot(223)
plt.scatter([1, 3, 5], [2, 4, 6])
# 绘制第4张子图:直方图
ax4 = plt.subplot(224)
plt.hist([2, 2, 2, 3, 4])
(array([3., 0., 0., 0., 0., 1., 0., 0., 0., 1.]),
array([2. , 2.2, 2.4, 2.6, 2.8, 3. , 3.2, 3.4, 3.6, 3.8, 4. ]),
<BarContainer object of 10 artists>)
每次在新的子图上画图时,都得调用subplot()
函数,例如,第4张子图就得写成ax4=plt.subplot(224),那么能不能一次性生成多张子图呢?这就需要用到subplots()函数,代码如下。
fig, axes = plt.subplots(nrows=2, ncols=2)
ax1, ax2, ax3, ax4 = axes.flatten()
subplots()函数主要有两个参数:nrows表示行数,ncols表示列数。第1行代码中的plt.subplots(nrows=2,ncols=2)(也可以简写为plt.subplots(2,2))就表示绘制2行2列共4张子图,它会返回两个内容:fig(画布)和axes(子图集合,以数组形式存储各张子图)。
第2行代码使用flatten()函数将子图集合展开,从而获得各张子图,此处已知是4张子图,所以分别用“ax1,ax2,ax3,ax4”代表4张子图,之后即可在这4张子图中画图,演示代码如下。这里采用subplots()函数的简写方式,并通过figsize参数设置图表尺寸为1000×800像素。
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
ax1, ax2, ax3, ax4 = axes.flatten()
ax1.plot([1, 2, 3], [2, 4, 6]) # 绘制第1张子图
ax2.bar([1, 2, 3], [2, 4, 6]) # 绘制第2张子图
ax3.scatter([1, 3, 5], [2, 4, 6]) # 绘制第3张子图
ax4.hist([2, 2, 2, 3, 4]) # 绘制第4张子图
,使用subplot()函数在画布中绘制图表时,每次都要调用该函数来指定位置;而使用subplots()函数只需调用生成子图的ax,就可以一次生成多张子图
更多推荐
所有评论(0)