# Python 数据分析三剑客之 Matplotlib（三）：图例/LaTeX/刻度/子图/补丁等基本图像属性

TRHX

2020-04-14

Python 数据分析 / Matplotlib

字数统计:

3,904字

阅读时长≈

18分

Matplotlib 系列文章：

- Python 数据分析三剑客之 Matplotlib（一）：初识 Matplotlib 与其 matplotibrc 配置文件
- Python 数据分析三剑客之 Matplotlib（二）：文本描述 / 中文支持 / 画布 / 网格等基本图像属性
- Python 数据分析三剑客之 Matplotlib（三）：图例 / LaTeX / 刻度 / 子图 / 补丁等基本图像属性
- Python 数据分析三剑客之 Matplotlib（四）：线性图的绘制
- Python 数据分析三剑客之 Matplotlib（五）：散点图的绘制
- Python 数据分析三剑客之 Matplotlib（六）：直方图 / 柱状图 / 条形图的绘制
- Python 数据分析三剑客之 Matplotlib（七）：饼状图的绘制
- Python 数据分析三剑客之 Matplotlib（八）：等高线 / 等值线图的绘制
- Python 数据分析三剑客之 Matplotlib（九）：极区图 / 极坐标图 / 雷达图的绘制
- Python 数据分析三剑客之 Matplotlib（十）：3D 图的绘制
- Python 数据分析三剑客之 Matplotlib（十一）：最热门最常用的 50 个图表【译文】

专栏：

【NumPy 专栏】【Pandas 专栏】【Matplotlib 专栏】

推荐学习资料与网站：

【NumPy 中文网】【Pandas 中文网】【Matplotlib 中文网】【NumPy、Matplotlib、Pandas 速查表】

    1
    2
    3
    4
    5

    这里是一段防爬虫文本，请读者忽略。
    本文原创首发于 CSDN，作者 TRHX。
    博客首页：https://itrhx.blog.csdn.net/
    本文链接：https://itrhx.blog.csdn.net/article/details/105828143
    未经授权，禁止转载！恶意转载，后果自负！尊重原创，远离剽窃！

## 【1x00】设置图例

`matplotlib.pyplot.legend()` 方法可以为图表设置图例。

基本语法：`matplotlib.pyplot.legend(\*args, \*\*kwargs)`

部分常见参数：

参数 | 描述
--- | ---
loc | 图例在画布中的位置，默认为 best，其他取值： `best`, `upper right`, `upper left`, `lower left` `lower right`, `right`, `center left`, `center right` `lower center`, `upper center`, `center` 也可以用数字 0 - 10 来表示上述位置
bbox_to_anchor | 调整图例在画布中的位置，当 loc 达不到我们想要的效果时，就可以使用该参数 该参数接收一个二元数组 (x, y)，x 用于控制图例的左右移动，值越大越向右边移动 y 用于控制图例的上下移动，值越大，越向上移动
borderaxespad | 图例距离轴之间的距离，float 类型，默认为 0.5
borderpad | 图例边框空白区域大小，float 类型，默认为 0.4
columnspacing | 图例列间距，float 类型，默认为 2.0
edgecolor | 图例边缘线颜色，支持英文颜色名称及其简写、十六进制颜色码等 更多颜色示例参见官网 Color Demo
facecolor | 图例背景颜色，默认继承自 `axes.facecolor` 其他颜色，支持英文颜色名称及其简写、十六进制颜色码等 更多颜色示例参见官网 Color Demo
fancybox | 是否使用圆形框作为图例背景， 默认为 True
fontsize | 图例字体大小，默认为 `medium`，`xx-small`, `x-small`, `small`, `medium` `large`, `x-large`, `xx-large`, `smaller`, `larger` 也可以使用数字来表示字体大小
framealpha | 图例透明度，float 类型，默认为 0.8，取值范围：`[0, 1]`
handleheight | 图例的高度 ，float 类型，默认为 0.7
handlelength | 图例的宽度，float 类型，默认为 2.0
handletextpad | 图例和图例文本之间的水平距离，float 类型，默认为 0.8
labelspacing | 不同图例之间的垂直距离，float 类型，默认为 0.5
shadow | 是否给图例添加阴影效果，默认为 False

### 【1x01】方法一：指定 label 参数

在画图的时候先指定 `label` 标签文本，再调用 `legend()` 方法即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)
    a = [5, 10, 15, 20, 25, 30]
    b = [3, 4, 5, 6, 7, 8]

    plt.plot(a, b, label='图例一')    # 指定 a,b 数据的图例
    plt.plot(x, y, label='图例二')    # 指定 x,y 数据的图例

    plt.legend(loc=2, edgecolor='red', facecolor='#F5F5F5')  # 指定图例位置、边缘线条颜色和背景色
    plt.show()

### 【1x02】方法二：使用 set_label 方法

在画图的时候先使用 `set_label()` 方法指定标签文本，再调用 `legend()` 方法即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)
    a = [5, 10, 15, 20, 25, 30]
    b = [3, 4, 5, 6, 7, 8]

    line1, = plt.plot(a, b)
    line2, = plt.plot(x, y)
    line1.set_label('图例一')    # 指定 a,b 数据的图例
    line2.set_label('图例二')    # 指定 x,y 数据的图例

    plt.legend(loc=2, edgecolor='red', facecolor='#F5F5F5')  # 指定图例位置、边缘线条颜色和背景色
    plt.show()

### 【1x03】方法三：直接使用 legend 方法

直接使用 `legend()` 方法来指定图例标签也可以达到同样效果，图例以列表或者元组形式储存，图例与绘制图形的顺序一一对应。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)
    a = [5, 10, 15, 20, 25, 30]
    b = [3, 4, 5, 6, 7, 8]

    plt.plot(a, b)
    plt.plot(x, y)

    plt.legend(['图例一', '图例二'], loc=2, edgecolor='red', facecolor='#F5F5F5')
    plt.show()

也可以使用两个元组，将绘制的图形和图例一一对应来储存：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)
    a = [5, 10, 15, 20, 25, 30]
    b = [3, 4, 5, 6, 7, 8]

    line1, = plt.plot(a, b)
    line2, = plt.plot(x, y)

    plt.legend((line1, line2), ('图例一', '图例二'), loc=2, edgecolor='red', facecolor='#F5F5F5')
    plt.show()

以上三种方法绘制的图形均一致：

<fancybox>
</fancybox>

## 【2x00】数学公式 LaTeX

LaTeX（LATEX，音译“拉泰赫”）是一种基于 TeX 的排版系统，常用于生成复杂表格和数学公式，Matplotlib 提供了自己的 TeX 表达式解析器，布局引擎和字体，布局引擎基于 Donald Knuth 的 TeX 布局算法改编。使用数学公式时用 `$` 将其包围起来即可。具体的符号与其对应的英文表示参见官方文档：https://matplotlib.org/tutorials/text/mathtext.html

应用举例：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    import numpy as np
    import matplotlib.pyplot as plt

    t = np.arange(0.0, 2.0, 0.01)
    s = np.sin(2*np.pi*t)

    plt.title(r'$\alpha_i > \beta_i$', fontsize=20)
    plt.text(1, -0.6, r'$\sum_{i=0}^\infty x_i$', fontsize=20)
    plt.text(0.6, 0.6, r'$\mathcal{A}\mathrm{sin}(2 \omega t)$', fontsize=20)
    plt.xlabel('time (s)')
    plt.ylabel('volts (mV)')

    plt.plot(t, s)
    plt.show()

<fancybox>
</fancybox>

## 【3x00】调整 x / y 轴刻度和范围

在生成图像时，默认会按照所给的数据均匀设置几个刻度，如果对默认的刻度不满意，则可以使用 `xticks()` 或 `yticks()` 方法指定刻度值。`xlim()` 与 `ylim()` 则可以设置刻度的范围。

基本语法：
`matplotlib.pyplot.xticks([ticks=None, labels=None, \*\*kwargs])`
`matplotlib.pyplot.yticks([ticks=None, labels=None, \*\*kwargs])`

参数 | 描述
--- | ---
ticks | 数组形式的位置列表，即显示第 n 个位置的刻度，可选项，若传递空列表将删除所有 xtick / ytick
labels | 数组形式的值，在对应刻度线显示的标签信息。仅当同时传递了刻度时，才能传递此参数
**kwargs | 其他参数参见 Text

其他参数里面有一个常用的 `rotation` 参数，次参数可以用于设置刻度标签的旋转角度，对于标签太长的可以将其旋转一个角度来显示。

应用举例：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)

    plt.plot(x, y)
    # x 轴每隔三个显示一次刻度，旋转45°显示标签
    plt.xticks(range(2, 26, 3), ('the {} ticks'.format(i) for i in range(2, 26, 3)), rotation=45)

    plt.show()

<fancybox>
</fancybox>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)

    plt.xlim((0, 30))   # 设置 x 轴刻度范围
    plt.plot(x, y)

    plt.show()

<fancybox>
</fancybox>

## 【4x00】画布边框与坐标轴的移动

Matplotlib 所绘制的图表中的每个绘图元素，例如线条 Line2D、文字 Text、刻度等在内存中都有一个对象与之对应。

`matplotlib.pyplot.gca()` 函数用于获取当前的绘图区 `Axes`（Get Current Axes）

`matplotlib.pyplot.gcf()` 函数用于获取当前的画布 `Figure`（Get Current Figure）

例如：`matplotlib.pyplot.plot()` 实际上会通过 `matplotlib.pyplot.gca()` 获得当前的 Axes对象 `ax`，然后再调用 `ax.plot()` 方法实现真正的绘图。我们可以通过这种方法来实现画布边框的隐藏和坐标轴的移动。

应用举例：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    import matplotlib.pyplot as plt
    import numpy as np

    x = np.arange(0, 2*np.pi, np.pi/100)
    y = np.sin(x)
    plt.plot(x, y)

    plt.xlabel('X axis')
    plt.ylabel('Y axis')

    ticks = (0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi)
    labels = ('0', r'$\frac{\pi} {2}$', r'$\pi$', r'$\frac{3\pi} {2}$', r'$2\pi$')
    plt.xticks(ticks, labels)                      # 设置 x 坐标轴显示的数据

    ax = plt.gca()                                 # 获取当前的画布, gca = get current axes
    ax.spines['right'].set_visible(False)          # 设置右边框不显示
    ax.spines['top'].set_visible(False)            # 设置上边框不显示
    # ax.spines['top'].set_color('none')           # 设置颜色为无也可以

    ax.xaxis.set_ticks_position('bottom')          # 设置 x 坐标轴的标签位置
    ax.yaxis.set_ticks_position('left')            # 设置 y 坐标轴的标签位置
    ax.spines['bottom'].set_position(('data', 0))  # 设置 x 轴在 (0, 0) 位置
    ax.spines['left'].set_position(('data', 0))    # 设置 y 轴在 (0, 0) 位置

    plt.show()

<fancybox>
</fancybox>

    1
    2
    3
    4
    5

    这里是一段防爬虫文本，请读者忽略。
    本文原创首发于 CSDN，作者 TRHX。
    博客首页：https://itrhx.blog.csdn.net/
    本文链接：https://itrhx.blog.csdn.net/article/details/105828143
    未经授权，禁止转载！恶意转载，后果自负！尊重原创，远离剽窃！

## 【5x00】创建子图

子图的概念：在同一张画布中创建多个图像，方便对数据进行对比。

### 【5x01】方法一：add_subplot()

首先创建一个画布，然后利用 `add_subplot()` 方法填充子图，该方法接收三个参数，前两个参数表示子图有几行几列，最后一个参数表示第几个子图，如：`fig.add_subplot(221)` 表示总共有两行两列（2x2=4）一共4个子图，当前是第一个子图。若子图大于9个则用逗号隔开即可。

应用举例：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    import numpy as np
    import matplotlib.pyplot as plt

    x = np.arange(100)

    fig = plt.figure(figsize=(12, 6))

    ax1 = fig.add_subplot(221)   # 第 1 个子图
    ax1.plot(x, x)

    ax2 = fig.add_subplot(222)   # 第 2 个子图
    ax2.plot(x, -x)

    ax3 = fig.add_subplot(223)   # 第 3 个子图
    ax3.plot(x, x ** 2)

    ax4 = fig.add_subplot(224)   # 第 4 个子图
    ax4.plot(-x, x ** 2)

    plt.show()

<fancybox>
</fancybox>

### 【5x02】方法二：pyplot.subplot()

`matplotlib.pyplot.subplot()` 方法和 `add_subplot()` 方法有点儿类似，同样接收三个参数，前两个参数表示子图有几行几列，最后一个参数表示第几个子图。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    import numpy as np
    import matplotlib.pyplot as plt

    x = np.arange(100)

    plt.figure(figsize=(12, 6))

    plt.subplot(221)     # 第 1 个子图
    plt.plot(x, x)

    plt.subplot(222)     # 第 2 个子图
    plt.plot(x, x ** 2)

    plt.subplot(223)     # 第 3 个子图
    plt.plot(x, x ** 3)

    plt.subplot(224)     # 第 4 个子图
    plt.plot(x, x ** 4)

    plt.show()

<fancybox>
</fancybox>

### 【5x03】方法三：pyplot.subplots()

`matplotlib.pyplot.subplots()` 函数会将画布分割成指定的列和行，分割后依次在各个区域画图即可。注意与 `matplotlib.pyplot.subplot()` 略有差别。

`fig, axes = plt.subplots` 的意思是：`plt.subplots` 方法会返回一个包含 figure（画布） 和 axes（绘图区） 对象的元组，fig 和 axes 参数分别接收这两个对象，后期对不同绘图区进行处理即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    import numpy as np
    import matplotlib.pyplot as plt

    x = np.arange(100)
    fig, axes = plt.subplots(figsize=(12, 6), nrows=2, ncols=2)  # 将画布分割为2行2列，起始值为0

    axes[0][0].plot(x, x)         # 绘制第1行第1列
    axes[0][1].plot(x, -x)        # 绘制第1行第2列
    axes[1][0].plot(-x, x ** 2)   # 绘制第2行第1列
    axes[1][1].plot(x, -x ** 2)   # 绘制第2行第2列

    plt.show()

<fancybox>
</fancybox>

## 【6x00】填充补丁

`matplotlib.patches` 可用于在画布上填充圆形、长方形、椭圆形、多边形等多种图像补丁。

官方文档：https://matplotlib.org/api/patches_api.html

类 | 描述
--- | ---
matplotlib.patches.Arc(xy, width, height, angle=0.0, theta1=0.0, theta2=360.0, **kwargs) | 椭圆弧
matplotlib.patches.Arrow(x, y, dx, dy, width=1.0, **kwargs) | 箭头
matplotlib.patches.Circle(xy, radius=5, **kwargs) | 圆
matplotlib.patches.Ellipse(xy, width, height, angle=0, **kwargs) | 椭圆
matplotlib.patches.CirclePolygon(xy, radius=5, resolution=20, **kwargs) | 近似多边形的圆形面片
matplotlib.patches.Polygon(xy, closed=True, **kwargs) | 不规则多边形
matplotlib.patches.Rectangle(xy, width, height, angle=0.0, **kwargs) | 矩形
matplotlib.patches.RegularPolygon(xy, numVertices, radius=5, orientation=0, **kwargs) | 正多边形
matplotlib.patches.Shadow(patch, ox, oy, props=None, **kwargs) | 创建给定补丁的阴影
matplotlib.patches.Wedge(center, r, theta1, theta2, width=None, **kwargs) | 楔形

应用举例：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.patches as mpathes

    x = np.arange(0.0, 2.0, 0.01)
    y = np.sin(2*np.pi*x)

    # 获取当前绘图区（gca = Get Current Axes
    ax = plt.gca()

    # 圆形：圆点(0.2, -0.25)，半径0.2，红色
    circle = mpathes.Circle((0.2, -0.25), 0.2, color='r')

    # 长方形：左侧和底部坐标(0.25, 0.75)，宽0.25，高0.15，透明度0.5
    rect = mpathes.Rectangle((0.25, 0.75), 0.25, 0.15, alpha=0.5)

    # 正多边形：中心点坐标(1.0, 0)，顶点数6，中心到每个顶点的距离0.25
    regular_polygon = mpathes.RegularPolygon((1.0, 0), 6, 0.25, color='g')

    # 不规则多边形：polygon_point 为要连接的点的坐标
    polygon_point = [[1.5, -0.75], [1.75, -1], [2.0, 0], [1.5, -0.25]]
    polygon = mpathes.Polygon(polygon_point, color='#FF69B4', alpha=0.3)

    # 椭圆形：中心点坐标(1.25, 0.75)，横轴长度0.4，垂直轴长度0.2
    ellipse = mpathes.Ellipse((1.25, 0.75), 0.4, 0.2, color='y')

    # 将补丁添加到当前绘图区
    ax.add_patch(circle)
    ax.add_patch(rect)
    ax.add_patch(regular_polygon)
    ax.add_patch(polygon)
    ax.add_patch(ellipse)

    plt.xlabel('x axis label')
    plt.ylabel('y axis label')
    plt.grid()
    plt.plot(x, y)
    plt.show()

<fancybox>
</fancybox>

## 【7x00】保存图像

`matplotlib.pyplot.savefig()` 方法可以将绘制的图像保存到本地，支持多种格式：eps, pdf, pgf, png, ps, raw, rgba, svg, svgz。

注意：因为调用 `plt.show()` 函数后，会创建一个新的空白的图片，所以在保存图片时注意要在 `plt.show()` 前调用 `plt.savefig()`

基本语法：`matplotlib.pyplot.savefig(fname, dpi=None, facecolor='w', edgecolor='w', format=None, transparent=False)`

参数 | 描述
--- | ---
fname | str 类型 / 文件路径 / 类似文件的对象 如果未设置格式，则根据 fname 的扩展名（如果有）和 `rcParams[“savefig.format”] = ‘png’` 推断输出格式 如果设置了格式，则它将确定输出格式
dpi | 保存图片的像素（dpi），以每英寸点数为单位。如果为 None，则默认取 `rcParams[’savefig.dpi’] = ‘figure’`
facecolor | 保存图片的画布颜色，默认为 white
edgecolor | 保存图片的边缘颜色，默认为 white
format | 保存图片的格式，未设置则取 fname 中的格式
transparent | 保存图片的背景是否透明

应用举例：

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    import matplotlib.pyplot as plt

    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    x = range(2, 26, 2)
    y = range(0, 12)
    a = [5, 10, 15, 20, 25, 30]
    b = [3, 4, 5, 6, 7, 8]

    line1, = plt.plot(a, b)
    line2, = plt.plot(x, y)

    plt.legend((line1, line2), ('图例一', '图例二'), loc=2, edgecolor='red', facecolor='#F5F5F5')
    plt.savefig('D:\\data\\pic.png', transparent=True)  # 保存为透明文件
    plt.show()

<fancybox>
</fancybox>

    1
    2
    3
    4
    5

    这里是一段防爬虫文本，请读者忽略。
    本文原创首发于 CSDN，作者 TRHX。
    博客首页：https://itrhx.blog.csdn.net/
    本文链接：https://itrhx.blog.csdn.net/article/details/105828143
    未经授权，禁止转载！恶意转载，后果自负！尊重原创，远离剽窃！

您的喜欢是作者写作最大的动力！❤️

- PayPal
- AliPay
- WeChatPay
- QQPay

Donate

最后更新于 2020年8月6日

Matplotlib

图例

LaTeX

子图

补丁

###### 上一页

#### Python 数据分析三剑客之 Matplotlib（四）：线性图的绘制

###### Matplotlib 线性图

###### 下一页

#### Python 数据分析三剑客之 Matplotlib（二）：文本描述/中文支持/画布/网格等基本图像属性

###### Matplotlib 画布 网格

#### 评论

## ๑۩ﺴ TRHX ﺴ۩๑

本文目录
欢迎光临

Hexo QQ 交流群 Telegram 交流群

CSDN 内容合伙人

文章分类

- BLOG
  (4)
- CDN
  (1)
- Hexo
  (9)
- Java
  (1)
- Linux
  (2)
- Markdown
  (2)
- Python 数据分析
  (27)
- Matplotlib
  (11)
- NumPy
  (6)
- Pandas
  (10)
- Python3 学习笔记
  (41)
- 基础学习
  (9)
- 学习经验
  (4)
- 爬虫学习
  (18)
- 爬虫实战
  (10)
- VPS
  (1)
- WEB前端
  (2)
- 图床
  (1)

热门标签
12306 3D图 58同城 Ajax BLOG Beautiful Soup CDN Coding Pages DataFrame Deepin Elicpse GitHub Pages Github Github Pages GroupBy HTTPS Hexo ICP备案 IO操作 Index JDBC JS 预加载 LaTeX Markdown Material X Matplotlib MongoDB MySQL NumPy PEP8 Pandas PicGo Pygame Python Redis SEO SQL Server 2012 SSR Selenium Series Ubuntu User-Agent VMware VPS XPath if语句 input()函数 instant.page jsDelivr lxml matplotibrc pyspider requests spfk urllib while循环 主题个性化 代理 位运算 公安备案 函数 函数应用 分割 切片 列表 判断函数 前程无忧 变量 合并数据集 哔哩哔哩 图例 图床 图形验证码 垃圾 备份 子图 字典 字符串函数 安居客 层级索引 年终总结 广播 异常 技巧 拼接 排序 排序函数 操作列表 散点图 数学函数 数据分裂 数据可视化 数据合并 数据替换 数据类型 数据读写 数据重塑 数组 文件 文件储存 无界面浏览器 时间序列 映射 条件函数 条形图 极区图 极坐标图 柱状图 模块 正则表达式 滑动验证码 点触验证码 爬虫 猫眼电影 瓜子二手车 画布 直方图 矩阵 等值线图 等高线图 算术函数 算术运算 类 索引 线性代数 线性图 统计函数 统计描述 统计计算 继承 编辑器 缺失值 网格 肺炎疫情 虎扑论坛 补丁 豆瓣电影 迭代 雷达图 饼状图
最近在听