mpl等高线与隐式函数的绘制

当我们想绘制一个隐式函数,比如著名的椭圆曲线y^2=x^3+ax+b,我们主要有两种方法:一是使用参数方程,而是使用等高线(plt.contour)绘图。

但参数方程的转换未免太过麻烦;所以我们注重更便捷的contour函数。

 

在绘图之前,要先了解一下numpy的meshgrid()函数。

mpl有个grid()函数,作用是为子图添加网格线。而meshgrid()函数接受坐标向量,返回坐标矩阵;它将构成一张网格点图。

meshgrid(*xi, copy=True, sparse=False, indexing='xy')

主要参数说明:

参数 说明
    x1, x2,..., xn : array_like 表示网格坐标的一维数组
    indexing : {'xy', 'ij'}, optional 设定笛卡尔('xy',默认)或矩阵('ij')的输出索引。
    sparse : bool, optional 如果为True,则返回一个稀疏网格以节省内存。
    copy : bool, optional 如果为False,则返回原始数组的视图,以节省内存。默认为True。
点击查看代码
import numpy as np
import matplotlib.pyplot as plt
import pprint as pp
y,x=np.ogrid[0:10:100j,0:10:100j]
plt.grid()#网格线
a=np.linspace(0,10,5)#横坐标向量
pp.pprint(a)
b=np.linspace(4,6,2)#纵坐标向量
pp.pprint(b)
X,Y=np.meshgrid(a,b,indexing="xy")#返回坐标矩阵
pp.pprint(X)
pp.pprint(Y)
pp.pprint(X*Y)
plt.plot(X,Y,"o")

'''
生成了2行5列共10个网格点。相当于横纵坐标的全排列。

a=array([ 0. ,  2.5,  5. ,  7.5, 10. ])
b=array([4., 6.])
X=array([[ 0. ,  2.5,  5. ,  7.5, 10. ],
       [ 0. ,  2.5,  5. ,  7.5, 10. ]])
Y=array([[4., 4., 4., 4., 4.],
       [6., 6., 6., 6., 6.]])
X*Y=array([[ 0., 10., 20., 30., 40.],
       [ 0., 15., 30., 45., 60.]])
'''

如果我们想生成40行50列网格点,只需:

a=np.linspace(0,100,50)
b=np.linspace(0,100,40)
X,Y=np.meshgrid(a,b,indexing="xy")

 

下面来看contour函数。

contour(*args, data=None, **kwargs)

主要参数说明:

参数 说明
    X, Y : array-like, optional

Z中值的坐标。必须是与Z数组形状相同的二维数组;如果是一维数组,则必须满足len(X) == M,len(Y) == N。

如果为空,系统自动赋值;``X = range(M)``, ``Y = range(N)``.

    Z : array-like(N, M) 轮廓线的高度值。即方程。
    levels : int or array-like, optional 确定等高线/区域的数量和位置。
    extent : (x0, x1, y0, y1), optional 确定范围。
import numpy as np
import matplotlib.pyplot as plt
plt.grid()
plt.title("x*y=1")

a=np.linspace(0,100,50)
b=np.linspace(0,100,40)
X,Y=np.meshgrid(a,b,indexing="xy")
cs=plt.contour(X,Y,X*Y,6#将函数取值范围分为6个区间。
               )
plt.clabel(cs)#为等值线标上对应的值
plt.show()

import numpy as np
import matplotlib.pyplot as plt
#y,x = np.ogrid[-10:10:200j, -5:5:200j]这行代码可以替换掉下面三行代码。

a=np.linspace(-5,5,200)
b=np.linspace(-10,10,200)
x,y=np.meshgrid(a,b)

f = y**2-x**3+5*x#椭圆曲线的方程
fig,ax=plt.subplots()
ax.grid()
ax.set(xlabel="x",ylabel="y")
extent = [np.min(x), np.max(x), np.min(y), np.max(y)]#限定范围
cs = plt.contour(f,extent=extent,
                 levels=[0,1,5,10],#绘制了四条曲线。它们的“高度”分别是:0,4,5,10
                 colors=["b", "r","g","k"],#颜色
                 linestyles=["solid", "-","-"],#一个东西:实线。不填也没关系,系统会默认赋值。
                 linewidths=[2,2,2])#线宽
#plt.axis("equal")
plt.clabel(cs)
plt.show()

这样,就绘制出了隐函数(椭圆曲线)的图像。

 

最后,我们再了解一下np.ogrid()这个函数。

上面一个例子里,我说 y,x = np.ogrid[-10:10:200j, -5:5:200j]这行代码可以替换掉下面三行代码。我们来看它做了什么。

#复数步长即等分。
y, x = np.ogrid[-10:10:200j, -5:5:200j]#x是第二个数组 y是第一个数组
print(type(x),x.ndim,x.shape,x.size)
print(type(y),x.ndim,y.shape,y.size)

'''
<class 'numpy.ndarray'> 2 (1, 200) 200 #这是x,第二个数组
<class 'numpy.ndarray'> 2 (200, 1) 200
'''

这个函数返回了两个数组,第一个是(200*1)的二维数组数组(第一维为200,第二维为1);

第二个是(1*200)的二维数组数组(第一维为1,第二维为200);所以把第二个数组作为x轴,第一个为y轴。

x=np.ogrid[0:100:5]
print(x,x.shape)

'''
参数只有一维时,与arange函数没什么区别。
[ 0  5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95] (20,)
'''

a=np.ogrid[0:10:2,0:10:2,0:10:2,]


pp.pprint(a[0].shape)
pp.pprint(a[1].shape)
pp.pprint(a[2].shape)
pp.pprint(a[0])
pp.pprint(a[1])
pp.pprint(a[2])

'''
这个例子就很一目了然了。参数有三个维度时,该函数返回三个数组,形状如下: 
(5, 1, 1)
(1, 5, 1)
(1, 1, 5)
可以认为依次沿着第一,第二,第三(z,y,x轴)构造数组。
array([[[0]],

       [[2]],

       [[4]],

       [[6]],

       [[8]]])
array([[[0],
        [2],
        [4],
        [6],
        [8]]])
array([[[0, 2, 4, 6, 8]]])

'''

 

posted @ 2021-10-03 21:24  zeroy610  阅读(236)  评论(0)    收藏  举报