Python 之 Numpy库以及Matplotlib库的学习
Numpy(Numerical Python)是Python中一个非常常用的第三方科学计算库。Numpy提供了python对多维数组对象的支持:ndarray,具有矢量运算能力,快速、节省空间。numpy支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
Matplotlib(数据可视化)是Python中一个能够提供数据绘图功能的第三方库。其pyplot 子库主要用于实现各种数据展示图形的绘制,包括线性图(折线图,函数图)、柱形图、饼图等基础而直观的图形,在平常的开发当中需要绘图时就非常有用了。
引用方式:
1 import numpy as np 2 import matplotlib.pyplot as plt 3 #以下三行代码是为了正确显示中文字体,更改了默认设置,'SimHei'表示黑体字。 4 import matplotlib 5 matplotlib.rcParams['font.family'] = 'SimHei' 6 matplotlib.rcParams['font.sans-serif'] = ['SimHei']
as 保留字与import 一起使用能够改变后续代码中库的命名空间,有助于提高代码可读性。简单说,在后续程序中,np 代替numpy,plt 将代替matplotlib.pyplot。
一、Numpy
使用Numpy库,可以执行以下操作:
- 数组的算数和逻辑运算。
- 傅立叶变换和用于图形操作的例程。
- 与线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。
- Ndarray对象
numpy 库处理的最基础数据类型是由同种元素构成的多维数组(ndarray),简称“数组”。数组中所有元素的类型必须相同,数组中元素可以用整数索引,序号从0开始。ndarray 类型的维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。一维数组的秩为1,二维数组的秩为2,二维数组相当于由两个一维数组构成。
常用的创建数组函数如下:
创建了数组后,ndarray类型有一些基本属性:
代码示例:
>>> import numpy as np
>>> a = np.ones((3,3))
>>> print(a)
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
>>> a.ndim
2
>>> a.shape
(3, 3)
>>> a.dtype
dtype('float64')
ndarray类的形态操作方法:
ndarray类的索引和切片:
与列表的相同,不过需要注意的是数组切片得到的是原始数组的视图,所有修改都会直接反映到源数组。如果需要得到的ndarray 切片的一份副本,需要进行复制操作,比如 arange[5:8].copy()。
- Numpy库的运算函数
这些函数中,输出参数y可选,如果没有指定,将创建并返回一个新的数组保存计算结果;如果指定参数,则将结果保存到参数中。例如,两个数组相加可以简单地写为a+b,而np.add(a, b, a)则表示a+=b。
- where()函数是三元表达式x if condition else y 的矢量版本。
- 这些函数将返回一个布尔数组,它包含两个数组中对应元素值的比较结果,如下:
>>> np.less([1, 2],[2,2]) array([ True, False], dtype=bool)
其他运算函数:
二、Matplotlib
- Matplotlib.pyplot 库(plt 子库提供了一批操作和绘图函数,每个函数代表对图像进行的一个操作,比如创建绘图区域、添加标注或者修改坐标轴等)
plt库的绘图区域函数:
- 使用figure()函数创建一个全局绘图区域,并且使它成为当前的绘图对象,figsize参数可以指定绘图区域的宽度和高度,单位为英寸。鉴于figure()函数参数较多,这里采用指定参数名称的方式输入参数。
>>> plt.figure(figsize = (8, 5))
- axes()默认创建一个subplot(111)坐标系,参数rec = [left,bottom,width,height]中四个变量的范围都为[0,1],表示坐标系与全局绘图区域的关系;axisbg 指背景色,默认为white。
>>> plt.axes([0.1, 0.1, 0.7, 0.3], axisbg = 'y')
>>> plt.show() - subplot()都用于在全局绘图区域内创建子绘图区域,其参数表示将全局绘图区域分成nrows 行和ncols 列,并根据先行后列的计数方式在plot_number 位置生成一个坐标系,实例代码如下,三个参数关系如下图所示。其中,全局绘图区域被风割成3x2 的网格,其中,在第4 个位置绘制了一个坐标系。
>>> plt.subplot(324)
>>> plt.show()
plt库的读取和显示函数:
plt库的基础图表函数:
- plot()函数是用于绘制直线的最基础函数,调用方式很灵活,x 和y 可以是numpy计算出的数组,并用关键字参数指定各种属性。其中,label 表示设置标签并在图例(legend)中显示,color 表示曲线的颜色,linewidth 表示曲线的宽度。在字符串前后添加"$"符号,matplotlib 会使用其内置的latex 引擎绘制的数学公式。
示例:
- plt库的坐标轴(plt 库有两个坐标体系;图像坐标和数据坐标。图像坐标将图像所在区域左下角视为原点,将x 方向和y 方向长度设定为1。整体绘图区域有一个图像坐标,每个axes()和subplot()函数产生的子图也有属于自己的图像坐标。axes()函数参数rect 指当前产生的子区域相对于整个绘图区域的图像坐标。数据坐标以当前绘图区域的坐标轴为参考,显示每个数据点的相对位置)
坐标轴设置函数:
>>> plt.plot([1, 2, 4], [1, 2, 3]) >>> plt.axis() #获得当前坐标轴范围 (1.0, 4.0, 1.0, 3.0) >>> plt.axis([0, 5, 0, 8]) #4个变量分别是[xmin, xmax, ymin, ymax]
标签设置函数:
示例:
区域填充函数:
示例:
三、雷达图绘制
1 import numpy as np 2 import matplotlib.pyplot as plt 3 import matplotlib 4 matplotlib.rcParams['font.family'] = 'SimHei' 5 matplotlib.rcParams['font.sans-serif'] = ['SimHei'] 6 labels = np.array(['第一周','第二周','第三周','第四周','第五周','第六周']) 7 nAttr = 6 8 data = np.array([100, 98, 98, 100, 96, 94]) #成绩值 9 angles = np.linspace(0, 2*np.pi, nAttr, endpoint=False) 10 data = np.concatenate((data, [data[0]])) 11 angles = np.concatenate((angles, [angles[0]])) #这两行代码作用是进行数组的拼接 12 fig = plt.figure(facecolor="white") 13 plt.subplot(111, polar=True) 14 plt.plot(angles, data, 'bo-', color = 'g', linewidth = 2) 15 plt.fill(angles, data, facecolor = 'g', alpha = 0.25) 16 plt.thetagrids(angles*180 / np.pi, labels) 17 plt.figtext(0.52, 0.95, '小明的成绩表', ha = 'center') 18 plt.grid(True) 19 plt.savefig('Grade.JPG') 20 plt.show()
效果如下:
四、自定义手绘风
1 from PIL import Image 2 import numpy as np 3 vec_el=np.pi/2.2 #光源的俯视角度,弧度值 4 vec_az=np.pi/4. #光源的方位角度,弧度值 5 depth=10. #(0-100) 6 im=Image.open("pic.jpg").convert('L') 7 a=np.asarray(im).astype('float') 8 grad=np.gradient(a) #取图像灰度的梯度值 9 grad_x,grad_y=grad #分别取横纵图像梯度值 10 grad_x=grad_x*depth/100. 11 grad_y=grad_y*depth/100. 12 dx=np.cos(vec_el)*np.cos(vec_az) #光源对x轴的影响 13 dy=np.cos(vec_el)*np.sin(vec_az) #光源对y轴的影响 14 dz=np.sin(vec_el) #光源对z轴的影响 15 A=np.sqrt(grad_x**2+grad_y**2+1.) 16 uni_x=grad_x/A 17 uni_y=grad_y/A 18 uni_z=1./A 19 a2=255*(dx*uni_x+dy*uni_y+dz*uni_z) #光源归一化 20 a2=a2.clip(0,255) 21 im2=Image.fromarray(a2.astype('uint8')) #重构图像 22 im2.save('pic_handdraw.jpg')