当前位置: 代码迷 >> 综合 >> matplotlib--pyplot
  详细解决方案

matplotlib--pyplot

热度:23   发布时间:2023-11-25 15:47:39.0

前言

上一节我们提到,matplotlib绘图有两种风格

  • 显式创建图形与轴空间,并在其上调用方法的OO风格
  • 依靠pyplot自动创建和管理图形和轴,并使用pyplot函数进行绘图的plt风格。

我们上一节中的示例代码一第一种方式为主,这一节我们介绍第二种方式,也就是pyplot

pyplot介绍

matplotlib.pyplot是一些函数的集合,使matplotlibMATLAB一样工作。每个绘图函数对图形(figure)进行一些更改:例如,创建图形,在图形中创建绘图区域,在绘图区域绘制一些线条,使用标签装饰绘图等。

matplotlib.pyplot中,多种状态通过函数之间的调用来保存,以便跟踪诸如当前图形和绘图区域之类的东西。并且绘图函数始终指向当前轴域(请注意,这里和文档中的大多数位置中的『轴域』(axes)是指图形的一部分(坐标轴围成的区域),而不是指代多于一个轴的严格数学术语)。

通过pyplot绘制图像是非常迅速的。plt.plot 是有返回值的,返回的是线的实例列表。只不过这里我们并不需要获得返回值

import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdyFhxV5-1644763593009)(D:\2021-autumn\matplotlib\图像\pyplot\output.png)]

我们明明只传入了一个列表,为什么绘制出了 x 的范围和 y 的范围呢?如果我们向plot中只传入了一个列表或数组,matplotlib会认为这个序列代表的是 y 的值,并且为我们自动产生 x 的值。因为 python 中的范围是从 0 开始的,且默认的 x 向量与 y 向量具有相同的长度。因此,生成的 x 是[0,1,2,3]。

plot是一个通用函数,并且可以接受任意数量的参数。如果要绘制 x 和 y,我们可以写成

plt.plot([1, 2, 3, 4], [1, 4, 9, 16])

在这里插入图片描述

  • plot只能画二维图像,我们绘制 x-y 时需要成对输入(每一对是一条线)。如果有单个的序列,则会被认为是 y 的值,并且自动生成 x。

    plt.plot([1, 2, 3, 4], [1, 4, 9, 16],[1, 2, 3, 4],[1, 2, 3, 4])
    

在这里插入图片描述

设置plot的风格

对于每一对 x,y 参数,都有可选的第三个参数(格式字符串)来控制颜色和绘制的线的类型。格式字符串的字母和符号来自 MATLAB,并且将颜色字符串与线型字符串连接在一起。默认格式字符串为"b-",它是一条蓝色实线。例如,要绘制红色圆圈,我们可以写成

plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')
plt.axis([0, 6, 0, 20])
plt.show()

在这里插入图片描述
例子中的axis()函数的输入是[xmin, xmax, ymin, ymax],用于指定轴域的可视范围。

如果matplotlib仅限于使用列表,它对于数字处理是相当无用的。通常,我们将会使用numpy数组。事实上,所有序列都会在内部被转换成numpy数组。

下面的例子演示了使用数组在一个函数调用中绘制具有不同格式样式的几条线。

import numpy as np# evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()

在这里插入图片描述

通过关键词字符串绘制

在某些情况下,数据的格式允许我们使用字符串访问特定的变量。比如numpy.recarray或者pandas.DataFrame

Matplotlib允许我们使用data关键字参数提供这样的对象。如果提供,那么我们可以用这些变量对应的字符串生成图形。

data = {
    'a': np.arange(50),'c': np.random.randint(0, 50, 50),'d': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100plt.scatter('a', 'b', c='c', s='d', data=data) #c:color s:size
plt.xlabel('entry a')
plt.ylabel('entry b')
plt.show()

在这里插入图片描述

通过类别变量绘图

names = ['group_a', 'group_b', 'group_c']
values = [1, 10, 100]plt.figure(figsize=(9, 3))plt.subplot(131)
plt.bar(names, values)
plt.subplot(132)
plt.scatter(names, values)
plt.subplot(133)
plt.plot(names, values)
plt.suptitle('Categorical Plotting')
plt.show()

在这里插入图片描述

plt.bar()函数绘制条形图,各种参数如下(上面的names是x参数)

参数 说明 类型
x x坐标 int,float
height 条形的高度 int,float
width 线条的宽度 0~1,默认是0.8
botton 条形的起始位置 也就是y轴的起始坐标
align 条形的中心位置 “center”,"lege"边缘
color 条形的颜色 “r”,“b”,“g”,“#123465",默认的颜色是“b”
edgecolor 边框的颜色 同上
linewidth 边框的宽度 像素,默认无,int
tick_label 下标的标签 可以是元组类型的字符组合
log y轴使用科学计算法表示 bool
orientation 是竖直条还是水平条 竖直:“vertical”,水平条:“horizontal”

控制线条属性

线条有很多可以控制的属性:线宽,线条样式,反锯齿化等。下面有几种可以控制线条属性的方式

  • 使用关键词参数

    plt.plot(x, y, linewidth=2.0)
    
  • 使用二维直线实例的设定方法。plot 返回二维直线对象的列表,例如 line1,line2 = plot(x1,y1,x2,y2)。在下面的代码中,我们假设只有一行,因此返回的列表长度为1(也就是只返回一个二维直线实例)。我们对line使用元组解构,得到该列表的第一个元素:

    line, = plt.plot(x, y, '-') #该 line 是一个 Line2D 实例
    line.set_antialiased(False) # turn off antialiasing
    
    x = [1, 2, 3]
    y = [1, 2, 3]
    line = plt.plot(x, y) #该 line 是一个列表
    print(type(line))
    >> <class 'list'>
    print(line)
    >> [<matplotlib.lines.Line2D object at 0x000001E7FF9495B0>]x = [1, 2, 3]
    y = [1, 2, 3]
    line, = plt.plot(x, y) #该 line 是一个 Line2D 实例
    print(type(line))
    >> <class 'matplotlib.lines.Line2D'>
    print(line)
    >> Line2D(_line0)
    
  • 使用setp()命令。下面的示例使用 MATLAB 风格的命令来设置线条列表上的多个属性。setp()显而易见地对对象列表或者单个对象工作。我们可以使用python关键词参数或者MATLAB风格的字符串/值对:

    lines = plt.plot(x1, y1, x2, y2) #线的对象列表
    # use keyword arguments
    plt.setp(lines, color='r', linewidth=2.0)
    # or MATLAB style string value pairs
    plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
    

下面是可用的二维直线的属性

属性 值类型
alpha 浮点值
animated [True / False]
antialiased or aa [True / False]
clip_box matplotlib.transform.Bbox 实例
clip_on [True / False]
clip_path Path 实例, Transform,以及Patch实例
color or c 任何 matplotlib 颜色
contains 命中测试函数
dash_capstyle ['butt' / 'round' / 'projecting']
dash_joinstyle ['miter' / 'round' / 'bevel']
dashes 以点为单位的连接/断开墨水序列
data (np.array xdata, np.array ydata)
figure matplotlib.figure.Figure 实例
label 任何字符串
linestyle or ls [ '-' / '--' / '-.' / ':' / 'steps' / ...]
linewidth or lw 以点为单位的浮点值
lod [True / False]
marker [ '+' / ',' / '.' / '1' / '2' / '3' / '4' ]
markeredgecolor or mec 任何 matplotlib 颜色
markeredgewidth or mew 以点为单位的浮点值
markerfacecolor or mfc 任何 matplotlib 颜色
markersize or ms 浮点值
markevery [ None / 整数值 / (startind, stride) ]
picker 用于交互式线条选择
pickradius 线条的拾取选择半径
solid_capstyle ['butt' / 'round' / 'projecting']
solid_joinstyle ['miter' / 'round' / 'bevel']
transform matplotlib.transforms.Transform 实例
visible [True / False]
xdata np.array
ydata np.array
zorder 任何数值

要获取一个线的可设置的属性列表,可以使用line或lines作为参数调用setp函数

In [69]: lines = plt.plot([1, 2, 3])In [70]: plt.setp(lines)alpha: floatanimated: [True | False]antialiased or aa: [True | False]...snip

处理多个图形和轴域

MATLABpyplot具有当前图像和当前轴域的概念。所有的绘图函数都应用在当前的轴域上。函数gca()返回当前轴域(一个matplotlib.axes.Axes实例),函数gcf()返回当前图像(一个matplotlib.figure.Figure实例)。通常,你不必担心这一点,因为它都是在幕后处理。 下面是一个创建两个子图的脚本。

def f(t):return np.exp(-t) * np.cos(2*np.pi*t)t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)plt.figure()
plt.subplot(211) #两行一列的第一个图
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')plt.subplot(212) #两行一列的第二个图
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

在这里插入图片描述

figure函数的调用是可选的,因为如果不存在图像的话会创建一个图像。就像没有轴域存在的时候会自动创建一个一样(等价于显式调用subplot函数)。subplot函数调用指定 numrows(行数),numcols(列数),plot_number(图的序号)。plot_number的范围是1~numrows*numcols。 如果numrows * numcols <10,则subplot命令中的逗号是可选的。 因此,子图subplot(211)subplot(2, 1, 1)相同。我们可以创建任意数量的子图和轴。如果要手动放置轴域,即不在矩形网格上,请使用axes()命令,该命令允许你将axes([left, bottom, width, height])指定为位置,其中所有值都使用小数(0 到 1)坐标。 手动放置轴域的示例请参见pylab_examples示例代码:axes_demo.py,具有大量子图的示例请参见pylab_examples示例代码:subplots_demo.py

我们可以通过利用递增的图像序号,来多次调用figure函数,从而创建多个图像。当然,每个图都可以包含任意多的轴域和子图:

import matplotlib.pyplot as plt
plt.figure(1)                # the first figure
plt.subplot(211)             # the first subplot in the first figure
plt.plot([1, 2, 3])
plt.subplot(212)             # the second subplot in the first figure
plt.plot([4, 5, 6])plt.figure(2)                # a second figure
plt.plot([4, 5, 6])          # creates a subplot() by defaultplt.figure(1)                # figure 1 current; subplot(212) still current
plt.subplot(211)             # make subplot(211) in figure1 current
plt.title('Easy as 1, 2, 3') # subplot 211 title

在这里插入图片描述
在这里插入图片描述

我们可以使用clf清除当前图形,使用cla清除当前轴域。

如果你正在制作大量的图形,你需要注意一件事:在一个图形用close()显式关闭之前,该图所需的内存不会完全释放。 删除对图形的所有引用,或使用窗口管理器杀死屏幕上出现的图形的窗口是不够的,因为在调用close()之前,pyplot会维护内部引用

处理文本

使用text可以在任何位置添加文本。xlabel()ylabel()title()用于在指定的位置添加文本。

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=1, facecolor='g', alpha=0.75)plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

在这里插入图片描述

  • plt.text用法介绍
    • 坐标是根据坐标轴确定的二维空间确定的位置,而不是根据图的尺寸来定义的
# 第一个参数是x轴坐标
# 第二个参数是y轴坐标
# 第三个参数是要显式的内容
# alpha 设置字体的透明度
# family 设置字体
# size 设置字体的大小
# style 设置字体的风格
# wight 字体的粗细
# bbox 给字体添加框,alpha 设置框体的透明度, facecolor 设置框体的颜色

所有的text()命令返回一个matplotlib.text.Text实例。 与上面一样,我们可以通过将关键字参数传递到text函数或使用setp()来自定义属性:

t = plt.xlabel('my data', fontsize=14, color='red')

在文本中使用数学表达式

matplotlib在任何文本表达式中接受 TeX 方程表达式。 例如,要在标题中写入表达式,可以编写一个由 $ 包围的 TeX 表达式:

plt.title(r'$\sigma_i=15$')

标题字符串之前的r很重要 - 它表示该字符串是一个原始字符串,而不是将反斜杠作为 python 转义处理。matplotlib有一个内置的 TeX 表达式解析器和布局引擎,并且自带了自己的数学字体。因此,我们可以跨平台使用数学文本,而无需安装 TeX。

文本标注

上面的text()基本命令将文本放置在轴域的任意位置。 文本的一个常见用法是对图的某些特征执行标注,而annotate()方法提供一些辅助功能,使标注变得容易。 在标注中,有两个要考虑的点:由参数xy表示的标注位置和xytext表示的文本位置。 这两个参数都是(x, y)元组。

ax = plt.subplot()t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),arrowprops=dict(facecolor='black', shrink=0.05),)plt.ylim(-2, 2)
plt.show()

在这里插入图片描述

在本基本样例中,xy(箭头提示)和xytext位置(文本位置)都在数据坐标中。还有其他很多种坐标系可供选择。详细信息请参阅标注文本和标注轴域。 更多示例可以在pylab_examples示例代码:annotation_demo.py中找到。

对数和其它非线性轴

matplotlib.pyplot不仅支持线性轴刻度,还支持对数和对数刻度。 如果数据跨越许多数量级,通常会使用它。 更改轴的刻度很容易:

plt.xscale('log')

下面示例显示了四个图,具有相同数据和不同刻度的y轴。

# Fixing random state for reproducibility
np.random.seed(19680801)# make up some data in the open interval (0, 1)
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))# plot with various axes scales
plt.figure()# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthresh=0.01)
plt.title('symlog')
plt.grid(True)# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# Adjust the subplot layout, because the logit one may take more space
# than usual, due to y-tick labels like "1 - 10^{-3}"
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,wspace=0.35)plt.show()

在这里插入图片描述