Matplotlib is hiring a Research Software Engineering Fellow! See discourse for details. Apply by January 3, 2020

Version 3.1.1
matplotlib
Fork me on GitHub

目录

Related Topics

图像教程

关于使用matplotlib绘制图像的简短教程。

启动命令

首先,让我们从伊比森开始。它是对标准python提示的最优秀的增强,它与matplotlib尤其密切相关。现在就从外壳或ipython笔记本开始ipython。

随着IPython的启动,我们现在需要连接到一个GUI事件循环。这将告诉IPython在何处(以及如何)显示绘图。要连接到GUI循环,请执行 %Matlab 在你的ipython提示下变魔术。有更多的细节说明这到底是在干什么 IPython's documentation on GUI event loops .

如果您使用的是ipython笔记本,则可以使用相同的命令,但人们通常使用特定的参数来实现 %matplotlib 魔力:

In [1]: %matplotlib inline

这将打开内嵌打印,打印图形将显示在笔记本中。这对交互性有重要影响。对于内联打印,输出打印的单元格下方单元格中的命令不会影响打印。例如,无法从创建绘图的单元格下方的单元格更改颜色映射。但是,对于其他后端,例如打开单独窗口的qt5,在创建绘图的那些后面的单元格将更改绘图-它是内存中的活动对象。

本教程将使用matplotlib的命令式打印界面pyplot。此界面保持全局状态,对于快速轻松地尝试各种绘图设置非常有用。另一种选择是面向对象的接口,它也非常强大,通常更适合于大型应用程序开发。如果你想了解面向对象的接口,一个很好的起点是 Usage guide . 现在,让我们继续使用命令式方法:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

将图像数据导入numpy数组

加载图像数据支持 Pillow 类库。Matplotlib本身只支持PNG图像。如果本机读取失败,下面显示的命令将返回到枕头上。

本例中使用的图像是一个PNG文件,但请记住您自己的数据需要枕头。

下面是我们将要播放的图像:

图像教程

这是一个24位的r g b png图像(每一个r、g、b对应8位)。根据获取数据的位置,您最可能遇到的其他类型的图像是允许透明度的rgba图像,或单通道灰度(亮度)图像。您可以右键单击它,然后选择“将图像另存为”将其下载到您的计算机上,以完成本教程的其余部分。

我们开始…

img = mpimg.imread('../../doc/_static/stinkbug.png')
print(img)

出:

[[[0.40784314 0.40784314 0.40784314]
  [0.40784314 0.40784314 0.40784314]
  [0.40784314 0.40784314 0.40784314]
  ...
  [0.42745098 0.42745098 0.42745098]
  [0.42745098 0.42745098 0.42745098]
  [0.42745098 0.42745098 0.42745098]]

 [[0.4117647  0.4117647  0.4117647 ]
  [0.4117647  0.4117647  0.4117647 ]
  [0.4117647  0.4117647  0.4117647 ]
  ...
  [0.42745098 0.42745098 0.42745098]
  [0.42745098 0.42745098 0.42745098]
  [0.42745098 0.42745098 0.42745098]]

 [[0.41960785 0.41960785 0.41960785]
  [0.41568628 0.41568628 0.41568628]
  [0.41568628 0.41568628 0.41568628]
  ...
  [0.43137255 0.43137255 0.43137255]
  [0.43137255 0.43137255 0.43137255]
  [0.43137255 0.43137255 0.43137255]]

 ...

 [[0.4392157  0.4392157  0.4392157 ]
  [0.43529412 0.43529412 0.43529412]
  [0.43137255 0.43137255 0.43137255]
  ...
  [0.45490196 0.45490196 0.45490196]
  [0.4509804  0.4509804  0.4509804 ]
  [0.4509804  0.4509804  0.4509804 ]]

 [[0.44313726 0.44313726 0.44313726]
  [0.44313726 0.44313726 0.44313726]
  [0.4392157  0.4392157  0.4392157 ]
  ...
  [0.4509804  0.4509804  0.4509804 ]
  [0.44705883 0.44705883 0.44705883]
  [0.44705883 0.44705883 0.44705883]]

 [[0.44313726 0.44313726 0.44313726]
  [0.4509804  0.4509804  0.4509804 ]
  [0.4509804  0.4509804  0.4509804 ]
  ...
  [0.44705883 0.44705883 0.44705883]
  [0.44705883 0.44705883 0.44705883]
  [0.44313726 0.44313726 0.44313726]]]

注意这里的数据类型-float32。Matplotlib已将每个通道的8位数据重新调整为介于0.0和1.0之间的浮点数据。作为旁注,枕头可以使用的唯一数据类型是uint8。Matplotlib Plotting可以处理float32和uint8,但除png之外的任何格式的图像读/写都限于uint8数据。为什么是8位?大多数显示器只能显示每个通道8位的颜色渐变值。为什么它们只能渲染8位/通道?因为这是人眼所能看到的。更多信息(从摄影角度来看): Luminous Landscape bit depth tutorial .

每个内部列表代表一个像素。这里,对于一个RGB图像,有3个值。因为它是黑白图像,r、g和b都是相似的。一个rgba(其中a是alpha或transparency),每个内部列表有4个值,一个简单的亮度图像只有一个值(因此只有二维数组,而不是三维数组)。对于rgb和rgba图像,matplotlib支持float32和uint8数据类型。对于灰度,matplotlib仅支持float32。如果数组数据不符合其中一个描述,则需要重新缩放它。

将numpy数组绘制为图像

所以,您的数据在一个numpy数组中(通过导入或生成它)。我们来渲染一下。在Matplotlib中,使用 imshow() 功能。在这里我们将抓取绘图对象。此对象提供了一种从提示操作绘图的简单方法。

imgplot = plt.imshow(img)
图像教程

您还可以绘制任何numpy数组。

伪彩色方案在图像绘图中的应用

伪彩色可以成为增强对比度和更容易可视化数据的有用工具。这在使用投影仪显示数据时尤其有用-它们的对比度通常很差。

伪彩色只与单通道、灰度、亮度图像有关。我们目前有一个RGB图像。由于R、G和B都是相似的(请参见上面或您的数据),我们只需选择一个数据通道:

lum_img = img[:, :, 0]

# This is array slicing.  You can read more in the `Numpy tutorial
# <https://docs.scipy.org/doc/numpy/user/quickstart.html>`_.

plt.imshow(lum_img)
图像教程

现在,对于亮度(2d,无颜色)图像,将应用默认的颜色映射(又称查找表,lut)。默认值称为viridis。还有很多其他选择。

plt.imshow(lum_img, cmap="hot")
图像教程

请注意,还可以使用 set_cmap() 方法:

imgplot = plt.imshow(lum_img)
imgplot.set_cmap('nipy_spectral')
图像教程

注解

但是,请记住,在带有内联后端的IPython笔记本中,不能更改已经呈现的绘图。如果在一个单元格中创建imgplot,则不能在后一个单元格中对其调用set_cmap(),并期望早先的绘图发生更改。确保在一个单元格中同时输入这些命令。PLT命令不会更改早期单元格的绘图。

还有许多其他的配色方案可用。见 list and images of the colormaps .

色阶参考

了解颜色代表的值是很有帮助的。我们可以通过添加颜色条来做到这一点。

imgplot = plt.imshow(lum_img)
plt.colorbar()
图像教程

这会在现有图形中添加颜色条。这不会自动改变,如果你改变你切换到一个不同的颜色映射-你必须重新创建你的绘图,并再次添加到颜色栏。

检查特定数据范围

有时,您希望增强图像中的对比度,或者在特定区域扩大对比度,同时牺牲颜色变化不大或不重要的细节。找到有趣区域的一个好工具是柱状图。为了创建图像数据的柱状图,我们使用 hist() 功能。

plt.hist(lum_img.ravel(), bins=256, range=(0.0, 1.0), fc='k', ec='k')
图像教程

最常见的是,图像中“有趣的”部分位于峰值附近,您可以通过剪切峰值上方和/或下方的区域来获得额外的对比度。在我们的柱状图中,高端似乎没有太多有用的信息(图像中没有太多白色的东西)。让我们调整上限,以便有效地“放大”柱状图的一部分。我们通过将clim参数传递给imshow来实现这一点。您也可以通过拨打 set_clim() 图像打印对象的方法,但在使用ipython笔记本时,请确保在与plot命令相同的单元格中执行此操作-它不会更改早期单元格的打印。

您可以在调用中指定clim plot .

imgplot = plt.imshow(lum_img, clim=(0.0, 0.7))
图像教程

还可以使用返回的对象指定clim

fig = plt.figure()
a = fig.add_subplot(1, 2, 1)
imgplot = plt.imshow(lum_img)
a.set_title('Before')
plt.colorbar(ticks=[0.1, 0.3, 0.5, 0.7], orientation='horizontal')
a = fig.add_subplot(1, 2, 2)
imgplot = plt.imshow(lum_img)
imgplot.set_clim(0.0, 0.7)
a.set_title('After')
plt.colorbar(ticks=[0.1, 0.3, 0.5, 0.7], orientation='horizontal')
图像教程

阵列插值方案

插值根据不同的数学方案计算像素“应该”的颜色或值。一个常见的情况是当你调整图像的大小。像素数会改变,但您需要相同的信息。因为像素是离散的,所以有丢失的空间。插值就是你如何填充这个空间。这就是为什么你的图像有时会在放大时看起来像像素。当原始图像和扩展图像之间的差异较大时,效果更明显。让我们把图像缩小。我们有效地丢弃了像素,只保留少数选择。现在,当我们绘制它时,数据会放大到屏幕上的大小。旧的像素已经不存在了,计算机必须绘制像素来填充这个空间。

我们将使用我们用来加载图像的枕头库来调整图像的大小。

from PIL import Image

img = Image.open('../../doc/_static/stinkbug.png')
img.thumbnail((64, 64), Image.ANTIALIAS)  # resizes image in-place
imgplot = plt.imshow(img)
图像教程

这里我们有默认的插值,双线性,因为我们没有给出 imshow() 任何插值参数。

我们试试其他的吧。这是“最近的”,没有插值。

imgplot = plt.imshow(img, interpolation="nearest")
图像教程

双三次:

imgplot = plt.imshow(img, interpolation="bicubic")
图像教程

双三次插值常用于放大照片-人们倾向于模糊而不是像素化。

脚本的总运行时间: (0分2.042秒)