来源:投稿 作者:Fairy
编辑:学姐
本教程涵盖了一些基本的使用模式和最佳实践,以帮助您开始使用Matplotlib,我们可以先导入需要用到的Python库:
import matplotlib.pyplot as plt
import numpy as np
unset
unset
一个简单的例子
unset
unset
Matplotlib将您的数据绘制在
Figure
s上(例如,窗口、Windows窗口小部件等),其中每一个都可以包含一个或多个
Axes
,即可以根据x-y坐标(或极坐标图中的θ-r,3D图中的x-y-z等)指定点的区域。创建具有轴的图的最简单方法是使用
pyplot.subplots
。然后我们可以使用
Axes.plot
在轴上绘制一些数据,使用
show
显示图形:
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
plt.show()
根据您工作的环境,
plt.show()
可以省略(如果是Jupyter Notebook环境,这个可以省略)。这是一个例子,使用自动显示在一个代码单元中创建的所有图形的Xueyter笔记本。
unset
unset
图的各个组成部分
unset
unset
一幅Matplotlib图包括以下组成部分。
Figure
整个图形。Figure跟踪所有子Axes,一组“特殊”的艺术家(标题、图例、色条等),甚至嵌套的子图。
通常,您将通过以下函数之一来创建新的Figure:
fig = plt.figure()
fig, ax = plt.subplots()
fig, axs = plt.subplots(2, 2)
fig, axs = plt.subplot_mosaic([['left', 'right_top'],['left', 'right_bottom']])
subplots()和subplot_mosaic是方便的函数,可以在Figure内创建Axes对象,但您也可以稍后手动添加Axes。
Axes
一个Axes是附加到Figure的艺术家,它包含用于绘制数据的区域,并通常包括两个(在3D情况下为三个)Axis对象(注意Axes和Axis之间的区别),这些对象提供刻度和刻度标签,为Axes中的数据提供比例。每个Axes还有一个标题(通过set_title()设置),一个x标签(通过set_xlabel()设置),和一个y标签(通过set_ylabel()设置)。
Axes
方法是配置绘图大部分部分内容的主要界面(添加数据、控制轴标度和限制、添加标签等)。
Axis
这些对象设置刻度和限制,并生成刻度(Axis上的标记)和ticklabels(标记刻度的字符串)。刻度的位置由
Locator
对象确定,而ticklabel字符串由
Formatter
格式化。正确的
Locator
和
Formatter
的组合可以非常精细地控制刻度位置和标签。
Artist
基本上,图中可见的所有内容都是一个艺术家(包括Figure、Axes和Axis对象)。这包括文本对象、Line2D对象、集合对象、Patch对象等。当图形被渲染时,所有的艺术家都被绘制到画布上。大多数艺术家都与一个Axes相关联;这样的艺术家不能被多个Axes共享,也不能从一个Axes移动到另一个Axes。
unset
unset
绘图函数的输入类型
unset
unset
绘图函数期望
numpy.array
或
numpy.ma.masked_array
作为输入,或者可以传递给
numpy.asarray
的对象。类似于数组('array-like')的类,如
pandas
数据对象和
numpy.matrix
可能无法按预期工作。常见的约定是在打印之前将这些对象转换为
numpy.array
对象。例如,要转换
numpy.matrix
。
b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)
大多数方法也会解析字符串可索引对象,如dict,结构化numpy数组或
pandas.DataFrame
。Matplotlib允许您提供
data
关键字参数,并通过与x和y变量对应的字符串生成图。
np.random.seed(19680801)
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']) * 100
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.scatter('a', 'b', c='c', s='d', data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b')
unset
unset
编码样式
unset
unset
如上所述,使用Matplotlib基本上有两种方法:
-
显式地创建Figures和Axes,并调用它们的方法(“面向对象(OO)风格”)。
-
依赖pyplot隐式地创建和管理Figures和Axes,并使用pyplot函数进行绘图。
可以使用OO样式:
x = np.linspace(0, 2, 100)
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear')
ax.plot(x, x**2, label='quadratic')
ax.plot(x, x**3, label='cubic')
ax.set_xlabel('x label')
ax.set_ylabel('y label')
ax.set_title("Simple Plot")
ax.legend()
或者pyplot样式:
x = np.linspace(0, 2, 100)
plt.figure(figsize=(5, 2.7), layout='constrained')
plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
此外,还有第三种方法,当在GUI应用程序中嵌入Matplotlib时,它完全放弃了pyplot,甚至用于图形创建。
unset
unset
制作一个帮助函数
unset
unset
如果你需要反复使用不同的数据集绘制相同的图形,或者想要轻松地封装Matplotlib方法,请使用下面推荐的签名函数。
def my_plotter(ax, data1, data2, param_dict):
out = ax.plot(data1, data2, **param_dict)
return out
然后用两次来填充两个子图:
data1, data2, data3, data4 = np.random.randn(4, 100)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.7))
my_plotter(ax1, data1, data2, {'marker': 'x'})
my_plotter(ax2, data3, data4, {'marker': 'o'})
unset
unset
造型艺术家
unset
unset
大多数绘图方法都有用于Artist的样式选项,可以在调用绘图方法时访问,也可以从Artist上的“setter”访问。在下面的图中,我们手动设置由
plot
创建的艺术家的颜色,线宽和线条样式,我们使用
set_linestyle
设置第二行的线条样式。
fig, ax = plt.subplots(figsize=(5, 2.7))
x = np.arange(len(data1))
ax.plot(x, np.cumsum(data1), color='blue', linewidth=3, linestyle='--')
l, = ax.plot(x, np.cumsum(data2), color='orange', linewidth=2)
l.set_linestyle(':')
unset
unset
颜色
unset
unset
Matplotlib有一个非常灵活的颜色数组,大多数艺术家都可以接受;请参阅允许的颜色定义以获得规范列表。一些艺术家会使用多种颜色。即,对于
scatter
图,标记的边缘可以是与内部不同的颜色:
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='C0', edgecolor='k')
unset
unset
线宽、线型和标记尺寸
unset
unset
线条宽度通常以印刷磅(1磅= 1/72英寸)为单位,可用于具有描边线条的艺术家。类似地,描边线可以具有线样式。请参见linestyles示例。
标记大小取决于所使用的方法。
plot
以点为单位指定标记大小,通常是标记的“直径”或宽度。
scatter
将标记大小指定为与标记的可视区域近似成比例。有一系列标记样式可作为字符串代码(参见
markers
),或者用户可以定义自己的
MarkerStyle
。
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(data1, 'o', label='data1')
ax.plot(data2, 'd', label='data2')
ax.plot(data3, 'v', label='data3')
ax.plot(data4, 's', label='data4')
ax.legend()
unset
unset
标记图
unset
unset
轴标签和文本
set_xlabel
、
set_ylabel
和
set_title
用于在指定位置添加文本(有关更多讨论,请参见Matplotlib中的文本)。也可以使用
text
将文本直接添加到图中:
mu, sigma = 115, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
n, bins, patches = ax.hist(x, 50, density=True, facecolor='C0', alpha=0.75)
ax.set_xlabel('Length [cm]')
ax.set_ylabel('Probability')
ax.set_title('Aardvark lengths\n (not really)')
ax.text(75, .025, r'$\mu=115,\ \sigma=15$')
ax.axis([55, 175, 0, 0.03])
ax.grid(True)
所有的
text
函数都返回一个
matplotlib.text.Text
实例。就像上面的行一样,你可以通过向文本函数传递关键字参数来自定义属性:
t = ax.set_xlabel('my data', fontsize=14, color='red')
在文本中使用数学表达式
Matplotlib接受任何文本表达式中的TeX方程表达式。例如,要在标题中写入表达式 𝜎𝑖=15 ,您可以编写一个由美元符号包围的TeX表达式:
ax.set_title(r'$\sigma_i=15$')
其中标题字符串前面的
r
表示该字符串是原始字符串,并且不将反斜杠视为python转义符。Matplotlib有一个内置的TeX表达式解析器和布局引擎,并提供自己的数学字体-详细信息请参阅编写数学表达式。您也可以直接使用LaTeX来格式化文本,并将输出直接合并到显示图形或保存的后记中-请参阅使用LaTeX进行文本渲染。
注释
我们也可以注释图上的点,通常通过将指向xy的箭头连接到text处的一段文本:
fig, ax = plt.subplots(figsize=(5, 2.7))
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2 * np.pi * t)
line, = ax.plot(t, s, lw=2)
ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05))
ax.set_ylim(-2, 2)
图例
通常我们想用
Axes.legend
来标识线条或标记
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(np.arange(len(data1)), data1, label='data1')
ax.plot(np.arange(len(data2)), data2, label='data2')
ax.plot(np.arange(len(data3)), data3, 'd', label='data3')
ax.legend()
轴刻度和刻度
每个轴有两个(或三个)
Axis
对象代表x轴和y轴。这些控件控制轴的比例、刻度定位器和刻度格式化器。可以附加其他轴以显示更多的轴对象。
小标尺
除了线性标尺,Matplotlib还提供非线性标尺,例如对数标尺。由于对数标度被大量使用,因此也有直接方法,如
loglog
,
semilogx
和
semilogy
。有许多尺度(参见其他示例的尺度)。在这里,我们手动设置比例:
fig, axs = plt.subplots(1, 2, figsize=(5, 2.7), layout='constrained')
xdata = np.arange(len(data1))
data = 10**data1
axs[0].plot(xdata, data)
axs[1].set_yscale('log')
axs[1].plot(xdata, data)
刻度定位器和格式化
每个轴都有一个刻度定位器和格式化程序,用于选择在沿着轴对象的何处放置刻度标记。一个简单的接口是
set_xticks
:
fig, axs = plt.subplots(2, 1, layout='constrained')
axs[0].plot(xdata, data1)
axs[0].set_title('Automatic ticks')
axs[1].plot(xdata, data1)
axs[1].set_xticks(np.arange(0, 100, 30), ['zero', '30', 'sixty', '90'])
axs[1].set_yticks([-1.5, 0, 1.5])
axs[1].set_title('Manual ticks')
绘制日期和字符串
Matplotlib可以处理绘制日期数组和字符串数组,以及浮点数。它们会根据需要获取特殊的定位器和格式化程序。日期:
from matplotlib.dates import ConciseDateFormatter
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
dates = np.arange(np.datetime64('2021-11-15'), np.datetime64('2021-12-25'