Python 绘图

  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数组。

特定图像样例

  https://www.runoob.com/w3cnote/matplotlib-tutorial.html

  https://blog.csdn.net/jasonzhoujx/article/details/81780774

原文地址:https://www.cnblogs.com/qizhou/p/12180157.html