Python 可视化与图像处理
<p> python绘图库有很多,底层的就是matplotlib,另外还有基于matplotlib的更方便,代码可读性更强的库,比如seaborn、plotnine等。各个库之间的对比:</p><p> https://www.zhihu.com/question/39684179</p>
<h1>matplotlib</h1>
<p> 在python下一般使用matplotlib包下的<span style="text-decoration: underline"><strong>pyplot</strong></span>,所以通常<strong>import matplotlib.pyplot as plt</strong>方便使用它的绘图函数。下面仅记录matplotlib3.2.0之后的版本。</p>
<h2>通用函数</h2>
<h3>plt.show()</h3>
<p> 显示绘图窗口。</p>
<h3>plt.figure()</h3>
<p> 创建绘图新窗口并传给fig:</p>
<div class="cnblogs_code">
<pre>fig = plt.figure()</pre>
</div>
<p> fig能使用下面绘图、创建子图等函数。不创建新窗口直接plt.function()也能绘图,默认一个窗口。</p>
<h3>fig.add_subplot()</h3>
<p> 给窗口添加子图像,参数有三个,分别是子图像的行、列、索引。两种使用方式:</p>
<div class="cnblogs_code">
<pre>ax =<span style="color: rgba(0, 0, 0, 1)"> fig.add_subplot(numbRow, numbCol, plotNum)
ax </span>= fig.add_subplot(111)</pre>
</div>
<p> 前一种是一般的用逗号隔开,明确三个参数。后一种是三个整数参数直接合成一个整数传入,这要求这个整数只能是3位的,这样才能唯一确定用户传入的参数。(比如223,就是把图像划分成2*2的格子,添加一个子图像在第三个格子里) </p>
<h3>fig.subplots()</h3>
<p> 同时创建窗口和多个子图像的方法,用法如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> matplotlib.pyplot as plt
fig, axs </span>= plt.subplots(2,2<span style="color: rgba(0, 0, 0, 1)">)
axs.plot(,)
plt.show()</span></pre>
</div>
<p> fig为创建的窗口对象,axs为多个子图对象的二维数组,因此可以通过索引获取子图对象。</p>
<h3>plt.imsave()</h3>
<p> 用于保存图像,因为源代码中没有提示,很容易因为传参顺序而出错。用法如下:</p>
<div class="cnblogs_code">
<pre>plt.imsave(name,img)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">先传名字再传img数组</span></pre>
</div>
<h3>图例</h3>
<p> 为图像添加图例,在画图函数中添加label属性就行。如:</p>
<div class="cnblogs_code">
<pre>ax.plot(X,Y,label = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">图例</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p> 然后使用legend()函数显示所有的图例,它可以设置图例的位置等参数:</p>
<div class="cnblogs_code">
<pre>ax.legend(loc=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">best</span><span style="color: rgba(128, 0, 0, 1)">'</span>) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">看这个介绍https://blog.csdn.net/qq_35240640/article/details/89478439</span></pre>
</div>
<p> 显示中文(不然可能乱码):</p>
<div class="cnblogs_code">
<pre>plt.rcParams[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">font.sans-serif</span><span style="color: rgba(128, 0, 0, 1)">'</span>]=[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">SimHei</span><span style="color: rgba(128, 0, 0, 1)">'</span>] <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">用来正常显示中文标签</span>
plt.rcParams[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">axes.unicode_minus</span><span style="color: rgba(128, 0, 0, 1)">'</span>]=False <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">用来正常显示负号</span></pre>
</div>
<h3>图像标题</h3>
<div class="cnblogs_code">
<pre>ax.set_title(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">aaa</span><span style="color: rgba(128, 0, 0, 1)">'</span>,fontsize=12,color=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<h3>坐标轴设置</h3>
<p> 坐标轴一般设置</p>
<div class="cnblogs_code">
<pre>ax.set_xlim([-2, 2])<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置x坐标轴范围</span>
ax.set_ylim([-2, 2])<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置y坐标轴范围</span>
ax.set_xlabel(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">xxxxxxxxxxx</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置x坐标轴名称</span>
ax.set_ylabel(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">yyyyyyyyyyy</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置y坐标轴名称</span>
<span style="color: rgba(0, 0, 0, 1)">
ticks </span>= np.arange(-2, 2, 0.3<span style="color: rgba(0, 0, 0, 1)">)
ax.set_xticks(ticks)</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置x轴刻度</span>
ax.set_yticks(ticks)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置y轴刻度</span>
<span style="color: rgba(0, 0, 0, 1)">
ax.axis(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">scaled</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置坐标轴宽高等比于x、y范围</span>
ax.axis(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">image</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">类似于scaled,暂时没发现区别</span>
ax.axis(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">off</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">关闭坐标轴</span>
ax.axis(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">equal</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">图像宽高比例不变,坐标轴范围变</span>
ax.axis(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tight</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">坐标轴紧紧贴合图像,不设置默认就是这个</span>
ax.axis(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">square</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置坐标轴宽高比为1:1,坐标轴跨度取较大的那个</span>
<span style="color: rgba(0, 0, 0, 1)">
ax.spines[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">right</span><span style="color: rgba(128, 0, 0, 1)">'</span>].set_color(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">none</span><span style="color: rgba(128, 0, 0, 1)">'</span>) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">包含'top','bottom','right','left'4个轴。这里设置右边轴消失</span>
ax.spines[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">left</span><span style="color: rgba(128, 0, 0, 1)">'</span>].set_position((<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">'</span>,0)) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将左边的轴移动到与横坐标0处对齐</span>
ax.spines[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">bottom</span><span style="color: rgba(128, 0, 0, 1)">'</span>].set_position((<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">data</span><span style="color: rgba(128, 0, 0, 1)">'</span>,0)) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将下面的轴移动到与纵坐标0处对齐</span></pre>
</div>
<p> 变换坐标轴位置(除了使用上述的spines外),给坐标轴加箭头等</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> mpl_toolkits.axisartist as axisartist
fig </span>=<span style="color: rgba(0, 0, 0, 1)"> plt.figure()
ax </span>= axisartist.Subplot(fig, 1,1,1<span style="color: rgba(0, 0, 0, 1)">)
fig.add_axes(ax) </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">使用这两句定义ax而不是add_subplot</span>
<span style="color: rgba(0, 0, 0, 1)">
ax.axis[:].set_visible(False) </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">隐藏'top','bottom','left','right','x','y'六个坐标轴</span>
ax.axis[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">x</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = ax.new_floating_axis(0, 0) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定义新的坐标轴给x轴,第一个0表示x方向,第二个0表示x轴处于y轴的0位置</span>
ax.axis[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">y</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = ax.new_floating_axis(1, 0) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定义新的坐标轴给y轴,第一个1表示y方向,第二个0表示y轴处于x轴的0位置</span>
ax.axis[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">x</span><span style="color: rgba(128, 0, 0, 1)">"</span>].set_axisline_style(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-></span><span style="color: rgba(128, 0, 0, 1)">"</span>, size = 1)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置x轴的风格,使用箭头</span>
ax.axis[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">y</span><span style="color: rgba(128, 0, 0, 1)">"</span>].set_axisline_style(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-></span><span style="color: rgba(128, 0, 0, 1)">"</span>, size = 1)</pre>
</div>
<h3>动态图像</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">plt.cla()
ax.clear()</span></pre>
</div>
<p> 这两个函数用于将子图清空,配合暂停函数</p>
<div class="cnblogs_code">
<pre>plt.pause(0.1) </pre>
</div>
<p> 即可实现动态图像。</p>
<h2>二维图像</h2>
<h3>contourf()和contour()</h3>
<p> 画等高线图。这两个函数差一个字母,但用法一样,区别如下:</p>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202005/1908255-20200526130028576-1443617524.png" alt="" height="218" width="486" style="display: block; margin-left: auto; margin-right: auto"></p>
<p> 使用方法:</p>
<div class="cnblogs_code">
<pre>ax.contourf(X, Y, Z, levels=10, alpha=0.5, cmap=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">jet</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p><strong> </strong><strong>X</strong>是生成网格的X坐标数组(二维数组array,或者matrix),<strong>Y</strong>是和X相同类型的Y坐标,<strong>Z</strong>是对应网格的每个格点的函数值数组(也是二维数组array,或者matrix),网格的生成是使用numpy库中的meshgrid()函数。<strong>levels</strong>是图像中等高线的数量,我这里设置为10。<strong>alpha</strong>是图像的透明度,介于0~1,我这里设置为0.5半透明。可以设置透明度有个好处就是可以把很多图画在同一个画布上,方便比较。<strong>cmap</strong>是图像的颜色类型,有很多预设的颜色类型,我这里用一个叫‘jet’的颜色类型,当然也可以自己定义,具体设置网上再找吧。后三项有预设值,可以省略。</p>
<p> 效果图:</p>
<p><img src="https://img2018.cnblogs.com/common/1908255/202001/1908255-20200112230107219-1605231997.png" alt="" height="292" width="593" style="display: block; margin-left: auto; margin-right: auto"></p>
<p> 看起来不是很圆润,这是因为我的网格规模就是7*7的,它画图就按照你的网格数量来画,所以有棱有角的。有一点奇怪的就是,网格是有限的,它是怎么画出这么多的等高线的?我猜它应该是线性插值插进去的。反正也就一个图用来看的,不用特别准确。但是如果要准确怎么办?那就把网格设置地密一些!别让等高线的密度比网格的密度大太多就好了。</p>
<p> 另外,可以用clabel()这个函数用来标注等高线图的数值:</p>
<div class="cnblogs_code">
<pre>plt.clabel(C, inline=False, fontsize=12)</pre>
</div>
<p> C代表刚刚画的等高线图(在用contour()等函数画完以后传给C,C = contour(...)),inline是否画在线内,fontsize数字的大小。</p>
<h3>plot()</h3>
<div class="cnblogs_code">
<pre>ax.plot(x, y,ls=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-</span><span style="color: rgba(128, 0, 0, 1)">"</span>, lw=2, label=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">plot figure</span><span style="color: rgba(128, 0, 0, 1)">"</span>, color=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">black</span><span style="color: rgba(128, 0, 0, 1)">'</span>,alpha=0.5...)</pre>
</div>
<p> 用来画二维面上的点、线。当然也可以在三维的空间里面画,就画在三维坐标系的xOy面上。重要参数介绍:</p>
<p> x: 要画的线的各个点在x轴上的坐标(一维数组)</p>
<p> y: 要画的线的各个点在y轴上的坐标(一维数组或二维数组,第一维规模要和x轴的数组一致,第二维规模的大小就是画线的数量)</p>
<p> ls:折线图的线条风格,这里是一个减号</p>
<p> lw:折线图的线条宽度</p>
<p> label:标记图内容的标签文本</p>
<p> color:颜色</p>
<p> alpha:透明度</p>
<p> 还有很多的参数可以调节,这里不一一列举,请看链接。另外,很多其它画线的函数也都支持一些个性化的参数,比如color、alpha、width等等,参数汇总看链接。</p>
<h3>bar()</h3>
<div class="cnblogs_code">
<pre>ax.bar(range(len(values)), values)</pre>
</div>
<p> 绘制条形图,第一个参数为横坐标,第二个参数为横坐标对应的值。</p>
<p> 示例代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> matplotlib.pyplot as plt
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> numpy as np
values </span>= np.random.normal(0,1,)
plt.bar(range(len(values)),values)
plt.show()</span></pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202103/1908255-20210302090848184-1764985387.png" alt="" style="display: block; margin-left: auto; margin-right: auto"></p>
<h3>hist()</h3>
<div class="cnblogs_code">
<pre>ax.hist(data,bins=50,range=[-5,5],density=True,cumulative=True,rwidth=0.9,orientation = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">vertical</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p> 画频次直方图,这个函数会自动对数据做统计,如果是已经统计好的数据,可以使用上面的bar()函数画图。重要参数介绍:</p>
<p> x:待统计的一维数据。</p>
<p> bins:柱子的数量</p>
<p> range:数据统计的范围</p>
<p> density:是否转换为频率密度图(密度图,乘以范围宽度才是这个范围内数据的频率占比)</p>
<p> cumulative:是否累加,若为真,柱子统计的是小于等于这个值的所有数据。</p>
<p> rwidth:柱子的宽度。</p>
<p> orientation:柱子是垂直还是水平放置。</p>
<p> 以下统计一个正态分布的累计柱状图:</p>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202006/1908255-20200610204348492-1888123599.png" alt="" height="273" width="432" style="display: block; margin-left: auto; margin-right: auto"></p>
<h3>hist2d()与hexbin()</h3>
<div class="cnblogs_code">
<pre>ax.hist2d(x,y,bins=30,cmap=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Blues</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p> 二维频次直方图。参数与上述一维频次直方图类似。以下显示二维正态分布抽样频次统计图(旁边的色度条是plt.colorbar(),子图如何加还没研究...):</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/1908255/202006/1908255-20200610211416827-237293087.png" alt="" height="288" width="369"></p>
<div class="cnblogs_code">
<pre>ax.hexbin(x,y,gridsize=30,cmap=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Blues</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p> 就是方格变成六边形格,gridsize表示格子大小:</p>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202006/1908255-20200610211952282-18136154.png" alt="" height="288" width="362" style="display: block; margin-left: auto; margin-right: auto"></p>
<h3>绘制二维热度图</h3>
<p> 以上二维频次直方图函数会先对输入做统计,再进行绘图。如果是已经统计好的二维数据,我们可以用imshow()函数来画。示例代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> matplotlib.pyplot as plt
values </span>= np.random.randint(0,100,)
hot </span>= plt.imshow(values, cmap=plt.cm.hot_r) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">第二个参数是颜色风格</span>
plt.colorbar(hot)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置刻度条</span>
plt.show()</pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202103/1908255-20210302092147762-1406971376.png" alt="" height="214" width="252" style="display: block; margin-left: auto; margin-right: auto"></p>
<h3>推荐cmap</h3>
<p> ['Spectral', 'GnBu', 'plasma', 'summer', 'turbo', 'viridis']</p>
<h2>三维图像</h2>
<h3>建立三维坐标系</h3>
<div class="cnblogs_code">
<pre>fig = plt.figure()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">添加绘图窗口</span>
ax = fig.add_subplot(221,projection = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">3d</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">窗口内添加3d子图</span>
ax = fig.add_subplot(projection = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">3d</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">如果只画一张图,可以用这个</span></pre>
</div>
<h3>plot_surface()</h3>
<div class="cnblogs_code">
<pre>ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">jet</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p> 画三维的曲面图,并且带有梯度颜色。<strong><br></strong></p>
<p> X、Y、Z就是每个网格点在对应坐标轴的值,cmap是涂色类型。rstride 是在行上每几个网格点计算一次梯度来图上对应梯度的颜色。cstride 就是列上的。它们越大,画梯度颜色的“补丁”也越大,对应地,“补丁”的数量也越少。如下图,一个是1,一个是2,“补丁”就一个是20,一个是10。</p>
<p><img src="https://img2018.cnblogs.com/common/1908255/202001/1908255-20200123005955532-995550473.png" alt="" height="306" width="439" style="display: block; margin-left: auto; margin-right: auto"></p>
<p><img src="https://img2018.cnblogs.com/common/1908255/202001/1908255-20200123010011143-1510404447.png" alt="" height="258" width="453" style="display: block; margin-left: auto; margin-right: auto"></p>
<h2>外部图像</h2>
<h3>图像导入与显示</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> matplotlib.pyplot as plt
</span><span style="color: rgba(0, 0, 255, 1)">import</span> pylab <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">原本在jupyter里才能显示的图片,可以用窗口显示</span>
<span style="color: rgba(0, 0, 0, 1)">
img</span>=plt.imread(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">image.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">读取图片,读取到的是:高度×宽度×3RGB 的array数组</span>
fig = plt.figure() <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">创建窗口</span>
ax = fig.add_subplot(111) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">创建子图</span>
ax.imshow(img) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">子图中添加图片</span>
<span style="color: rgba(0, 0, 0, 1)">
pylab.show() </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">显示窗口</span></pre>
</div>
<h1>cv2</h1>
<h2>图像批处理</h2>
<h3>从压缩包中直接读取图片</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> zipfile
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> cv2
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> numpy as np
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> matplotlib.pyplot as plt
path </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">D:/Datasets/dogs-vs-cats/train.zip</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">压缩包地址</span>
with zipfile.ZipFile(path,mode=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) as f:
</span><span style="color: rgba(0, 0, 255, 1)">for</span> name <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> f.namelist():
</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">.jpg</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">not</span> <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> name:
</span><span style="color: rgba(0, 0, 255, 1)">continue</span>
<span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(name)
with f.open(name,mode</span>=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) as image_file:
content </span>= image_file.read() <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 读取图片</span>
img = np.asarray(bytearray(content), dtype=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">uint8</span><span style="color: rgba(128, 0, 0, 1)">'</span>) <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将jpg格式转码</span>
img = cv2.imdecode(img, cv2.IMREAD_COLOR)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">再转化为BGR格式,注意不是RGB,顺序反了 ,不重组的话在plt颜色显示异常</span>
b,g,r =<span style="color: rgba(0, 0, 0, 1)"> cv2.split(img)
img </span>= cv2.merge()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将BGR拆分再重组为RGB</span>
<span style="color: rgba(0, 0, 0, 1)"> plt.imshow(img)
plt.show()
</span><span style="color: rgba(0, 0, 255, 1)">break</span></pre>
</div>
<h3>图形拉伸</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> cv2
cv2.resize(img,(w,h),interpolation</span>=0)</pre>
</div>
<p> 将存在数组中的图像拉伸成w宽,h高。interpolation=0表示最近邻插值,不作平滑处理。其它插值参数(interpolation)请看链接。</p>
<h1>seaborn</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span> seaborn as sns</pre>
</div>
<p> seaborn简化了matplotlib的绘图操作,并且让图像更精美,绘制matplotlib图像时,使用sns.set(),可让图像更具特色。</p>
<h1>mayavi</h1>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span> mayavi.mlab as mlab</pre>
</div>
<p> mayavi是专门绘制三维图形的库,虽然matplotlib也能绘制,但是matplotlib并不支持光线追踪,所以没有遮挡的效果。绘制各种图像的函数和matplotlib差不多。mayavi文档、简易实例。</p>
<h3>mesh()</h3>
<p> 绘制三维图形表面,用法和matplotlib的plot_surface类似,但是创建网格时推荐用mgrid,meshgrid的索引顺序不对。</p>
<div class="cnblogs_code">
<pre>mlab.mesh(x, y, z )<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">绘制光滑表面</span>
mlab.mesh(x, y, z, representation=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">wireframe</span><span style="color: rgba(128, 0, 0, 1)">"</span>, line_width=1.0)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">绘制线而不是表面</span></pre>
</div>
<p> 下图画了一个卷起来的彩带:</p>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202009/1908255-20200901121444086-490376186.png" alt="" height="358" width="408" style="display: block; margin-left: auto; margin-right: auto"></p>
<p> 代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> mayavi.mlab as mlab
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> numpy as np
roll </span>= 10<span style="color: rgba(0, 0, 0, 1)">
r </span>= 0.5<span style="color: rgba(0, 0, 0, 1)">
w </span>= 0.8<span style="color: rgba(0, 0, 0, 1)">
theta </span>= np.linspace(np.pi*0.5,np.pi*2*roll,num=roll*100<span style="color: rgba(0, 0, 0, 1)">)[:,np.newaxis]
h </span>= np.linspace(-1,1,num=2)+0.5<span style="color: rgba(0, 0, 0, 1)">
x </span>= y = z =<span style="color: rgba(0, 0, 0, 1)"> np.zeros()])
x </span>= x + np.cos(theta)*theta*r/<span style="color: rgba(0, 0, 0, 1)">np.pi
y </span>= y + np.sin(theta)*theta*r/<span style="color: rgba(0, 0, 0, 1)">np.pi
z </span>= z + h - theta*w/<span style="color: rgba(0, 0, 0, 1)">np.pi
</span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(y.shape,z.shape)
mlab.mesh(x, y, z)</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">绘制光滑表面 </span>
mlab.show() </pre>
</div>
<h3>plot3d()</h3>
<p> 画三维坐标系中的曲线。用法和matplotlib的plot类似。同样推荐用mgrid创建网格。</p>
<div class="cnblogs_code">
<pre>mlab.plot3d(x,y,z)</pre>
</div>
<h1>numpy</h1>
<p> 用numpy的一些函数生成格式化的绘图数据。 </p>
<h3><strong>linspace()</strong></h3>
<p> linspace(a, b, n),传回一个在a、b之间的插值列表(包括a、b),插值的数量是n。这个差值列表类型是array,而不是list,array里的数据类型是固定的,都是float。而列表list里面则并不是固定的,里面可以存任何东西。array是numpy下定义的一个类型,这个类型类似C++的数组,随机查找很快。所以处理大批量同类数据的时候,最好使用array类型。</p>
<p> 具体使用和其他参数:</p>
<p> https://www.cnblogs.com/antflow/p/7220798.html</p>
<h3>meshgrid()</h3>
<p> 用于生成对应列表的网格(网格也是用列表存,二维网格是对每一维来说是二维列表,三维网格对每一维来说是三维列表),用于绘制梯度图等。使用方法如下:</p>
<p> 1. = meshgrid(x,y)或者python还支持X,Y = meshgrid(x,y),不加方括号也行,当然直接A = meshgrid(x,y),传给一个值也行,就是后面不太好处理。</p>
<p> 2. = meshgrid(x)与 = meshgrid(x, x)是等同的</p>
<p> 3. = meshgrid(x, y, z)生成三维的网格</p>
<p> 生成的网格索引顺序在二维X、Y中是先Y再X,三维X、Y、Z中顺序是Y、X、Z。例如,在三维网格中,如果要获得x,y,z位置的Y轴坐标,就是Y。在二维网格中,如果要获得x,y位置的X轴坐标,就是X。</p>
<p> 下图显示8*3的网格的X的列表:</p>
<p><img src="https://img2018.cnblogs.com/common/1908255/202001/1908255-20200111164946807-1659280127.png" alt="" height="242" width="409" style="display: block; margin-left: auto; margin-right: auto"></p>
<h3>mgrid</h3>
<p> 与meshgrid类似,同样能生成对应的网格。但是它并不是函数,而是以索引的形式使用的属性,并且还可以生成类似的2维以上的网格。另外,它和meshgrid的不同之处在于它们生成的网格的索引方式是相反的。推荐使用mgrid,它更容易理解。以下是实例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> numpy as np
a </span>= np.mgrid
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(a)</pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/1908255/202007/1908255-20200728092525909-788763088.png" alt="" height="199" width="220" style="display: block; margin-left: auto; margin-right: auto"></p>
<p> 索引的第二个冒号传入整数表示数的间隔,不包含最后一个数。传入复整数表示数的个数,比如5j表示范围内5个数,包含最后一个数。</p>
<h1>特定图像样例</h1>
<p> https://www.runoob.com/w3cnote/matplotlib-tutorial.html</p>
<p> https://blog.csdn.net/jasonzhoujx/article/details/81780774</p><br><br>
来源:https://www.cnblogs.com/qizhou/p/12180157.html
頁:
[1]