1.密度图和等高线

我们可以利用 Matplotlib 的三个函数来绘制等高线,用 plt.contour 画等高线;用 plt.contourf 画带有填充的等高线图的色彩;用 plt.imshow 显示图像。

先来看一段书上的示例代码:

1
2
3
4
5
6
7
8
9
10
11
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
def f(x,y):
return np.sin(x)**10+np.cos(10+y*x)*np.cos(x)
x = np.linspace(0,5,50)
y = np.linspace(0,5,40)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
plt.contour(X,Y,Z,colors='blue')

1

2.np.meshgrid

来搞明白 np.meshgrid 这个函数是干嘛的,就直接看帮助文档了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#Return coordinate matrices from coordinate vectors.
#从坐标向量返回坐标矩阵。
indexing : {'xy', 'ij'}, optional
Cartesian ('xy', default) or matrix ('ij') indexing of output.
#输出笛卡尔,默认索引值为"xy"或矩阵"ij"。
xv, yv = np.meshgrid(x, y, sparse=False, indexing='ij')
for i in range(nx):
for j in range(ny):
# treat xv[i,j], yv[i,j]
xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy')
for i in range(nx):
for j in range(ny):
# treat xv[j,i], yv[j,i]
sparse : bool, optional
If True a sparse grid is returned in order to conserve memory.
Default is False.
#Examples
#--------
>>> nx, ny = (3, 2)
>>> x = np.linspace(0, 1, nx)
>>> y = np.linspace(0, 1, ny)
>>> xv, yv = np.meshgrid(x, y)
>>> xv
array([[ 0. , 0.5, 1. ],
[ 0. , 0.5, 1. ]])
>>> yv
array([[ 0., 0., 0.],
[ 1., 1., 1.]])
# make sparse output arrays(创建稀疏输出数组)
>>> xv, yv = np.meshgrid(x, y, sparse=True)
>>> xv
array([[ 0. , 0.5, 1. ]])
>>> yv
array([[ 0.],[ 1.]])

官方的帮助文件大概就是这样,具体的示例看下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#1.索引为 xy ,sparse 的值的 False
import numpy as np
x1 = [1,2,3]
y1 = [4,5]
X1,Y1 = np.meshgrid(x1,y1,indexing='xy',sparse=False)
print(X1)
print(Y1)

#2.索引为 xy ,sparse 的值的 True
import numpy as np
x3 = [1,2,3]
y3 = [4,5]
X3,Y3 = np.meshgrid(x3,y3,indexing='xy',sparse=True)
print(X3)
print(Y3)

#3.索引为 ij ,sparse 的值的 False
import numpy as np
x2 = [1,2,3]
y2 = [4,5]
X2,Y2 = np.meshgrid(x2,y2,indexing='ij',sparse=False)
print(X2)
print(Y2)

#4.索引为 ij ,sparse 的值的 True
import numpy as np
x4 = [1,2,3]
y4 = [4,5]
X4,Y4 = np.meshgrid(x4,y4,indexing='ij',sparse=True)
print(X4)
print(Y4)

把每一个输出的结果放在一起比较:

参数 输出
#1.索引为 xy ,sparse 的值的 False x1 [[1 2 3] [1 2 3]] y1[[4 4 4] [5 5 5]]
#2.索引为 xy ,sparse 的值的 True x2[[1 2 3]] y2[[4] [5]]
#3.索引为 ij ,sparse 的值的 False x3[[1 1] [2 2] [3 3]] y3 [[4 5] [4 5] [4 5]]
#4.索引为 ij ,sparse 的值的 True x4[[1] [2] [3]] y4[[4 5]]

从结果集中我们可以看出 xy 和 ij 模式的差别,为了方便理解,我画了张图。

而加上 sparse = True 的作用就是将重复的行列省去,以节省内存,但是值得注意的是,尽管没有输出,我们还是可以取到省略掉的值。

3.plt.contour/plt.contourf

书上写的太少,还是上官方文档来理解怎么用吧。

1
2
3
4
#Signature: plt.contour(*args, data=None, **kwargs)
#Docstring:
#Plot contours.
#绘制轮廓
参数解析
x,y,z
1
2
3
4
X, Y : array-like, optional
#The coordinates of the values in *Z*. Z的坐标
Z : array-like(N, M)
#The height values over which the contour is drawn. 绘制轮廓的高度

x,y,z 就是分别设置相应的位置参数,而且表示的维度类型必须匹配。

levles
1
2
levels : int or array-like, optional
#Determines the number and positions of the contour lines / regions.

levels 是用来确定轮廓线/区域的数量和位置的。如果为 int(n) 则使用 n 个数据间隔,绘制 n+1 个等高线,水平高度是自动选择的。

部分其他参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
corner_mask : bool, optional #启用/禁用边角遮罩,默认True
colors : color string or sequence of colors, optional #颜色
alpha : float, optional #透明度
cmap : str or `.Colormap`, optional #色彩图,colors 参数可覆盖效果
norm : `~matplotlib.colors.Normalize`, optional #缩放色阶值映射到规范颜色范围
vmin, vmax : float, optional #覆盖默认的颜色缩放比例
origin : {*None*, 'upper', 'lower', 'image'}, optional #确定 z 的方向和确切位置
# - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner.
#- 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.
#- 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left corner.
#- 'image': Use the value from :rc:`image.origin`.
extend : {'neither', 'both', 'min', 'max'}, optional, default: 'neither' #确定轮廓线外的值的颜色
linewidths : float or sequence of float, optional #线宽
linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional #线型

其实这些参数加上以后的效果好像并不是太明显,具体的用法后续在讨论。

上图的间隙之间还是有点大,我们可以使用 plt.contourf 函数来进行等高线的填充。

1
2
3
4
5
6
7
8
9
10
11
12
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
def f(x,y):
return np.sin(x)**10+np.cos(10+y*x)*np.cos(x)
x = np.linspace(0,5,50)
y = np.linspace(0,5,40)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
plt.contourf(X,Y,Z,20,cmap='Blues')
plt.colorbar() #显示颜色条

其实这样只能大致的看到,深色的地方是“波峰”,浅色的地方是“波谷”。但是,数据的可视化并没有特别明了。

我们可以修改显示的透明度,然后加上线条,看下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
def f(x,y):
return np.sin(x)**10+np.cos(10+y*x)*np.cos(x)
x = np.linspace(0,5,50)
y = np.linspace(0,5,40)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
contours = plt.contour(X,Y,Z,3,colors='black')
plt.clabel(contours,inline=True,fontsize=8)
plt.imshow(Z,extent=[0,5,0,5],origin='lower',cmap='Blues',alpha=0.5)
plt.colorbar()

5

这样来看就清楚了很多,下面来就上面用到的函数进行参数的说明。

4.plt.clabel

1
2
3
4
#Signature: plt.clabel(CS, *args, **kwargs)
#Docstring:
#Label a contour plot.
#便签轮廓图
主要参数解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cs : `.ContourSet`
#The ContourSet to label.
levels : array-like, optional
#A list of level values, that should be labeled. The list must be
#a subset of ``cs.levels``. If not given, all levels are labeled.
fontsize : string or float, optional
#Size in points or relative size e.g., 'smaller', 'x-large'.
#See `.Text.set_size` for accepted string values.
colors : color-spec, optional
#The label colors:
inline : bool, optional
#If ``True`` the underlying contour is removed where the label is
#placed. Default is ``True``.
inline_spacing : float, optional
#Space in pixels to leave on each side of label when
#placing inline. Defaults to 5.
fmt : string or dict, optional

CS 参数就是要设置标签的轮廓线;levels 可以设置添加标签的级别,若不给出,则所以的轮廓线都加上标签;fontsize 设置字体大小;colors 标签色彩;inline 默认为 True 底部轮廓是从标签上移除的;inline_spacing 像素空间在标签的每一边。

5.plt.imshow

1
2
3
4
5
6
7
8
plt.imshow(X,cmap=None,norm=None,aspect=None,
interpolation=None,alpha=None,vmin=None,vmax=None,
origin=None,extent=None,shape=<deprecated parameter>,
filternorm=1,filterrad=4.0,imlim=<deprecated parameter>,
resample=None,url=None,*,data=None,**kwargs,)
Docstring:
#Display an image, i.e. data on a 2D regular raster.
#显示图像,二维常规光栅上的数据

对这个函数进行参数解析前,先来看一下,只使用该函数时画出的图是什么样子的。

1
2
3
4
5
6
7
8
9
10
11
12
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
def f(x,y):
return np.sin(x)**10+np.cos(10+y*x)*np.cos(x)
x = np.linspace(0,5,50)
y = np.linspace(0,5,40)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
plt.imshow(Z,extent=[0,5,0,5],origin='lower',cmap='Blues')
plt.colorbar()

5

可以看到图像有点被像素画了,这就是 imshow 函数的作用。

主要参数解析
1
2
3
4
5
X : array-like or PIL image
#The image data. Supported array shapes are:
- (M, N): an image with scalar data. The data is visualized
- (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),

第一个参数用来定义图像数据,支持三种形式。

  • -(M,N):具有标量数据的图像。数据是可视化的
  • -(M,N,3):具有RGB值(0-1浮点或0-255整数)的图像
  • -(M,N,4):具有RGBA值(0-1浮点或0-255 int)的图像
1
2
3
4
5
6
7
8
9
10
11
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
x = np.random.randn(5)
y = np.random.randn(5)
print(x,y)
plt.imshow((x,y),extent=[0,5,0,5],origin='lower',cmap='Blues')
plt.colorbar()
##x [-0.49486504 -0.99105513 3.27752515 0.02882249 0.04733611]
##y [ 0.88204904 -0.72641683 0.95912824 -0.36288482 1.53353979]

7

1
2
3
4
aspect : {'equal', 'auto'} or float, optional
#Controls the aspect ratio of the axes.
#equal:确保宽高比为1
#auto:轴报错固定,方向调整为使数据符合坐标轴

用来控制坐标轴的横纵比。

1
2
3
4
5
6
7
8
9
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
x = np.random.randn(5)
y = np.random.randn(5)
print(x,y)
plt.imshow((x,y),extent=[0,5,0,5],origin='lower',cmap='Blues',aspect='0.1')
plt.colorbar()

8

1
2
3
4
5
6
7
interpolation : str, optional
#Supported values are 'none', 'nearest', 'bilinear', 'bicubic',
#'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser',
#'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc',
#'lanczos'.
alpha : scalar, optional
#The alpha blending value, between 0 (transparent) and 1

interpolation 这个参数看了翻译没看懂,来看一下图像的输出效果对比一下:

1
2
3
4
5
6
7
8
9
10
11
12
#spline36
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
x = np.random.randn(5)
y = np.random.randn(5)
print(x,y)
plt.imshow((x,y),extent=[0,5,0,5],origin='lower',cmap='Blues',interpolation='spline36')
plt.colorbar()
## x[-0.2397638 -0.89091552 0.60802011 2.20626021 -0.28450459]
## y[-1.78338935 1.26923305 0.49671364 -0.72569517 1.36340109]

9

1
2
3
4
5
6
7
8
9
10
11
12
#spline16
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
x = np.random.randn(5)
y = np.random.randn(5)
print(x,y)
plt.imshow((x,y),extent=[0,5,0,5],origin='lower',cmap='Blues',interpolation='spline16')
plt.colorbar()
## x[ 2.52507531 1.66726626 0.41991259 0.70137512 -0.55313458]
## y[ 0.27079771 -0.1188416 3.21609489 -0.11450694 -0.5017201 ]

10

其实我们可以从上两个示例中看出来,这个参数改变了他的像素模式,部分边缘进行了变化。

1
2
3
4
5
6
7
8
origin : {'upper', 'lower'}, optional
#Place the [0,0] index of the array in the upper left or lower left
#corner of the axes. The convention 'upper' is typically used for
#matrices and images.
#If not given, :rc:`image.origin` is used, defaulting to 'upper'.
extent : scalars (left, right, bottom, top), optional
#The bounding box in data coordinates that the image will fill.
#The image is stretched individually along x and y to fill the box.

origin 和 extent 都是对坐标轴的范围进行控制的。origin 控制原点坐标对应的数组[0,0]的位置。默认 upper,extent 图像将填充的数据坐标中的边界框。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('seaborn-white')
import numpy as np
x = np.random.randn(2)
y = np.random.randn(2)
X,Y = np.meshgrid(x,y)
Z = X+Y
print(X,Y,Z)
contents = plt.contour(X,Y,Z,3,colors='black')
plt.clabel(contents,inline=True,fontsize=15)
plt.imshow((x,y),extent=[-2,2,-2,2],origin='lower',cmap='Blues')
plt.colorbar()
## x[[-1.01180067 -1.71479387][-1.01180067 -1.71479387]]
## y[[-0.80430271 -0.80430271][-0.64073178 -0.64073178]]
## z[[-1.81610338 -2.51909658][-1.65253244 -2.35552565]]

11