python绘图库有很多,底层的就是matplotlib,另外还有基于matplotlib的更方便,代码可读性更强的库,比如seaborn、plotnine等。各个库之间的对比:

matplotlib

在python下一般使用matplotlib包下的pyplot,所以通常import matplotlib.pyplot as plt方便使用它的绘图函数。下面仅记录matplotlib3.2.0之后的版本。

通用函数

plt.show()

显示绘图窗口。

plt.figure()

创建绘图新窗口并传给fig:

fig = plt.figure()

fig能使用下面绘图、创建子图等函数。不创建新窗口直接plt.function()也能绘图,默认一个窗口。

fig.add_subplot()

给窗口添加子图像,参数有三个,分别是子图像的行、列、索引。两种使用方式:

ax =fig.add_subplot(numbRow, numbCol, plotNum)
ax= fig.add_subplot(111)

前一种是一般的用逗号隔开,明确三个参数。后一种是三个整数参数直接合成一个整数传入,这要求这个整数只能是3位的,这样才能唯一确定用户传入的参数。(比如223,就是把图像划分成2*2的格子,添加一个子图像在第三个格子里)

plt.imsave()

用于保存图像,因为源代码中没有提示,很容易因为传参顺序而出错。用法如下:

plt.imsave(name,img)#先传名字再传img数组

图例

为图像添加图例,在画图函数中添加label属性就行。如:

ax.plot(X,Y,label = '图例')

然后使用legend()函数显示所有的图例,它可以设置图例的位置等参数:

ax.legend(loc='best') #看这个介绍

显示中文(不然可能乱码):

plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

图像标题

ax.set_title('aaa',fontsize=12,color='r')

坐标轴设置

ax.set_xlim([-2, 2])#设置x坐标轴范围
ax.set_ylim([-2, 2])#设置y坐标轴范围
ax.set_xlabel('xxxxxxxxxxx')#设置x坐标轴名称
ax.set_ylabel('yyyyyyyyyyy')#设置y坐标轴名称
ticks= np.arange(-2, 2, 0.3)
ax.set_xticks(ticks)#设置x轴刻度
ax.set_yticks(ticks)#设置y轴刻度
ax.axis('scaled')#设置坐标轴宽高等比于x、y范围
ax.axis('image')#类似于scaled,暂时没发现区别
ax.axis('off')#关闭坐标轴
ax.axis('equal')#图像宽高比例不变,坐标轴范围变
ax.axis('tight')#坐标轴紧紧贴合图像,不设置默认就是这个
ax.axis('square')#设置坐标轴宽高比为1:1,坐标轴跨度取较大的那个

动态图像

plt.cla()
ax.clear()

这两个函数用于将子图清空,配合暂停函数

plt.pause(0.1)

即可实现动态图像。

二维图像

contourf()和contour()

画等高线图。这两个函数差一个字母,但用法一样,区别如下:

python 3维坐标系转换 python建立三维坐标系_python 3维坐标系转换

使用方法:

ax.contourf(X, Y, Z, levels=10, alpha=0.5, cmap='jet')

X是生成网格的X坐标数组(二维数组array,或者matrix),Y是和X相同类型的Y坐标,Z是对应网格的每个格点的函数值数组(也是二维数组array,或者matrix),网格的生成是使用numpy库中的meshgrid()函数。levels是图像中等高线的数量,我这里设置为10。alpha是图像的透明度,介于0~1,我这里设置为0.5半透明。可以设置透明度有个好处就是可以把很多图画在同一个画布上,方便比较。cmap是图像的颜色类型,有很多预设的颜色类型,我这里用一个叫‘jet’的颜色类型,当然也可以自己定义,具体设置网上再找吧。后三项有预设值,可以省略。

效果图:

python 3维坐标系转换 python建立三维坐标系_子图_02

看起来不是很圆润,这是因为我的网格规模就是7*7的,它画图就按照你的网格数量来画,所以有棱有角的。有一点奇怪的就是,网格是有限的,它是怎么画出这么多的等高线的?我猜它应该是线性插值插进去的。反正也就一个图用来看的,不用特别准确。但是如果要准确怎么办?那就把网格设置地密一些!别让等高线的密度比网格的密度大太多就好了。

另外,可以用clabel()这个函数用来标注等高线图的数值:

plt.clabel(C, inline=False, fontsize=12)

C代表刚刚画的等高线图(在用contour()等函数画完以后传给C,C = contour(...)),inline是否画在线内,fontsize数字的大小。

plot()
ax.plot(x, y, ls="-", lw=2, label="plot figure", color='black',alpha=0.5...)

用来画二维面上的点、线。当然也可以在三维的空间里面画,就画在三维坐标系的xOy面上。重要参数介绍:

x: 要画的线的各个点在x轴上的坐标(一维数组)

y: 要画的线的各个点在y轴上的坐标(一维数组或二维数组,第一维规模要和x轴的数组一致,第二维规模的大小就是画线的数量)

ls:折线图的线条风格,这里是一个减号

lw:折线图的线条宽度

label:标记图内容的标签文本

color:颜色

alpha:透明度

还有很多的参数可以调节,这里不一一列举,请看链接。另外,很多其它画线的函数也都支持一些个性化的参数,比如color、alpha、width等等,参数汇总看链接。

hist()
ax.hist(data,bins=50,range=[-5,5],density=True,cumulative=True,rwidth=0.9,orientation = 'vertical')

画频次直方图,重要参数介绍:

x:待统计的一维数据

bins:柱子的数量

range:数据统计的范围

density:是否转换为频率密度图(密度图,乘以范围宽度才是这个范围内数据的频率占比)

cumulative:是否累加,若为真,柱子统计的是小于等于这个值的所有数据。

rwidth:柱子的宽度。

orientation:柱子是垂直还是水平放置。

以下统计一个正态分布的累计柱状图:

python 3维坐标系转换 python建立三维坐标系_python 3维坐标系转换_03

hist2d()与hexbin()

ax.hist2d(x,y,bins=30,cmap='Blues')

二维频次直方图。参数与上述一维频次直方图类似。以下显示二维正态分布抽样频次统计图(旁边的色度条是plt.colorbar(),子图如何加还没研究...):

python 3维坐标系转换 python建立三维坐标系_坐标轴_04

ax.hexbin(x,y,gridsize=30,cmap='Blues')

就是方格变成六边形格,gridsize表示格子大小:

python 3维坐标系转换 python建立三维坐标系_python3d图像处理_05

三维图像

建立三维坐标系

fig = plt.figure() #添加绘图窗口
ax = fig.add_subplot(221,projection = '3d') #窗口内添加3d子图
ax = fig.add_subplot(projection = '3d') #如果只画一张图,可以用这个
plot_surface()
ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap='jet')

画三维的曲面图,并且带有梯度颜色。

X、Y、Z就是每个网格点在对应坐标轴的值,cmap是涂色类型。rstride 是在行上每几个网格点计算一次梯度来图上对应梯度的颜色。cstride 就是列上的。它们越大,画梯度颜色的“补丁”也越大,对应地,“补丁”的数量也越少。如下图,一个是1,一个是2,“补丁”就一个是20,一个是10。

python 3维坐标系转换 python建立三维坐标系_python 3维坐标系转换_06

python 3维坐标系转换 python建立三维坐标系_python 3维坐标系转换_07

外部图像

图像导入与显示

importmatplotlib.pyplot as pltimport pylab #原本在jupyter里才能显示的图片,可以用窗口显示
img=plt.imread("image.jpg") #读取图片,读取到的是:高度×宽度×3RGB 的array数组
fig = plt.figure() #创建窗口
ax = fig.add_subplot(111) #创建子图
ax.imshow(img) #子图中添加图片
pylab.show()#显示窗口
cv2

图像批处理

从压缩包中直接读取图片

importzipfileimportcv2importnumpy as npimportmatplotlib.pyplot as plt
path= 'D:/Datasets/dogs-vs-cats/train.zip'#压缩包地址
with zipfile.ZipFile(path,mode='r') as f:for name inf.namelist():if '.jpg' not inname:continue
print(name)
with f.open(name,mode='r') as image_file:
content= image_file.read() #读取图片
 img = np.asarray(bytearray(content), dtype='uint8') #将jpg格式转码
 img = cv2.imdecode(img, cv2.IMREAD_COLOR)#再转化为BGR格式,注意不是RGB,顺序反了 ,不重组的话在plt颜色显示异常
 b,g,r =cv2.split(img) 
 img= cv2.merge([r,g,b]) #将BGR拆分再重组为RGB
plt.imshow(img) 
plt.show()break

图形拉伸

importcv2
cv2.resize(img,(h,w),interpolation=0)

将存在数组中的图像拉伸成h高,w宽。interpolation=0表示最近邻插值,不作平滑处理。其它插值参数(interpolation)请看链接。

seaborn
import seaborn as sns

seaborn简化了matplotlib的绘图操作,并且让图像更精美,绘制matplotlib图像时,使用sns.set(),可让图像更具特色。

mayavi
import mayavi.mlab as mlab

mayavi是专门绘制三维图形的库,虽然matplotlib也能绘制,但是matplotlib并不支持光线追踪,所以没有遮挡的效果。绘制各种图像的函数和matplotlib差不多。mayavi文档、简易实例。

mesh()

绘制三维图形表面,用法和matplotlib的plot_surface类似,但是创建网格时推荐用mgrid,meshgrid的索引顺序不对。

mlab.mesh(x, y, z )#绘制光滑表面
mlab.mesh(x, y, z, representation="wireframe", line_width=1.0)#绘制线而不是表面

下图画了一个卷起来的彩带:

python 3维坐标系转换 python建立三维坐标系_子图_08

代码如下:

importmayavi.mlab as mlabimportnumpy as np
roll= 10r= 0.5w= 0.8theta= np.linspace(np.pi*0.5,np.pi*2*roll,num=roll*100)[:,np.newaxis]
h= np.linspace(-1,1,num=2)[np.newaxis,:]+0.5x= y = z =np.zeros([len(theta),len(h[0,:])])
x= x + np.cos(theta)*theta*r/np.pi
y= y + np.sin(theta)*theta*r/np.pi
z= z + h - theta*w/np.piprint(y.shape,z.shape)
mlab.mesh(x, y, z)#绘制光滑表面
mlab.show()
plot3d()

画三维坐标系中的曲线。用法和matplotlib的plot类似。同样推荐用mgrid创建网格。

mlab.plot3d(x,y,z)
numpy

用numpy的一些函数生成格式化的绘图数据。

linspace()

linspace(a, b, n),传回一个在a、b之间的插值列表(包括a、b),插值的数量是n。这个差值列表类型是array,而不是list,array里的数据类型是固定的,都是float。而列表list里面则并不是固定的,里面可以存任何东西。array是numpy下定义的一个类型,这个类型类似C++的数组,随机查找很快。所以处理大批量同类数据的时候,最好使用array类型。

具体使用和其他参数:

meshgrid()

用于生成对应列表的网格(网格也是用列表存,二维网格是对每一维来说是二维列表,三维网格对每一维来说是三维列表),用于绘制梯度图等。使用方法如下:

1. [X, Y] = meshgrid(x,y)或者python还支持X,Y = meshgrid(x,y),不加方括号也行,当然直接A = meshgrid(x,y),传给一个值也行,就是后面不太好处理。

2. [X, Y] = meshgrid(x)与[X, Y] = meshgrid(x, x)是等同的

3. [X, Y, Z] = meshgrid(x, y, z)生成三维的网格

生成的网格索引顺序在二维X、Y中是先Y再X,三维X、Y、Z中顺序是Y、X、Z。例如,在三维网格中,如果要获得x[2],y[7],z[3]位置的Y轴坐标,就是Y[7][2][3]。在二维网格中,如果要获得x[2],y[7]位置的X轴坐标,就是X[7][2]。

下图显示8*3的网格的X的列表:

python 3维坐标系转换 python建立三维坐标系_hg_09

mgrid

与meshgrid类似,同样能生成对应的网格。但是它并不是函数,而是以索引的形式使用的属性,并且还可以生成类似的2维以上的网格。另外,它和meshgrid的不同之处在于它们生成的网格的索引方式是相反的。推荐使用mgrid,它更容易理解。以下是实例:

importnumpy as np
a= np.mgrid[0:10:2,0:10:1]print(a)

python 3维坐标系转换 python建立三维坐标系_hg_10

索引的第二个冒号传入整数表示数的间隔,不包含最后一个数。传入复整数表示数的个数,比如5j表示范围内5个数,包含最后一个数。

特定图像样例