1.4. Matplotlib: plotting

作者Nicolas Rougier,MikeMüller,GaëlVaroquaux

1.4.1. 简介

小费

Matplotlib可能是2D图形最常用的Python包。它提供了一种非常快速的方式来可视化来自Python的数据和许多格式的出版品质数字。我们将以交互方式探索matplotlib,覆盖大多数常见的情况。

1.4.1.1. IPython and the matplotlib mode

小费

IPython是一个增强的交互式Python shell,它具有许多有趣的功能,包括命名输入和输出,访问shell命令,改进调试等等。它是Python中的科学计算工作流的核心,与Matplotlib结合使用:

对于具有Matlab / Mathematica类功能的交互式matplotlib会话,我们使用IPython和它的特殊Matplotlib模式,使非阻塞绘图。

IPython控制台:
 

当使用IPython控制台时,我们使用命令行参数--matplotlib(非常旧版本中的-pylab)启动它。

IPython笔记本:
 

在IPython笔记本中,我们在笔记本开头插入以下魔术

%matplotlib inline

1.4.1.2. pyplot

小费

pyplot提供了matplotlib面向对象绘图库的过程接口。它在Matlab™之后紧密建模。因此,pyplot中的大多数绘图命令都具有类似参数的Matlab™模拟。重要的命令用交互式示例解释。

from matplotlib import pyplot as plt

1.4.2. 简单图

小费

在本节中,我们要在同一个图上绘制余弦和正弦函数。从默认设置开始,我们将逐步丰富图表,使其更好。

第一步是获取正弦和余弦函数的数据:

import numpy as np
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)

X现在是一个numpy数组,256个值范围从-π到+π(包括)。C是余弦(256个值),S是正弦(256个值)。

要运行该示例,您可以在IPython交互式会话中键入它们:

$ ipython --pylab

这使我们来到IPython提示:

IPython 0.13 -- An enhanced Interactive Python.
? -> Introduction to IPython's features.
%magic -> Information about IPython's 'magic' % functions.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
Welcome to pylab, a matplotlib-based Python environment.
For more information, type 'help(pylab)'.

小费

你也可以下载每个例子,并使用普通的python运行它,但你会失去交互式数据操作:

$ python plot_exercise_1.py

您可以通过单击相应的图获得每个步骤的源。

1.4.2.1. Plotting with default settings

../../_images/sphx_glr_plot_exercise_1_001.png

链接

文件

小费

Matplotlib有一组默认设置,允许自定义各种属性。您可以控制matplotlib中几乎每个属性的默认值:图大小和dpi,线宽,颜色和样式,轴,轴和网格属性,文本和字体属性等。

import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
plt.plot(X, C)
plt.plot(X, S)
plt.show()

1.4.2.2. Instantiating defaults

../../_images/sphx_glr_plot_exercise_2_001.png

链接

文件

在下面的脚本中,我们实例化了(和评论过)影响绘图外观的所有图形设置。

小费

设置已明确设置为其默认值,但现在您可以交互式使用值来了解其影响(请参阅下面的线属性线样式)。

import numpy as np
import matplotlib.pyplot as plt
# Create a figure of size 8x6 inches, 80 dots per inch
plt.figure(figsize=(8, 6), dpi=80)
# Create a new subplot from a grid of 1x1
plt.subplot(1, 1, 1)
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
# Plot cosine with a blue continuous line of width 1 (pixels)
plt.plot(X, C, color="blue", linewidth=1.0, linestyle="-")
# Plot sine with a green continuous line of width 1 (pixels)
plt.plot(X, S, color="green", linewidth=1.0, linestyle="-")
# Set x limits
plt.xlim(-4.0, 4.0)
# Set x ticks
plt.xticks(np.linspace(-4, 4, 9, endpoint=True))
# Set y limits
plt.ylim(-1.0, 1.0)
# Set y ticks
plt.yticks(np.linspace(-1, 1, 5, endpoint=True))
# Save figure using 72 dots per inch
# plt.savefig("exercise_2.png", dpi=72)
# Show result on screen
plt.show()

1.4.2.3. Changing colors and line widths

../../_images/sphx_glr_plot_exercise_3_001.png

链接

文件

小费

第一步,我们想让余弦在蓝色和正弦在红色和一个轻微的粗线为他们。我们还会稍微改变图形大小,使其更加水平。

...
plt.figure(figsize=(10, 6), dpi=80)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
...

1.4.2.4. Setting limits

../../_images/sphx_glr_plot_exercise_4_001.png

链接

文档

小费

图的电流限制有点太紧了,我们想要一些空间,以便清楚地看到所有的数据点。

...
plt.xlim(X.min() * 1.1, X.max() * 1.1)
plt.ylim(C.min() * 1.1, C.max() * 1.1)
...

1.4.2.5. Setting ticks

../../_images/sphx_glr_plot_exercise_5_001.png

小费

当前刻度不是理想的,因为它们不显示正弦和余弦的有趣值(+/-π,+ / - π/ 2)。我们将更改它们,以便它们只显示这些值。

...
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
plt.yticks([-1, 0, +1])
...

1.4.2.6. Setting tick labels

../../_images/sphx_glr_plot_exercise_6_001.png

小费

Ticks现在正确放置,但他们的标签不是很明确。我们可以猜测3.142是π,但最好是明确。当我们设置刻度值时,我们还可以在第二个参数列表中提供相应的标签。注意,我们将使用乳胶,以允许标签的渲染。

...
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.yticks([-1, 0, +1],
[r'$-1$', r'$0$', r'$+1$'])
...

1.4.2.7. Moving spines

../../_images/sphx_glr_plot_exercise_7_001.png

暗示

文件

小费

脊线是连接轴刻度线并注意数据区边界的线。它们可以放置在任意位置,直到现在,它们在轴的边界上。我们会改变,因为我们想让他们在中间。因为它们有四个(上/下/左/右),我们通过将它们的颜色设置为无,丢弃顶部和右侧,我们将移动底部和左边的数据在数据空间坐标中坐标为0。

...
ax = plt.gca() # gca stands for 'get current axis'
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
...

1.4.2.8. Adding a legend

../../_images/sphx_glr_plot_exercise_8_001.png

小费

让我们在左上角添加一个图例。这只需要在plot命令中添加关键字参数标签(将在图例框中使用)。

...
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine")
plt.legend(loc='upper left')
...

1.4.2.9. Annotate some points

../../_images/sphx_glr_plot_exercise_9_001.png

暗示

文件

小费

让我们使用annotate命令注释一些有趣的点。我们选择了2π/ 3的值,我们想要注释正弦和余弦。我们将首先在曲线上绘制一个标记以及一条直虚线。然后,我们将使用annotate命令显示一些带有箭头的文本。

...
t = 2 * np.pi / 3
plt.plot([t, t], [0, np.cos(t)], color='blue', linewidth=2.5, linestyle="--")
plt.scatter([t, ], [np.cos(t), ], 50, color='blue')
plt.annotate(r'$cos(\frac{2\pi}{3})=-\frac{1}{2}$',
xy=(t, np.cos(t)), xycoords='data',
xytext=(-90, -50), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.plot([t, t],[0, np.sin(t)], color='red', linewidth=2.5, linestyle="--")
plt.scatter([t, ],[np.sin(t), ], 50, color='red')
plt.annotate(r'$sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
xy=(t, np.sin(t)), xycoords='data',
xytext=(+10, +30), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
...

1.4.2.10. Devil is in the details

../../_images/sphx_glr_plot_exercise_10_001.png

暗示

文件

小费

刻度标签现在几乎不可见,因为蓝色和红色线。我们可以让它们更大,我们也可以调整他们的属性,使他们将呈现在半透明的白色背景上。这将允许我们看到数据和标签。

...
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65))
...

1.4.3. 数字,子图,轴和诀窍

matplotlib中的“figure”表示用户界面中的整个窗口。在此图中,可以有“subplots”

小费

到目前为止,我们已经使用隐式图形和轴创建。这对于快速绘图很方便。我们可以明确地使用图,子图和轴来更好地控制显示。当子绘图将绘图定位在规则网格中时,轴允许在图中自由放置。根据你的意图,两者都可以是有用的。我们已经使用数字和子图,没有明确地调用它们。当我们调用plot时,matplotlib调用gca()获取当前轴,gca依次调用gcf()获得当前图形。如果没有,则严格来说,调用figure()来创建一个subplot(111)让我们来看看细节。

1.4.3.1. Figures

小费

一个图是GUI中具有“图#”作为标题的窗口。数字从1开始编号,而不是从0开始的普通Python方法。这显然是MATLAB风格。有几个参数决定了图形的样子:

论据 默认 描述
num 1 数字
figsize figure.figsize 图尺寸(英寸)(宽度,高度)
dpi figure.dpi 分辨率,每英寸点数
facecolor figure.facecolor 绘图背景的颜色
edgecolor figure.edgecolor 边缘颜色的绘图背景
frameon True 绘制图框或不

小费

默认值可以在资源文件中指定,并且将在大多数时间使用。只有图形的编号经常改变。

与其他对象一样,您可以将figure属性也设置为setp或使用set_something方法。

当您使用GUI时,可以通过单击右上角的x来关闭图形。但是你可以通过调用close来以编程方式关闭一个数字。根据参数,它关闭(1)当前图形(无参数),(2)特定的图形(图形数字或图形实例作为参数)或者(3)所有图形("all"

plt.close(1)     # Closes figure 1

1.4.3.2. Subplots

小费

使用子图可以在常规网格中排列图。您需要指定行数和列数以及绘图数。请注意,gridspec命令是一个更强大的替代。

../../_images/sphx_glr_plot_subplot-horizontal_001.png ../../_images/sphx_glr_plot_subplot-vertical_001.png ../../_images/sphx_glr_plot_subplot-grid_001.png ../../_images/sphx_glr_plot_gridspec_001.png

1.4.3.3. Axes

轴非常类似于子图,但允许将绘图放置在图中的任何位置。所以,如果我们想把一个更小的图放在一个更大的,我们这样做与轴。

../../_images/sphx_glr_plot_axes_001.png ../../_images/sphx_glr_plot_axes-2_001.png

1.4.3.4. Ticks

出版物要求数据图具有良好的坐标轴。Matplotlib提供了可以自由配置轴的功能(ticks)。有刻度定位器指定刻度应该出现在哪里,刻度格式化,给刻度你想要的外观。主刻度和次刻度可以彼此独立地定位和格式化。默认情况下,不显示小的tick,即只有一个空列表,因为它是NullLocator(见下文)。

1.4.3.4.1. Tick Locators

Tick定位器控制刻度的位置。它们设置如下:

ax = plt.gca()
ax.xaxis.set_major_locator(eval(locator))

有几种定位器用于不同类型的要求:

../../_images/sphx_glr_plot_ticks_001.png

所有这些定位器派生自基类matplotlib.ticker.Locator你可以使它自己的定位器。处理日期作为ticks可能是特别棘手。因此,matplotlib在matplotlib.dates中提供了特殊的定位器。

1.4.4. 其他类型的图:示例和练习

../../_images/sphx_glr_plot_bar_ext_001.png ../../_images/sphx_glr_plot_imshow_ext_001.png ../../_images/sphx_glr_plot_quiver_ext_001.png ../../_images/sphx_glr_plot_pie_ext_001.png ../../_images/sphx_glr_plot_grid_ext_001.png ../../_images/sphx_glr_plot_multiplot_ext_001.png ../../_images/sphx_glr_plot_polar_ext_001.png ../../_images/sphx_glr_plot_plot3d_ext_001.png ../../_images/sphx_glr_plot_text_ext_001.png

1.4.4.1. Regular Plots

../../_images/sphx_glr_plot_plot_001.png

暗示

您需要使用fill_between命令。

从下面的代码开始,尝试重现右侧的图形,注意填充区域:

n = 256
X = np.linspace(-np.pi, np.pi, n, endpoint=True)
Y = np.sin(2 * X)
plt.plot(X, Y + 1, color='blue', alpha=1.00)
plt.plot(X, Y - 1, color='blue', alpha=1.00)

单击解决方案的图。

1.4.4.2. Scatter Plots

../../_images/sphx_glr_plot_scatter_001.png

暗示

颜色由(X,Y)的角度给出。

从下面的代码开始,尝试在右侧重现图形,处理标记大小,颜色和透明度。

n = 1024
X = np.random.normal(0,1,n)
Y = np.random.normal(0,1,n)
plt.scatter(X,Y)

点击图解为解决方案。

1.4.4.3. Bar Plots

../../_images/sphx_glr_plot_bar_001.png

暗示

你需要照顾文本对齐。

从下面的代码开始,尝试通过为红色条添加标签来重现右侧的图形。

n = 12
X = np.arange(n)
Y1 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)
Y2 = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)
plt.bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
plt.bar(X, -Y2, facecolor='#ff9999', edgecolor='white')
for x, y in zip(X, Y1):
plt.text(x + 0.4, y + 0.05, '%.2f' % y, ha='center', va='bottom')
plt.ylim(-1.25, +1.25)

点击图解为解决方案。

1.4.4.4. Contour Plots

../../_images/sphx_glr_plot_contour_001.png

暗示

您需要使用clabel命令。

从下面的代码开始,尝试在右侧重现图形,处理色彩映射(参见下面的色图)。

def f(x, y):
return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 -y ** 2)
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
plt.contourf(X, Y, f(X, Y), 8, alpha=.75, cmap='jet')
C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=.5)

点击图解为解决方案。

1.4.4.5. Imshow

../../_images/sphx_glr_plot_imshow_001.png

暗示

您需要在imshow命令中处理图像的origin,并使用颜色条

从下面的代码开始,尝试在右侧重现图形,注意色彩映射,图像插值和原点。

def f(x, y):
return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
n = 10
x = np.linspace(-3, 3, 4 * n)
y = np.linspace(-3, 3, 3 * n)
X, Y = np.meshgrid(x, y)
plt.imshow(f(X, Y))

单击解决方案的图。

1.4.4.6. Pie Charts

../../_images/sphx_glr_plot_pie_001.png

暗示

您需要修改Z.

从下面的代码开始,尝试在右侧重现图形,照顾颜色和切片大小。

Z = np.random.uniform(0, 1, 20)
plt.pie(Z)

单击解决方案的图。

1.4.4.7. Quiver Plots

../../_images/sphx_glr_plot_quiver_001.png

暗示

你需要绘制箭头两次。

从上面的代码开始,尝试在右侧重现图形,照顾颜色和方向。

n = 8
X, Y = np.mgrid[0:n, 0:n]
plt.quiver(X, Y)

点击图解为解决方案。

1.4.4.8. Grids

../../_images/sphx_glr_plot_grid_001.png

从下面的代码开始,尝试重现右侧的图形处理线型。

axes = plt.gca()
axes.set_xlim(0, 4)
axes.set_ylim(0, 3)
axes.set_xticklabels([])
axes.set_yticklabels([])

点击图解为解决方案。

1.4.4.9. Multi Plots

../../_images/sphx_glr_plot_multiplot_001.png

暗示

您可以使用不同分区的几个子图。

从下面的代码开始,尝试重现右边的图形。

plt.subplot(2, 2, 1)
plt.subplot(2, 2, 3)
plt.subplot(2, 2, 4)

点击图解为解决方案。

1.4.4.10. Polar Axis

../../_images/sphx_glr_plot_polar_001.png

暗示

您只需修改axes行即可

从下面的代码开始,尝试重现右边的图形。

plt.axes([0, 0, 1, 1])
N = 20
theta = np.arange(0., 2 * np.pi, 2 * np.pi / N)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N)
bars = plt.bar(theta, radii, width=width, bottom=0.0)
for r, bar in zip(radii, bars):
bar.set_facecolor(cm.jet(r / 10.))
bar.set_alpha(0.5)

点击图解为解决方案。

1.4.4.11. 3D图

../../_images/sphx_glr_plot_plot3d_001.png

暗示

您需要使用contourf

从下面的代码开始,尝试重现右边的图形。

from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='hot')

点击图解为解决方案。

也可以看看

3D plotting with Mayavi

1.4.4.12. Text

../../_images/sphx_glr_plot_text_001.png

暗示

请查看matplotlib徽标

尝试从头开始做同样的事情!

点击图解为解决方案。


快速阅读

如果你想第一次快速通过Scipy讲座来学习生态系统,你可以直接跳到下一章:Scipy : high-level scientific computing

本章的其余部分不必跟随介绍部分的其余部分。但是一定要回来,以后完成这一章。

1.4.5. 超出本教程

Matplotlib受益于大量文档以及大型用户和开发人员社区。以下是一些感兴趣的链接:

1.4.5.1. Tutorials

  • Pyplot教程
    • 介绍
    • 控制线属性
    • 使用多个图形和轴
    • 使用文本
  • 图像教程
    • 启动命令
    • 将图像数据导入Numpy数组
    • 将numpy数组绘制为图像
  • 文字教学
    • 文字介绍
    • 基本文本命令
    • 文本属性和布局
    • 写数学表达式
    • 使用LaTeX进行文本渲染
    • 注释文本
  • 艺术家教程
    • 介绍
    • 自定义对象
    • 对象容器
    • 图容器
    • 轴容器
    • Axis容器
    • 勾选容器
  • 路径教学
    • 介绍
    • Bézier示例
    • 复合路径
  • 转换教程
    • 介绍
    • 数据坐标
    • 轴坐标
    • 混合变换
    • 使用偏移变换创建阴影效果
    • 变换管道

1.4.5.2. Matplotlib documentation

1.4.5.3. Code documentation

代码有很好的文档,你可以从python会话中快速访问特定的命令:

>>> import matplotlib.pyplot as plt
>>> help(plt.plot)
Help on function plot in module matplotlib.pyplot:
plot(*args, **kwargs)
Plot lines and/or markers to the
:class:`~matplotlib.axes.Axes`. *args* is a variable length
argument, allowing for multiple *x*, *y* pairs with an
optional format string. For example, each of the following is
legal::
plot(x, y) # plot x and y using default line style and color
plot(x, y, 'bo') # plot x and y using blue circle markers
plot(y) # plot y using x as index array 0..N-1
plot(y, 'r+') # ditto, but with red plusses
If *x* and/or *y* is 2-dimensional, then the corresponding columns
will be plotted.
...

1.4.5.4. Galleries

当您搜索如何渲染给定图形时,matplotlib库也非常有用。每个例子都带有它的源。

1.4.5.5. Mailing lists

最后,还有一个用户邮寄名单,您可以要求帮助和开发人员邮寄名单,这是更技术性的。

1.4.6. 快速参考

这里是一组显示主要属性和样式的表。

1.4.6.1. Line properties

属性 描述 出现
alpha(或a) α透明度0-1级 ../../_images/sphx_glr_plot_alpha_001.png
抗锯齿 True或False - 使用抗锯齿渲染 ../../_images/sphx_glr_plot_aliased_001.png ../../_images/sphx_glr_plot_antialiased_001.png
颜色(或c) matplotlib颜色arg ../../_images/sphx_glr_plot_color_001.png
linestyle(或ls) 请参阅线属性  
线宽(或lw) 浮点数,线宽度(以点为单位) ../../_images/sphx_glr_plot_linewidth_001.png
solid_capstyle 实线的帽样式 ../../_images/sphx_glr_plot_solid_capstyle_001.png
solid_joinstyle 加入实线样式 ../../_images/sphx_glr_plot_solid_joinstyle_001.png
dash_capstyle 破折号的帽样式 ../../_images/sphx_glr_plot_dash_capstyle_001.png
dash_joinstyle 加入破折号样式 ../../_images/sphx_glr_plot_dash_joinstyle_001.png
标记 请参阅标记  
markeredgewidth(mew) 标记符号周围的线宽 ../../_images/sphx_glr_plot_mew_001.png
标记颜色 如果使用标记,边缘颜色 ../../_images/sphx_glr_plot_mec_001.png
markerfacecolor(mfc) 如果使用标记,则为面部颜色 ../../_images/sphx_glr_plot_mfc_001.png
标记(ms) 标记的大小(以点为单位) ../../_images/sphx_glr_plot_ms_001.png

1.4.6.2. Line styles

../../_images/sphx_glr_plot_linestyles_001.png

1.4.6.3. Markers

../../_images/sphx_glr_plot_markers_001.png

1.4.6.4. Colormaps

可以通过附加_r来颠倒所有颜色图。例如,gray_rgray相反。

如果您想了解更多关于色彩映射的信息,请检查记录matplotlib色彩映射

../../_images/sphx_glr_plot_colormaps_001.png