Python中Matplotlib库的使用(二)—— Pyplot模块

Pyplot模块

简介

matplotlib.pyplot 是一个函数集合,使得Matplotlib的使用方式类似于MATLAB。每个pyplot函数都会对图形进行一些修改,例如创建图形、在图形中创建绘图区域、在绘图区域中绘制线条、为图形添加标签等。

matplotlib.pyplot中,各种状态在函数调用之间被保留,以便它能够跟踪诸如当前图形、绘图区域等,而绘图函数会指向当前坐标轴(请注意,这里和文档中大多数地方所说的"axes"指的是图形的坐标轴部分,而不是严格的数学术语,表示多个轴)。

使用pyplot生成可视化非常快速:

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

之所以x轴范围是0-3,而y轴范围是1-4,是因为如果向plot提供一个单一的列表或数组,Matplotlib会假设它是一系列的y值,并自动为你生成x值。由于Python的范围从0开始,所以默认的x向量与y的长度相同,但从0开始;因此,x的数据是[0, 1, 2, 3]。

plot是一个多功能的函数,可以接受任意数量的参数。例如,要绘制x和y的关系,你可以这样写:

python 复制代码
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])

通过这段代码,你可以看到如何使用pyplot绘制简单的线图。首先导入matplotlib.pyplot,然后使用plt.plot()绘制数据,最后通过plt.show()显示图形。在这个示例中,我们绘制了一个包含指定y值的线图,自动生成对应的x值。这个过程非常简洁和快速。

格式化绘图样式

对于每一组x、y参数,都有一个可选的第三个参数,它是格式字符串,用于指示绘图的颜色线条类型。格式字符串的字母和符号来自于MATLAB,你可以将颜色字符串与线条样式字符串连接在一起。默认的格式字符串是'b-',表示实心的蓝色线条。例如,要绘制带有红色圆点的图形,你可以使用以下代码:

python 复制代码
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.pyplot.plot --- Matplotlib 3.7.2 documentation

如果Matplotlib仅限于使用列表进行操作,那么它在数值处理方面将会相当无用。通常,您会使用NumPy数组。实际上,所有的序列在内部都会被转换为NumPy数组。下面的示例演示了如何在一个函数调用中使用数组来绘制具有不同格式样式的多条线:

python 复制代码
import matplotlib.pyplot as plt
import numpy as np

# 设置全局字体为支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定微软雅黑或其他中文字体

# 创建一个均匀取样的时间间隔,间隔为0.2
t = np.arange(0., 5., 0.2)

# 使用不同格式样式绘制多条线
plt.plot(t, t, 'r--', label='线性')      # 红色虚线
plt.plot(t, t**2, 'bs', label='平方')   # 蓝色方块
plt.plot(t, t**3, 'g^', label='立方')   # 绿色三角形

# 设置x轴标签和y轴标签
plt.xlabel('X轴')
plt.ylabel('Y轴')

# 添加图例
plt.legend()

# 添加标题
plt.title('不同格式样式的多条线')

# 显示图形
plt.show()

使用关键字字符串进行绘图

在某些情况下,可能拥有的数据格式允许通过字符串访问特定的变量。例如,使用numpy.recarraypandas.DataFrame

Matplotlib允许通过data关键字参数提供这样的数据对象。当使用关键字字符串绘制图形时,可以直接使用数据对象中的变量名作为参数,而不需要提前提取出对应的数据数组。

示例如下:

python 复制代码
import matplotlib.pyplot as plt
import numpy as np

# 设置全局字体为支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定微软雅黑或其他中文字体

# 创建一个包含数据的字典
data = {'sales': np.array([100, 150, 200, 180, 120]),
        'profit': np.array([10, 25, 30, 20, 15]),
        'month': ['Jan', 'Feb', 'Mar', 'Apr', 'May']}

# 使用关键字字符串绘制柱状图
plt.bar('month', 'sales', data=data, color='blue', label='销售额')
plt.bar('month', 'profit', data=data, color='orange', label='利润')

# 设置x轴标签和y轴标签
plt.xlabel('月份')
plt.ylabel('金额')

# 添加图例
plt.legend()
# 添加标题
plt.title('销售额和利润')
# 显示图形
plt.show()

在这个示例中,我们创建了一个包含销售额、利润和月份的数据字典data。使用关键字字符串'month''sales''profit',我们直接在plt.bar()函数中引用了这些变量名。这样的话,Matplotlib会自动从data字典中获取对应的数据数组,并将它们用于绘制柱状图。通过这种方式,可以更加方便地从数据对象中提取数据并进行绘图,减少了额外的变量处理步骤。

使用分类变量绘图

使用分类变量绘图是一种在图形中展示不同类别之间数据关系的方法。分类变量通常表示一组离散的标签或类别,而不是连续的数值。Matplotlib允许直接将这些分类变量传递给绘图函数,以便在图形中呈现这些类别之间的数据。

python 复制代码
import matplotlib.pyplot as plt

# 分类变量列表
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()

在这个示例中,我们有一个包含三个分类变量的列表names,分别表示"group_a"、"group_b"和"group_c"。对应的数值列表values表示每个类别的数据。通过直接将这些分类变量传递给plt.bar()plt.scatter()plt.plot()等函数,我们可以在不同的子图中呈现不同类型的图形。

分类变量绘图的好处在于它可以帮助我们更清楚地比较不同类别之间的数据差异。例如,在上述示例中,我们可以看到"group_c"的数值明显大于其他两个组,这种视觉上的比较使得数据趋势更加明显。

控制线条属性

线条有许多可以设置的属性,例如线宽、虚线样式、抗锯齿等等;详见matplotlib.lines.Line2D。有几种方法可以设置线条的属性:

  1. 使用关键字参数:

    python 复制代码
    plt.plot(x, y, linewidth=2.0)

    plot函数中使用关键字参数来设置线条属性。

  2. 使用Line2D实例的设置方法。plot函数返回一个Line2D对象的列表;例如,line1, line2 = plt.plot(x1, y1, x2, y2)。在下面的代码中,我们假设只有一条线,因此返回的列表长度为1。我们使用元组解包,将列表的第一个元素赋给line

    python 复制代码
    line, = plt.plot(x, y, '-')
    line.set_antialiased(False)  # 关闭抗锯齿

    使用Line2D实例的setter方法来设置属性。

  3. 使用setp函数。下面的示例使用MATLAB风格的函数来在一组线条上设置多个属性。setp函数可以透明地处理对象列表或单个对象。你可以使用Python关键字参数或MATLAB风格的字符串/值对:

    python 复制代码
    lines = plt.plot(x1, y1, x2, y2)
    # 使用关键字参数
    plt.setp(lines, color='r', linewidth=2.0)
    # 或者使用MATLAB风格的字符串/值对
    plt.setp(lines, 'color', 'r', 'linewidth', 2.0)

在绘制图形时,通过设置这些线条属性,可以调整线条的样式、颜色、宽度等,以满足不同的绘图需求。无论是单一属性还是多个属性的组合,都可以根据需要灵活地控制线条的外观。

例如:

python 复制代码
import matplotlib.pyplot as plt
import numpy as np

# 创建一些示例数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)

# 绘制三条不同样式的线
plt.plot(x, y1, label='sin(x)', linewidth=2.0, linestyle='-', color='blue')
plt.plot(x, y2, label='cos(x)', linewidth=2.0, linestyle='--', color='red')
plt.plot(x, y3, label='tan(x)', linewidth=2.0, linestyle=':', color='green')

# 添加标签、标题和图例
plt.xlabel('x')
plt.ylabel('y')
plt.title('different line styles')
plt.legend()

# 显示图形
plt.show()

在这个示例中,使用了三种不同的线条样式来绘制三条曲线:实线、虚线和点线。通过设置linestyle参数,color参数和linewidth参数我们可以控制线条的样式,颜色以及宽度。

使用多个图形和轴

MATLAB和pyplot都有"当前图形"和"当前坐标轴"的概念。所有的绘图函数都作用于当前的坐标轴。

下面是一个脚本,用于创建两个子图:

python 复制代码
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调用指定了numrowsnumcolsplot_number,其中plot_number的取值范围从1到numrows * numcols。如果numrows * numcols小于10,则subplot调用中的逗号是可选的。因此,subplot(211)等同于subplot(2, 1, 1)

你可以创建任意数量的子图和坐标轴。如果你想手动放置一个坐标轴,即不使用矩形网格,可以使用axes函数,它允许你指定位置为axes([left, bottom, width, height]),其中所有的值都是分数(从0到1)的坐标。

可以通过使用多个figure调用并增加图形编号来创建多个图形。当然,每个图形可以包含多个坐标轴和子图:

python 复制代码
import matplotlib.pyplot as plt
plt.figure(1)                # 第一个图形
plt.subplot(211)             # 第一个图形的第一个子图
plt.plot([1, 2, 3])
plt.subplot(212)             # 第一个图形的第二个子图
plt.plot([4, 5, 6])

plt.figure(2)                # 第二个图形
plt.plot([4, 5, 6])          # 默认情况下创建一个子图()

plt.figure(1)                # 第一个图形仍然是当前的;
                             # 第一个图形的subplot(212)仍然是当前的
plt.subplot(211)             # 在第一个图形中创建subplot(211)作为当前的
plt.title('Easy as 1, 2, 3') # 给subplot 211 添加标题
plt.show()

文本和数学表达式

在Matplotlib的pyplot中,可以使用text函数在图形中添加文本注释,还可以使用数学表达式来显示数学符号和公式。

python 复制代码
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=True, 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()

使用数学表达式时,要点如下:

  1. 使用r''(原始字符串)将字符串标记为包含数学表达式。
  2. 使用$符号将数学表达式括起来。例如,r'$x$'表示数学符号x。
  3. 使用\符号来插入特殊字符,如下划线、上标和下标。例如,r'$y = x^2$'表示公式y=x²。
  4. 使用\text{}来插入普通文本。例如,r'$\text{Sine Function: } y = \sin(x)$'表示"Sine Function: y = sin(x)"。

批注

在Matplotlib中,批注(Annotation)是一种在图形中添加文本和箭头的方式,用于标识和解释图中的特定点、区域或趋势。批注可以是简单的文本注释,也可以包含箭头指向特定位置。

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

plt.plot(x, y, label='sin(x)')

# 添加简单的文本批注
plt.annotate('Maximum', xy=(np.pi/2, 1), xytext=(np.pi/2, 1.2),
             arrowprops=dict(facecolor='blue', shrink=0.05),
             fontsize=10, color='blue', ha='center')

plt.annotate('Minimum', xy=(3*np.pi/2, -1), xytext=(3*np.pi/2, -1.2),
             arrowprops=dict(facecolor='red', shrink=0.05),
             fontsize=10, color='red', ha='center')

plt.xlabel('x')
plt.ylabel('y')
plt.title('Sine Function')

plt.legend()
plt.show()

在上述示例中,使用annotate函数添加了两个批注,分别表示正弦函数的最大值和最小值。关键参数如下:

  • xy:注释箭头的目标点位置。
  • xytext:文本的位置。
  • arrowprops:设置箭头的属性,如颜色、缩放等。
  • fontsize:文本字体大小。
  • color:文本颜色。
  • ha:水平对齐方式。

非线性坐标轴

matplotlib.pyplot不仅支持线性坐标轴刻度,还支持对数坐标轴和logit刻度。对数坐标轴常用于数据跨越多个数量级的情况。在Matplotlib中,改变坐标轴的刻度是很容易的,例如:

python 复制代码
plt.xscale('log')

下面是一个示例,展示了使用相同数据在不同y轴刻度下的四个图。

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
# 生成一些示例数据
np.random.seed(19680801)
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))

# 创建具有不同坐标轴刻度的子图
plt.figure()

# 线性刻度
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)

# 对数刻度
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)

# 对称对数刻度
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)

# 调整子图布局,因为logit刻度可能需要更多的空间
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25, wspace=0.35)

plt.show()

这个示例展示了如何使用plt.yscale函数在同一数据集上创建不同的y轴刻度类型。其中包括线性刻度、对数刻度、对称对数刻度和logit刻度。不同的刻度类型可以更好地适应不同数据分布和数据范围,从而更好地呈现数据的特点。

注意问题

在matplotlib中使用其绘图时,会出现中文字体和负号无法显示的情况,需要添加代码设置全局字体和负号设置后方能正常显示。

因此在使用matplotlib绘图时,在代码中提前加入:

python 复制代码
# 设置全局字体为支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定微软雅黑或其他中文字体
# 设置负号为标准的减号
plt.rcParams['axes.unicode_minus'] = False
相关推荐
这个男人是小帅27 分钟前
【GAT】 代码详解 (1) 运行方法【pytorch】可运行版本
人工智能·pytorch·python·深度学习·分类
小白学大数据4 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
Shy9604184 小时前
Doc2Vec句子向量
python·语言模型
Leo.yuan7 小时前
数据量大Excel卡顿严重?选对报表工具提高10倍效率
数据库·数据分析·数据可视化·powerbi
秀儿还能再秀7 小时前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
阿_旭8 小时前
如何使用OpenCV和Python进行相机校准
python·opencv·相机校准·畸变校准
幸运的星竹8 小时前
使用pytest+openpyxl做接口自动化遇到的问题
python·自动化·pytest
kali-Myon9 小时前
ctfshow-web入门-SSTI(web361-web368)上
前端·python·学习·安全·web安全·web
B站计算机毕业设计超人10 小时前
计算机毕业设计Python+大模型农产品价格预测 ARIMA自回归模型 农产品可视化 农产品爬虫 机器学习 深度学习 大数据毕业设计 Django Flask
大数据·爬虫·python·深度学习·机器学习·课程设计·数据可视化