python绘图库有很多,底层的就是matplotlib,另外还有基于matplotlib的更方便,代码可读性更强的库,比如seaborn、plotnine等。各个库之间的对比:
https://www.zhihu.com/question/39684179
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(numbRow numbCol plotNum)
前一种是一般的用逗号隔开,明确三个参数。后一种是三个整数参数直接合成一个整数传入,这要求这个整数只能是3位的,这样才能唯一确定用户传入的参数。(比如223,就是把图像划分成2*2的格子,添加一个子图像在第三个格子里)
图例
为图像添加图例,在画图函数中添加label属性就行。如:
ax.plot(X,Y,label = '图例')
然后使用legend()函数显示所有的图例,它可以设置图例的位置等参数:
ax.legend(loc='best') #看这个介绍https://blog.csdn.net/qq_35240640/article/details/89478439
显示中文(不然可能乱码):
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
图像标题
ax.set_title('aaa',fontsize=12,color='r')
二维图像
contourf()和contour()
画等高线图。这两个函数差一个字母,但用法一样,区别如下:
使用方法:
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’的颜色类型,当然也可以自己定义,具体设置网上再找吧。后三项有预设值,可以省略。
效果图:
看起来不是很圆润,这是因为我的网格规模就是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:透明度
还有很多的参数可以调节,不一一列举,看链接:
https://blog.csdn.net/dss_dssssd/article/details/82810630
另外,和它一样,很多其它画线的函数也都支持一些个性化的参数(比如color、alpha、width等等),参数汇总看链接:
https://blog.csdn.net/qq_34940959/article/details/78488208
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:柱子是垂直还是水平放置。
以下统计一个正态分布的累计柱状图:
hist2d()与hexbin()
ax.hist2d(x,y,bins=30,cmap='Blues')
二维频次直方图。参数与上述一维频次直方图类似。以下显示二维正态分布抽样频次统计图(旁边的色度条是plt.colorbar(),子图如何加还没研究...):
ax.hexbin(x,y,gridsize=30,cmap='Blues')
就是方格变成六边形格,gridsize表示格子大小:
三维图像
建立三维坐标系
添加绘图窗口:
fig = plt.figure()
窗口内添加3d子图:
ax = fig.add_subplot(221,projection = '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。
外部图像
图像导入与显示
import matplotlib.pyplot as plt import pylab #原本在jupyter里才能显示的图片,可以用窗口显示 img=plt.imread("image.jpg") #读取图片,读取到的是:高度×宽度×3RGB 的array数组 fig = plt.figure() #创建窗口 ax = fig.add_subplot(111) #创建子图 ax.imshow(img) #子图中添加图片 pylab.show() #显示窗口
图从压缩包中直接读取图片
import zipfile import cv2 import numpy as np import matplotlib.pyplot as plt path = 'D:/Datasets/dogs-vs-cats/train.zip'#压缩包地址 with zipfile.ZipFile(path,mode='r') as f: for name in f.namelist(): if '.jpg' not in name: 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
图形拉伸
import cv2
cv2.resize(img,(h,w))
把(height,width,3)的三维图像数组拉伸成h高,w宽,直接取像素拉伸,并没有平滑处理。
seaborn
import seaborn as sns
seaborn简化了matplotlib的绘图操作,并且让图像更精美,绘制matplotlib图像时,使用sns.set(),可让图像更具特色。
numpy
用numpy的一些函数生成格式化的绘图数据。
linspace()
linspace(a, b, n),传回一个在a、b之间的插值列表(包括a、b),插值的数量是n。这个差值列表类型是array,而不是list,array里的数据类型是固定的,都是float。而列表list里面则并不是固定的,里面可以存任何东西。array是numpy下定义的一个类型,这个类型类似C++的数组,随机查找很快。所以处理大批量同类数据的时候,最好使用array类型。
具体使用和其他参数:
https://www.cnblogs.com/antflow/p/7220798.html
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的列表:
zeros()
生成全0的数组,传入数组的规模,一般用来初始化。如:
Z = zeros([4,5,6])
赋值给Z一个规模分别是4、5、6的三维全0数组。