Matplotlib教程 - 介绍与快速入门

Quick start guide-快速入门指南

本教程介绍了一些基本的使用模式和最佳实践,以帮助您开始使用Matplotlib。

# 导入数据
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl

A simple example-一个简单的例子

Matplotlib将您的数据绘制在 Figure(例如,窗口、Jupyter窗口小部件等), 每个图形都可以包含一个或多个轴Axes, 这是一个可以根据x-y坐标(或极坐标图中的theta-r、三维图中的x-y-z等)指定点的区域。创建带轴图形的最简单方法是使用pyplot.subplots. 然后,我们可以使用Axes.plot在轴上绘制一些数据:

fig, ax = plt.subplots()  # Create a figure containing a single axes.
ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plot some data on the axes.
quick start

请注意,要显示此图,您可能需要调用plt.show(), 具体取决于您的后端。有关地物和后端的更多详细信息,请参见 Introduction to Figures

Parts of a Figure - 图形的组成成分

以下是Matplotlib图的组成成分。

Figure - 图形

整个图形。该图形追踪所有的子Axes, 一组“特殊”格式(标题、图形图例、色条等), 甚至嵌套的子图形。

最简单方法是使用pyplot创建一个新图形:

fig = plt.figure()  # an empty figure with no Axes
fig, ax = plt.subplots() # a figure with a single Axes
fig, axs = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes
# a figure with one axes on the left, and two on the right:
fig, axs = plt.subplot_mosaic([['left', 'right_top'],
['left', 'right_bottom']])

与图形Figure一起创建轴Axes通常很方便,但您也可以稍后手动添加轴。请注意,许多Matplotlib backends支持在图形窗口上缩放和平移。

更多Figures的相关信息, 见Introduction to Figures.

Axes - 轴

轴是附着在图形上的Artist,图形包含用于绘制数据的区域,通常包括两个(如果是3D,则为三个)Axis对象(请注意AxesAxis之间的区别),这些对象提供记号和记号标签以提供轴中数据的比例。每个Axes也有一个标题(通过set_title()设置)、一个x标签(通过set_xlabel())和一个y标签(通过set_ylabel()设置。

Axes类及其成员函数是使用OOP接口的主要入口点,并且在它们上面定义了大多数绘图方法(例如,ax.plot(),如上所示,使用plot方法)

Axis - 所有轴

这些对象设置比例和限制,并生成记号(轴上的标记)和标签记号(标记记号的字符串)。记号的位置由Locator对象确定,记号字符串由Formatter格式化。正确的LocatorFormatter的组合可以对记号位置和标签进行非常精细的控制。

Artist

基本上,图形上的所有可见对象都是Artist(甚至图形Figure、轴Axes和轴Axis对象)。这包括Text对象、Line2D对象、collections对象、Patch对象等。当渲染地物时,所有Artists 都被绘制到画布上。大多数Artists都被束缚在Axes上;这样的Artists不能被多个轴共享或从一个轴移动到另一个轴。

Types of inputs to plotting functions - 绘图函数的输入数据类型

绘图函数需要numpy.arraynumpy.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数组(structured numpy array)或pandas.DataFrame。Matplotlib允许您提供数据关键字参数,并生成传递与x和y变量对应的字符串的绘图。

np.random.seed(19680801)  # seed the random number generator.
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) # 散点图 - s控制了散点的大小
ax.set_xlabel('entry a') # 设置x轴标题
ax.set_ylabel('entry b') # 设置y轴标题

Coding styles - 代码风格

The explicit and the implicit interfaces - 显式和隐式接口

如上所述,使用Matplotlib基本上有两种方法:

  • 显式地创建Figures和Axes,并调用它们上的方法(“面向对象(OO)风格”)。
  • 依靠pyplot隐式创建和管理Figures和Axes,并使用pyplot函数进行绘制。

请参阅Matplotlib Application Interfaces (APIs),以了解隐式和显式接口之间的权衡。

对于显示结构-OO样式

x = np.linspace(0, 2, 100)  # Sample data.

# Note that even in the OO-style, we use `.pyplot.figure` to create the Figure.
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear') # Plot some data on the axes.
ax.plot(x, x**2, label='quadratic') # Plot more data on the axes...
ax.plot(x, x**3, label='cubic') # ... and some more.
ax.set_xlabel('x label') # Add an x-label to the axes.
ax.set_ylabel('y label') # Add a y-label to the axes.
ax.set_title("Simple Plot") # Add a title to the axes.
ax.legend() # Add a legend.

隐式风格-the pyplot-style:

x = np.linspace(0, 2, 100)  # Sample data.

plt.figure(figsize=(5, 2.7), layout='constrained')
plt.plot(x, x, label='linear') # Plot some data on the (implicit) axes.
plt.plot(x, x**2, label='quadratic') # etc.
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()

(此外,还有第三种方法,适用于在GUI应用程序中嵌入Matplotlib的情况,它会完全删除pyplot,甚至用于图形创建。有关更多信息,请参阅库中的相应部分:Embedding Matplotlib in graphical user interfaces

Matplotlib的文档和示例同时使用OO和pyplot样式。通常,我们建议使用OO样式,特别是对于复杂的绘图,以及打算作为更大项目的一部分重用的函数和脚本。然而,pyplot样式对于快速交互工作来说非常方便。

注意:

您可能会通过pylab import*找到使用pylab接口的旧示例。强烈反对使用这种方法。

Making a helper functions - 制作辅助函数

如果需要使用不同的数据集反复绘制相同的绘图,或者希望轻松包装Matplotlib方法,建议使用下面推荐的函数签名方式。

def my_plotter(ax, data1, data2, param_dict):
"""
A helper function to make a graph.
"""
out = ax.plot(data1, data2, **param_dict)
return out

然后,您可以两次使用它来填充两个子绘图:

data1, data2, data3, data4 = np.random.randn(4, 100)  # make 4 random data sets
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'})

请注意,如果你想将这些作为python包或任何其他自定义安装,你可以使用网络上众多模板中的一个;Matplotlib在mpl-cookiecutter有一个

Styling Artists - 艺术风格

大多数plot方法都有“Artists”的样式选项,可以在调用plot方法时访问,也可以从“Artists”上的“设置器setter”访问。在下面的绘图中,我们手动设置创建的Artists的颜色color、线宽linewidth和线型linestyle ,并使用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(':')

Colors - 颜色

Matplotlib 提供了非常灵活的颜色组合,这些颜色在大多数绘图对象中都能被接受;有关允许的颜色定义列表,请参阅可接受的颜色定义(allowable color definitions)。某些绘图对象可以接受多种颜色。例如,在散点图(scatter)中,数据点边缘的颜色可以与内部颜色不同:

fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='C0', edgecolor='k')

Linewidths, linestyles, and markersizes - 线宽、线型和标记

线条宽度通常以印刷点为单位(1 pt=1/72英寸),可用于具有描边线条的Artists。类似地,笔划线可以具有线条样式。请参见linestyles example

标记大小取决于所使用的方法。plot以点为单位指定标记大小,通常是标记的“直径”或宽度。scatter指定标记大小与标记的可视区域大致成比例。有一系列标记样式可用作字符串代码(请参阅markers),或者用户可以定义自己的MarkerStyle(请参阅Marker reference):

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()

Labelling plots - 绘图标签

Axes labels and text - 轴标签和文字

set_xlabel, set_ylabelset_title用于在指定位置添加文本(有关更多讨论,请参阅Text in Matplotlib Plots)。文本也可以使用text直接添加到绘图中:

mu, sigma = 115, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
# the histogram of the data
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')

Text properties and layout中详细介绍了这些属性。

Using mathematical expressions in text - 在文本中使用数学表达式

Matplotlib接受任何文本表达式中的TeX方程式表达式。例如编写表达式$\sigma_i=15$在标题中,您可以写一个由美元符号$包围的TeX表达式:

ax.set_title(r'$\sigma_i=15$')

其中,标题字符串前面的r表示该字符串是原始字符串,不将反斜杠视为python转义符。Matplotlib有一个内置的TeX表达式解析器和布局引擎,并提供自己的数学字体——有关详细信息,请参阅 Writing mathematical expressions.。您也可以直接使用LaTeX来格式化文本,并将输出直接合并到显示图形或保存的postscript中——请参阅使用Text rendering with LaTeX

Annotations - 注释

我们还可以注释绘图上的点,通常通过将指向xy的箭头连接到xytext处的一段文本:

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)

在这个基本示例中,xyxytext都在数据坐标中。您可以选择多种其他坐标系——有关详细信息,请参见Basic annotationAdvanced annotation。更多示例也可以在“Annotating Plots.”中找到。

Legends - 图例

我们通常希望使用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() # 显示图例

Matplotlib中的图例在布局、位置以及它们可以代表的Artists方面都非常灵活。它们在Legend guide.中进行了详细讨论。

Axis scales and ticks - 轴刻度边界和刻度单位

每个Axes都有两个(或三个)Axis对象,表示x轴和y轴。它们控制轴刻度边界、刻度定位locators 和刻度格式器formatters的比例。还可以附加其他轴以显示更多的轴对象。

Scales - 刻度边界

除了线性比例外,Matplotlib还提供非线性比例,例如对数比例。由于对数标度被广泛使用,也有直接的方法,如对数loglog、半对数xsemilogx和半对数ysemilogy。有许多比例(有关其他示例,请参见Scales)。在这里,我们手动设置比例:

fig, axs = plt.subplots(1, 2, figsize=(5, 2.7), layout='constrained')
xdata = np.arange(len(data1)) # make an ordinal for this
data = 10**data1
axs[0].plot(xdata, data)

axs[1].set_yscale('log') # 设置坐标轴刻度
axs[1].plot(xdata, data)

比例设置从数据值到沿“轴”的间距的映射。这在两个方向上都会发生,并组合成一个变换transform,这就是Matplotlib从数据坐标映射到Axes、Figure或屏幕坐标的方式。请参见Transformations Tutorial.。

Tick locators and formatters - 刻度定位与格式

每个轴都有一个刻度定位器locator 和格式化程序formatter ,用于选择沿轴对象放置刻度标记的位置。一个简单的接口是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']) # 设置x轴刻度
axs[1].set_yticks([-1.5, 0, 1.5]) # note that we don't need to specify labels # 设置x轴刻度
axs[1].set_title('Manual ticks') # 设置标题

不同的刻度可以有不同的定位器和格式化程序;例如,上面的日志刻度使用LogLocatorLogFormatter。请参阅Tick locatorsTick formatters,了解其他格式化程序和定位器以及编写自己的信息。

Plotting dates and strings - 绘制日期和字符串

Matplotlib可以处理日期数组、字符串数组以及浮点数字的绘图。它们会根据需要获得特殊的定位器和格式化程序。对于日期:

fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
dates = np.arange(np.datetime64('2021-11-15'), np.datetime64('2021-12-25'),
np.timedelta64(1, 'h'))
data = np.cumsum(np.random.randn(len(dates)))
ax.plot(dates, data)
cdf = mpl.dates.ConciseDateFormatter(ax.xaxis.get_major_locator())
ax.xaxis.set_major_formatter(cdf)

有关更多信息,请参阅日期示例(例如Date tick labels

对于字符串,我们得到分类绘图(请参见:Plotting categorical variables)。

fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
categories = ['turnips', 'rutabaga', 'cucumber', 'pumpkins']

ax.bar(categories, np.random.rand(len(categories)))

关于分类绘图的一个警告:一些解析文本文件的方法会返回字符串列表,即使这些字符串都表示数字或日期。如果你传递1000个字符串,Matplotlib会认为你指的是1000个类别,并会在你的绘图中添加1000个记号!

Additional Axis objects - 附加坐标轴对象(双y轴)

在一张图表中绘制不同大小的数据可能需要额外的y轴。这样的轴可以通过使用twinx添加新的轴来创建,其中不可见的x轴和位于右侧的y轴(类似于twiny)。有关另一个示例,请参见Plots with different scales

类似地,可以添加与主轴具有不同比例的secondary_xaxissecondary_yaxis,以表示不同比例或单位的数据。有关更多示例,请参见“Secondary Axis”。

fig, (ax1, ax3) = plt.subplots(1, 2, figsize=(7, 2.7), layout='constrained')
l1, = ax1.plot(t, s)
ax2 = ax1.twinx()
l2, = ax2.plot(t, range(len(t)), 'C1')
ax2.legend([l1, l2], ['Sine (left)', 'Straight (right)'])

ax3.plot(t, s)
ax3.set_xlabel('Angle [rad]')
ax4 = ax3.secondary_xaxis('top', functions=(np.rad2deg, np.deg2rad))
ax4.set_xlabel('Angle [°]')

Color mapped data - 颜色映射数据

我们经常希望在一个图中有一个第三维度,用颜色图中的颜色来表示。Matplotlib有许多plot类型可以执行此操作:

X, Y = np.meshgrid(np.linspace(-3, 3, 128), np.linspace(-3, 3, 128))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)

fig, axs = plt.subplots(2, 2, layout='constrained')
pc = axs[0, 0].pcolormesh(X, Y, Z, vmin=-1, vmax=1, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[0, 0])
axs[0, 0].set_title('pcolormesh()')

co = axs[0, 1].contourf(X, Y, Z, levels=np.linspace(-1.25, 1.25, 11))
fig.colorbar(co, ax=axs[0, 1])
axs[0, 1].set_title('contourf()')

pc = axs[1, 0].imshow(Z**2 * 100, cmap='plasma',
norm=mpl.colors.LogNorm(vmin=0.01, vmax=100))
fig.colorbar(pc, ax=axs[1, 0], extend='both')
axs[1, 0].set_title('imshow() with LogNorm()')

pc = axs[1, 1].scatter(data1, data2, c=data3, cmap='RdBu_r')
fig.colorbar(pc, ax=axs[1, 1], extend='both')
axs[1, 1].set_title('scatter()')

Colormaps - 颜色地图

这些都是从ScalarMappable对象派生的Artists示例。它们都可以将vminvmax之间的线性映射设置为cmap指定的颜色映射(Colormaps) 。Matplotlib有许多颜色映射可供选择(Choosing Colormaps in Matplotlib),您可以自己制作(Creating Colormaps in Matplotlib)或作为第三方软件包下载(third-party packages)。

Normalizations - 归一化

有时我们想要数据到颜色映射的非线性映射,如上面的LogNorm示例。我们通过为ScalarMappable提供norm参数而不是vminvmax来实现这一点。更多规格化显示在“Colormap Normalization”中。

Colorbars - 颜色条

添加一个颜色条colorbar提供了一个将颜色与基础数据关联起来的键。色条是图形级别的Artists,并且附加到ScalarMappable(在那里他们获得关于范数和颜色映射的信息),并且通常从父Axes窃取空间。颜色条的放置可能很复杂:有关详细信息,请参见Placing Colorbars。您还可以使用extend关键字更改颜色条的外观以在末端添加箭头,并使用收缩和纵横来控制大小。最后,颜色栏将具有适用于规范的默认定位器和格式化程序。对于其他“轴”对象,可以对其进行更改。

Working with multiple Figures and Axes - 使用多个图形和轴

您可以通过多次调用fig = plt.figure()fig2, ax = plt.subplots()来绘制多个图。通过保留对象引用,您可以将Artists添加到任一图中。

可以通过多种方式添加多个轴,但最基本的是上面使用的plt.subplots()。为了实现更复杂的布局,其中Axes对象跨越列或行,可以使用subplot_mosaic

fig, axd = plt.subplot_mosaic([['upleft', 'right'],
['lowleft', 'right']], layout='constrained')
axd['upleft'].set_title('upleft')
axd['lowleft'].set_title('lowleft')
axd['right'].set_title('right')

Matplotlib有非常复杂的工具来排列轴:请参阅在图形中排列多个轴(Arranging multiple Axes in a Figure)和复杂和语义图形组合Complex and semantic figure composition (subplot_mosaic)

More reading - 更多内容

有关更多绘图类型,请参见Plot typesAPI reference,特别是Axes API.

Download Python source code: quick_start.py

Download Jupyter notebook: quick_start.ipynb

Other trick - 一些技巧

  1. 关于字体大小的设置: https://www.zhihu.com/question/509168559?utm_id=0

参考来源:

  1. matplotlib官网-快速开始指导