1 matplotlib(缩写mpl)

Matplotlib 是一个跨平台的 Python 库,用于绘制二维图形(也称为图)。 它可以在各种用户界面中使用,例如 Python 脚本,IPython Shell,Jupyter 笔记本,Web 应用和 GUI 工具包。 它可以用于开发专业的报表应用,交互式分析应用,复杂的仪表板应用或嵌入到 Web/GUI 应用中。 它还支持将图形保存为各种硬拷贝格式。 它还对三维图形的支持有限。 它还支持许多第三方工具包以扩展其功能。

matplotlib交互模式

import matplotlib 
matplotlib.is_interactive()#检查交互模式是ON(True)还是OFF(False)
matplotlib.pyplot.ion()#设置交互模式ON
matplotlib.pyplot.ioff()#切换OFF交互模式

在交互模式下,我们将屏幕输出设置为后端 %matplotlib inline ,然后不用输出 plt.show() 即可直接输出

1.1 matplotlib绘图原理剖析

图元素:包含输出图的所有元素的高级 Matplotlib 对象称为figure。 可以以不同方式排列多个图形以形成图形。 图的每个元素都是可自定义的。

  • 图形

下图是figure的剖析图,其中包含其所有元素:

  • 轴域

axes是该图的子部分,其中绘制了图形。axes具有标题,x 标签和 y 标签。figure可以具有许多这样的axes,每个figure代表一个或多个图形。 在上图中,只有一个axes,两个是蓝色和红色的折线图。

这些是数字线,代表要绘制的图形的比例。 二维图具有 x 轴和 y 轴,而三维图具有 x 轴, y 轴 ,以及 z 轴。

  • 标签

    这是图中各个元素的名称,例如 x 轴标签, y 轴标签,图形标签(上图中的蓝色信号/红色信号图形剖析等等。

  • 图例

当axes中有多个图形时(如上图,图形剖析图),每个图形都有其自己的标签,所有这些标签均表示为图例。 在上图中,图例位于图的右上角。

  • 标题

它是每个axes的名称。 当图形具有多个带有各自标题的轴域时,figure也可以具有自己的标题。 上图只有一个轴域,因此轴域和该图都只有一个标题。

  • 刻度标签

每个轴(x,y 或 z)都有一个范围的值,该值分为许多相等的桶。 桶分为两个级别。 在上一个图(剖析图), x 轴刻度范围从 0 到 4,分为四个主要区域(0-1、1-2、2-3 和 3-4),每个主要桶又分为四个次要桶(0-0.25、0.25-0.5 和 0.5-0.75)。 主桶两侧的刻度称为主刻度,次桶称为次刻度,它们的名称为主刻度标签和次刻度标签。

  • 轴线

该图的边界称为轴线。 每个轴域有四个轴线(上,下,左和右)。

  • 网格

为了更容易读取图形上各个点的坐标,将图形区域划分为网格。 通常,此网格沿着 x 和 y 轴的主要刻度线绘制。 在上图中,以虚线显示了网格。

1.2 matplotlib基本图形

1.2.1 折线图

一般是绘制时序变化数据或者探究变量之间的线性关系

plt.plot(x)#x为序列或者range对象,底部刻度标签为为0,1,2,3,4,也就是**x的索引**
plt.plot(x,y)#以x为x轴的刻度标签,y为y轴值,绘制图像

可以发现不管是数值还是标签都行。

同时,还可以设置线(line)与点(marker)的格式

1.2.2 堆叠图

堆叠图表示线形图下的区域,多条线形图彼此叠放。 它用于提供的可视化,即 y 轴域上绘制的多个变量的累积效果。

这个可以反映横向和纵向的变化。纵向是堆叠的效果,横向是比较。

1.2.3 散点图

一般是用来分析点的聚集离散状态

plt.scatter(x,y,s,marker,cmap,alpha,linwidths,edgecolors,data)

s:设置点的大小,可以通过数据给点设置不同的大小,长度与数据长度相同,比如设置s=‘x*y’,这样x,y越大,点就越大。
c:根据某个变量的类别设置颜色,变量类别必须先转化为数字类型。 marker:设置点的格式
alpha:设置图片透明度,图片通用参数
cmap:给点设置颜色

1.2.4 条形图

条形图一般是用来绘制分类变量的数据

plt.bar(x,height,width,bottom,data)#柱状图,竖着
plt.barh(y,width,height,left)#条形图,横着

x:标签
height:数值高度
width:条宽度
bottom:条的底部的起始点

条形图的每一个框可以看成一个对象,patches.Reactangle对象。条形图本身是一个可迭代的对象。

bar1[0].get_x()
bar1[0].get_height()
bar1[0].get_label()
bar1[0].get_width()
bar1[0].get_linestyle()
bar1[0].get_ls()
bar1[0].get_lw()

还可以为条形图设置线框,添加值的显示

1.2.5 饼图

饼图用于表示各种类别/组对总数的贡献。 例如,每个州对国家 GDP 的贡献,一部电影对一年中发行的电影总数的贡献,学生等级(A,B,C,D 和 E)占总班级人数的百分比 ,或每月家庭支出在杂货,蔬菜,公用事业,服装,教育,医疗保健等方面的分配。

labels和sizes是 Python 列表,代表流派和一年中发行的电影总数的百分比.输入列表中标签的顺序在饼图中按逆时针方向绘制。
explode参数指定要向外展开图表的哪个部分。
autopct自变量描述了要在百分比数据点中显示的小数点的数量。 如果省略此参数,则切片将不显示实际百分比(%)数据。
shadow参数指定是否应在每个切片上显示阴影。
startangle参数指定第一个切片应开始的角度,并且它逆时针旋转以表示饼图中的所有其他切片。
plt.axis(equal)表示图表应显示为圆形(x 和 y 轴相等)。 默认形状是椭圆:

pie1[0]#所有块形成的对象
pie1[0][0].get_label()
pie1[0][0].get_fc()
pie1[0][0].get_ec()

pie[1]#所有标签形成的对象

1.2.6 表格图

plt.table(table(cellText=None, cellColours=None, cellLoc='right', colWidths=None, rowLabels=None, rowColours=None, rowLoc='left', colLabels=None, colColours=None, colLoc='center', loc='bottom', bbox=None, edges='closed', **kwargs))

cell:设置表的内容,必须是二维的。表每一行的颜色,必须每一列的颜色都设置。也是二维的。表内容的位置。 col:设置列宽,列标签,列的颜色,列的位置 row:设置行宽,行标签,行颜色,行位置。

可以看到,table是在一个画布之下,也就是说支持在之前先画一张图然后再画表格,也就是表格图。一般是加上条形图

#数据
rows = ['2011', '2012', '2013', '2014', '2015']
columns = ('7Ah', '35Ah', '40Ah', '135Ah', '150Ah')
data = [[75, 144, 114, 102, 108], [90, 126, 102, 84, 126], 
        [96, 114, 75, 105, 135], [105, 90, 150, 90, 75], 
        [90, 75, 135, 75, 90]]
#y轴范围和长度
values = np.arange(0, 600, 100)
#指定要使用的色谱。 每年将以不同的颜色表示:
colors = plt.cm.OrRd(np.linspace(0, 0.5, len(rows)))
#定义要绘制条形的 x 轴刻度:
index = np.arange(len(columns)) + 0.3
bar_width = 0.5
#初始化堆叠条形图的垂直偏移量:
y_offset = np.zeros(len(columns))
#根据图形和轴域指定绘图区域:
fig, ax = plt.subplots()
#绘制条并为表格创建文本标签。 初始化用于保存表数据的列表:
cell_text = []
#for循环的每次迭代都以一种颜色绘制所有电池额定值的一年数据:
n_rows = len(data)
for row in range(n_rows):
    plot = plt.bar(index, data[row], bar_width, bottom=y_offset, 
                   color=colors[row])
    y_offset = y_offset + data[row]
    cell_text.append(['%1.1f' % (x) for x in y_offset])
    i=0
## Each iteration of this for loop, labels each bar with   
## corresponding value for the given year
    for rect in plot:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width()/2, y_offset[i],'%d' 
                % int(y_offset[i]), 
                ha='center', va='bottom')
        i = i+1 
#在轴域的底部添加一个表格:
the_table = plt.table(cellText=cell_text, rowLabels=rows, 
                rowColours=colors, colLabels=columns, loc='bottom')
plt.ylabel("Units Sold")
#x 轴上有 n 个刻度,因为此表覆盖了标签:
plt.xticks([])

1.2.7 极坐标图

极坐标图是在极坐标轴域上绘制的图表,其坐标为角度(以度为单位)和半径,与 x 和 y 的笛卡尔系统相对。 我们将以组织中各个部门产生的计划支出与实际支出为例。 这也称为蜘蛛网图

plt.figure(figsize=(10,6))
plt.subplot(polar=True)

通过设置plt.subplot(polar=True)来确定绘制极坐标图。

然后需要设置角度划分,与标签对应。角度划分时必须是弧度制

Depts = ["COGS","IT","Payroll","R & D", "Sales & Marketing"]
rp = [30, 15, 25, 10, 20, 30]
ra = [32, 20, 23, 11, 14, 32]
theta = np.linspace(0, 2 * np.pi, len(rp))#根据类别个数,均匀划分2π

plt.thetagrids将角度与标签对应,同时还可以生成相应对象

(lines,labels) = plt.thetagrids(range(0,360, int(360/len(Depts))),(Depts))

对应好后就是plt.plot(theta,rp)即可。

然后可以通过plt.fill(theta,rp,'颜色名',alpha),填充内部颜色,设置透明度。

极坐标投影也可以用于散点图,气泡图和条形图。 这只是另一个坐标系,每个点都需要转换为极坐标。

转换角度和弧度可以用np.degrees(弧度)将弧度转化为角度

1.2.9 绘制箱线图

plt.boxplot(data,notch,vert,showflier=T/F,flierprops=dict(marker=,markerfacecolor=),boxprops=dict(colors=))

data:data参数可以是一个或多个属性的列表
vert=False:绘制水平箱线图
showflier=False:抑制离群值
flierprops:设置离群点的颜色和格式
boxprops:可以在里面设置颜色

箱线图也可以看成是一系列线和线标签组成,可以给这些部分分别设置格式,是字典格式:

1.2.10 提琴图

提琴图是直方图和箱形图的组合。 它提供有关数据完整分布的信息,以及均值/中值,最小值和最大值。

plt.violinplot()绘制提琴图。 底部胡须是最小值,是顶部胡须是最大值,水平线在是平均值。 在的两侧,垂直线是代表和数据实际分布的数据直方图。 通过将showmeans=True替换为showmedian=True,我们可以用一条横线代表数据的中位数,而不是表示的意思.

1.2.11 热图

热图用于以不同的强度可视化不同颜色的数据范围。 在这里,我们以绘制相关矩阵作为热图为例。 相关矩阵的元素指示两个变量之间的线性关系的强度,并且矩阵包含给定数据中属性的所有组合的此类值。 如果数据具有五个属性,则相关矩阵将是5 x 5矩阵。

1.2.12 Hinton 图

Hinton 图是一个二维图,用于可视化深度学习应用中的权重矩阵。 Matplotlib 没有直接的方法来绘制此图。 因此,我们将不得不编写代码来对此进行绘制。

以下代码块定义了该函数并调用了该函数以绘制 Hinton 图:

从 Excel 文件中读取重量矩阵数据:
matrix = np.asarray((pd.read_excel('weight_matrix.xlsx')))
实例化图形和轴域:
fig, ax = plt.subplots()
为轴域设置参数:
ax.patch.set_facecolor('gray')
ax.set_aspect('equal', 'box')
ax.xaxis.set_major_locator(plt.NullLocator())
ax.yaxis.set_major_locator(plt.NullLocator())
绘制 Hinton 图:
max_weight = 2 ** np.ceil(np.log(np.abs(matrix).max()) / np.log(2))
for (x, y), w in np.ndenumerate(matrix):
        color = 'white' if w > 0 else 'black'
        size = np.sqrt(np.abs(w) / max_weight)
        rect = plt.Rectangle([x - size / 2, y - size / 2], size, size, facecolor=color, edgecolor=color)
    ax.add_patch(rect)
ax.autoscale_view()
在屏幕上显示:
plt.show()

也就是为每一个值画一个框,并且根据大小对框的大小还有颜色做出改变,最后整齐排列。

ax.patch.set_facecolor('gray')将每个方框的颜色设置为灰色。
ax.set_aspect('equal', 'box')将长宽比(宽高比)和图形上要点的形状指定为方框。
ax.xaxis.set_major_locator(plt.NullLocator())将 x 轴刻度设置为空,这样就不会标记任何刻度,也不会放置任何刻度标签。
启动for循环以遍历权重矩阵的每个元素,并将颜色设置为白色(正值),黑色(负值)和与max_weight成比例的大小。 最后,ax.autoscale_view()整齐地排列所有框并绘制 Hinton 图。

1.2.13 等高线图

等高线图通常用于显示误差如何随机器学习算法(例如线性回归)中优化的系数的变化而变化。 如果线性回归系数为theta0和theta1,并且预测值和实际值之间的误差为Loss,则对于给定的Loss值,theta0和theta1的所有值 ]形成轮廓。 对于Loss的不同值,通过更改和theta1的值形成不同的轮廓。

plt.contour()#绘制轮廓图
plt.clabel()#为轮廓图的损失添加标签

这里是数据的原因,效果并不是很好,可以看下面这个图:

1.2.16 路径,自定义绘图

Path是 Matplotlib 提供的一种用于绘制自定义图表的方法。 它使用 Matplotlib 提供的助手函数补丁。 让我们看看如何将其用于绘制简单图。

from matplotlib.path import Path
import matplotlib.patches as patches
#定义第一个曲线的点
verts1 = [(-1.5, 0.),             # left, bottom
          (0., 1.),               # left, top
          (1.5, 0.),              # right, top
          (0., -1.0),             # right, bottom
          (-1.5, 0.)]             # ignored

#绘制连接第一个曲线的点,形成图形
codes1 = [Path.MOVETO,    # Go to first point specified in vert1
          Path.LINETO,    # Draw a line from first point to second point
          Path.LINETO,    # Draw another line from current point to next point
          Path.LINETO,    # Draw another line from current point to next point
          Path.CLOSEPOLY] # Close the loop

#使用步骤 1 和步骤 2 中定义的点和线/曲线创建完整路径:
path1 = Path(verts1, codes1)

#对第二个图形进行相同的操作
verts2 = [(-1.5, 0.),       # left, bottom
          (0., 2.5),        # left, top
          (1.5, 0.),        # right, top
          (0., -2.5),       # right, bottom
          (-1.5, 0.)]       # ignored

codes2 = [Path.MOVETO, # Move to the first point
          Path.CURVE3, # Curve from first point along the control point and terminate on end point
          Path.CURVE3, # Curve from current point along the control point and terminate on end point
          Path.CURVE3,
          Path.CURVE3] # close by the curved loop

path2 = Path(verts2, codes2)

#定义图形和轴域
fig = plt.figure()
ax = fig.add_subplot(111)

#创建第一个补丁并将其添加到轴域中:
patch1 = patches.PathPatch(path1, lw=4, zorder=2)
ax.add_patch(patch1)

#创建第二个补丁并将其添加到轴域中:
patch2 = patches.PathPatch(path2, facecolor='orange', lw=2,                         zorder=1)
ax.add_patch(patch2)

# 设置x和y轴的限制:
ax.set_xlim(-2,2)

首先必须定义沿着曲线应该走的点,然后定义连接的方式和路径,利用path函数。然后最后再用path函数组合点和路径生成完整的路径。路径生成后并不是图,要通过patches.PathPatch设置补丁,将其添加到轴域,生成图形。可以指定图形的层级顺序(zorder)。

verts1和verts2定义了必须沿其绘制曲线的点。path1和path2定义了要绘制的每条曲线的完整路径。
Path.MOVETO使曲线的起点到达verts中指定的第一点。
Path.LINETO从当前位置的到指定的下一个点画一条线。
Path.CLOSEPOLY关闭多项式曲线循环。
Path.CURVE3沿着控制点从给定点绘制一条曲线,然后在第三点处终止。
Path.CURVE4(在此示例中未使用)进行相同的操作,但是在两个控制点而不是一个。
patches.PathPatch是一个辅助函数,可沿给定路径绘制曲线。
zorder参数会覆盖绘制不同补丁的默认顺序。 在这种情况下,我们希望先绘制第二个补丁,然后再绘制第一个补丁,以便两个都可见。 否则,较小的补丁将隐藏在较大的补丁之后。
lw指定线宽,facecolor指定要填充在色块内部的颜色,覆盖默认颜色。

1.3 画布(figure)和轴域(axes)设置

创建画布:plt.figure(num,figsize=()),figsize为可选参数,此时并没有轴域,num为可选参数,设置画布数字编号

创建轴域:ax=plt.axes(),ax=plt.axes([left,bottom,width,height])

在画布中添加轴域:fig=plt.figure(),fig.add_axes([left,bottom,width,height])这样就是比较自由的添加轴域了

获取当前画布中的轴域:plt.gca()

关闭画布:plt.close(‘all’)关闭所有画布;plt.close(mum)关闭相应数字编号的画布

fig.subplots_adjust(left=0.0, bottom=0.05, right=0.9, top=0.95, wspace=0.6)定义图形的边界框,在图形的左侧,底部,右侧和顶部定义的所有四个方向上都留有空间。wspace定义一行中各图之间要保留的空间量,以使它们的标签或图之间没有重叠。hspace是另一个参数,它控制列中各图之间的间隔。

fig.tight_out();#自动布局

ax.set_title()
ax.legend()
ax.text()
ax.set()
plt.xticks([tick],[label],minor)
plt.xlabel()
plt.title()#设置轴域标题
plt.subtitle()#设置画布标题
plt.legend()
plt.text()
plt.figtext(0.9, 0.1, 'x', size=20)是在图形坐标系上绘制的文本,并绘制了大小为 20 的 x 轴。类似地, y 轴绘制为(0.1, 0.9)在图形坐标系上。

1.3.1 设置轴域的四个轴线

ax.spines['位置'],位置选定是哪个轴线,轴线设置有线的设置,是否可见,轴线的位置

ax.spines['left'].set_position('center')#set_position('center')将 x 和 y 轴放置在相应数据范围之间。 在这种情况下, y 轴上的数据范围是 -1 到 +1,所以中心点是 0,而 x 轴上的数据范围是 0 到 6,所以中心点是3。 因此,交点为(3, 0)。
ax.spines['right'].set_visible(False)#设置轴是否可见
ax.spines['top'].set_color('r')
ax.spines['top'].set_linewidth(1.7)
#设置轴位置,axes属性,[0.25, 0.75]为0.25 * x 范围 = 0.25 * (0 到 6) = 1.5,0.75* y 范围 = 0.75 * (-1 到 1) = 0.5
ax.spines['bottom'].set_position(('axes', 0.75))
ax.spines['left'].set_position(('axes', 0.25))
#我们使用data选项指定输入数据中的位置。 因此,它将左脊和下脊置于(1, -1)交点。
ax.spines['bottom'].set_position(('data', -1))
ax.spines['left'].set_position(('data', 1))
#我们使用outward参数将轴线放置在远离图形的位置指定数量的单位; 在这里是10:
ax.spines['bottom'].set_position(('outward', 10))
ax.spines['left'].set_position(('outward', 10))

1.3.2 设置轴线的刻度

#主刻度设置
ax.set_xticks([主刻度位置],minor=bool),minor为false,默认不设置,设置true,则前面的列表变成设置次要刻度的位置
ax.set_yticks()

#分开设置
ax.xaxis.set_major_locator(majorLocator)
ax.xaxis.set_minor_locator(minorLocator)

#设置刻度单位
ax.xaxis.set_units([])#设置刻度的单位
ax.yaxis.set_units([])

#设置刻度所在轴线位置
ax.xaxis.set_ticks_position('bottom')#x轴刻度的位置,应该在那条轴线上。
ax.yaxis.set_ticks_position('left')

#设置刻度规模
ax.set_yscale()#设置x轴的规模,也就是量级,比如log等
ax.set_xscale()
ax.autoscale_view()#自动调整比例

#设置轴的一系列属性
ax.xaxis.set()#设置x轴的一系列属性
ax.yaxis.set()

#设置轴线的长宽高和颜色
ax.tick_params(which='major', length=10, color='g')
ax.tick_params(which='minor', length=4, color='r')
ax.tick_params(which='both', width=2)

#设置刻度之间的距离
matplotlib.rcParams['xtick.major.pad'] = 5
matplotlib.rcParams['ytick.major.pad'] = 5

#控制ticks与轴标签之间的距离
ax.xaxis.labelpad = 5
ax.yaxis.labelpad = 5

#ticker包
from matplotlib.ticker import (MultipleLocator AutoMinorLocator)

minorLocator = AutoMinorLocator()#自动生成次要刻度
majorLocator = MultipleLocator(major_step_size)#设定一个间隔,然后刻度就会以这个间隔自动生成,可以把这个赋给主要或次要刻度。
minorLocator = MultipleLocator(minor_step_size)

1.3.3 设置刻度标签

from matplotlib.ticker import (FuncFormatter,FormatStrFormatter)

majorFormatter = FormatStrFormatter('%d')#指定要显示的刻度标签编号的格式
formatter = FuncFormatter(Num_Format)#自定义函数,然后在图形生成时,自动根据默认标签,通过函数转换,生成最终标签。需要设置。

ax.set_xticklabels([labels])#默认设置主刻度标签
ax.set_yticklabels()
ax.yaxis.set_major_formatter(formatter)#设置主要刻度标签
ax.yaxis.set_minor_formatter(formatter)#设置次要刻度标签

1.3.4 设置轴范围,轴标签

ax.set_xlabel('label')
ax.set_ylabel()
ax.set_xlim((a,b))
ax.set_ylim((a,b))

1.3.5 添加线条,艺术家

ax.add_line()
ax.add_artist()

1.3.6 双生轴域设置

有时,我们可能希望在同一轴域上绘制两个图表,但是数据规模不同。 如果我们在左右轴线上使用具有相同比例尺的标准图,则由于数据比例尺的巨大差异,图表可能看起来不正确。 在这种情况下,我们可以使用 Matplotlib 提供的双生轴域功能。

轴域联动有三种选择:

twinx:为两个图形共享 x 轴,而左轴和右轴表示两个不同的比例
twiny:为两个图形共享 y 轴,而顶部和底部轴表示两个比例
no sharing:其中一张图使用底部轴和左轴,第二张图使用顶部轴和右轴

ax1 = plt.subplot(121)       # first plot
ax2 = ax1.twinx()            # share x axis

ax3 = plt.subplot(122)       # second plot
ax4 = ax3.twiny()            # share y axis

唯一的区别是ax1 = ax.twinx().twiny()。 而不是使用twinx()或twiny(),我们都使用了两者,以便将上轴域和右轴域用于此新逻辑轴域(ax1),而将左轴域和底轴域用于主轴域(ax)

plt.figure(figsize=(8,6))
ax = plt.subplot(111)
h1 = ax.scatter(iris.petal_width, iris.petal_length, s=5*iris.petal_width*iris.petal_length, c='b')

ax1 = ax.twinx().twiny()
h2 = ax1.scatter(iris.sepal_width, iris.sepal_length, 
                s=5*iris.sepal_width*iris.sepal_length, c='g')

1.3.7 在同一轴域绘制多个图形

当你画了很多个图形,并且没有分配轴域时,他们会在同一个轴域中展示出来。

1.3.8 在一个轴域中绘制另一个子轴域(子图)

图中的多个图排列在m x n网格中,其中m是行数,n是列数。 如果图中有六个绘图,我们可以将它们全部排成一排(每个都由 161、162、163、164、165 或 166 标识)或3 x 2(321、322,323、324、325 和 326)或2 x 3(231、232、233、234、235 和 236)或一列(611、612、613、614、615 和 616)。 前两位数字表示,行和列的数量的最后一位数字表示从 1 到 6 的连续数字(绘图总数),并从左向右,然后从上到下读取。

也可以将图指定为(3, 2, 1)而不是(321)。 当网格中有九个以上的绘图时,后一种表示法会造成混淆,而 Matplotlib 不接受它。 在这种情况下,如果您有一个(…),则必须使用(3, 4, 10),(3, 4, 11)或(3, 4, 12)而不是(3410),(3411)或(3412)。 3 x 4网格,共有 12 个绘图。

我们还可以绘制少于网格中允许的最大值的图,例如,在2 x 2网格中绘制 3 个图(其中是最大值)。

子图指的是在一个轴域的范围类放置其他的轴域,通过plt.axes([left,bottom,width,height])

1.3.9 将一个画布分成多个轴域(多图)

  1. fid.add_axes([left,bottom,width,height]),可以比较自由的设置轴域的位置
  2. ax1=fig.subplot(nrow,ncol,num)代表第几个图形,按照从左到右,从上到下

    fig = plt.figure() ax1 = plt.subplot(221) ax2 = plt.subplot(222) ax3 = plt.subplot(212)
  3. fig,ax=plt.subplots(nrow,ncol,figsize=(a,b)),ax是一个轴域的集合。如果只有一行,则是一维的,可以通过ax[0]这样确定那个轴域,如果是多行,则是ax[0,0]这样确定轴域。
  4. 使用plt.subplot2grid fig = plt.figure(1, figsize=(12, 9)) ax1 = plt.subplot2grid((3, 3), (0, 0)) ax2 = plt.subplot2grid((3, 3), (0, 1), colspan=2) ax3 = plt.subplot2grid((3, 3), (1, 0), colspan=2, rowspan=2) ax4 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)

1.3.9.1 用于图形布局的GridSpec

GridSpec()是用于复杂图形布局的另一个强大函数。plt.subplot()和plt.subplot2grid()实例化图形后,一次添加一个图,并且在中指定图形布局,每个子图中的行数和列数,其后是图的序列号,从右到上到下。 但是plt.subplots()一次就定义了整个图形布局,就行数和列数而言,然后使用和对应索引访问了每个图/轴域。GridSpec()允许在图形布局中创建多个网格,每个网格类似于plt.subplots()。 在本秘籍中,我们将学习如何使用GridSpec()以及如何将GridSpec()关键字参数与plt.subplots()一起使用。

先是利用GridSpec创建网格布局对象,然后在选取部分空间用来画图,可以配合fig.add_subplot()使用。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.gridspec import GridSpec
fig = plt.figure(figsize=(14,10))
gs1 = GridSpec(ncols=3, nrows=3, left=0.05, right=0.5, wspace=0.2, 
            hspace=0.1)
ax1 = fig.add_subplot(gs1[0, 0])
ellipse = patches.Ellipse((0.5, 0.5), 0.7, 0.3, transform=ax1.transAxes, facecolor='blue', alpha=0.3)
ax1.add_patch(ellipse)
ax4 = fig.add_subplot(gs1[1:, 1:], projection='polar')
N = 30
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = 10 * np.random.rand(N)
width = np.pi / 4 * np.random.rand(N)
bars = ax4.bar(theta, radii, width=width, bottom=0.0)
使用宽度和高度比率参数定义第二个GridSpec gs2:
widths = [2, 3, 1.5]
heights = [1, 3, 2]
gs2 = GridSpec(ncols=3, nrows=3, left=0.55, right=0.95, wspace=0.2, 
hspace=0.1, width_ratios=widths, height_ratios=heights)#width_ratios和height_ratios分别指定行和列中的相对宽度和高度

1.3.9.2 subplots使用gridspec

gridspec_kw参数

gs_kw = dict(width_ratios=widths, height_ratios=heights)
fig, axes = plt.subplots(ncols=3, nrows=3, figsize=(10,8), gridspec_kw=gs_kw)
for r, row in enumerate(axes):
    for c, ax in enumerate(row):
        ax.plot(t, s)
        label = 'Width: {}\nHeight: {}'.format(widths[c], heights[r])
        ax.annotate(label, (0.1, 0.5), xycoords='axes  fraction', va='center')
fig.tight_layout()
plt.show()

1.4 设置填充hatch

matplotlib 提供相当有限的支持,以用图案填充表面。 对于线条图案,为黑白打印准备图形时可能会有所帮助

填充体积的渲染函数(例如pyplot.bar())接受可选参数hatch。 此参数可以采用以下值:"/,\,|,-,+,x,o,0,.,*",可以设置多个,比如’-+o’

1.5 颜色

在 matplotlib 中定义颜色的方法有多种。 其中一些如下:

三元组:这些颜色可以描述为实值三元组-颜色的红色,蓝色和绿色分量。 分量必须在[0, 1]间隔内。 因此,Python 语法(1.0, 0.0, 0.0)将编码纯净的鲜红色,而(1.0, 0.0, 1.0)则显示为强粉色。

四元组:这些作为三元组,并且第四部分定义透明度值。 此值也应在[0, 1]间隔内。 将图形渲染到图片文件时,使用透明颜色可以使图形与背景融合。 当制作可在网页上滑动或结束的图形时,这特别有用。

预定义名称:matplotlib 将标准 HTML 颜色名称解释为实际颜色。 例如,字符串red将被接受为一种颜色,并将被解释为亮红色。 几种颜色具有一个字母别名,如下表所示:

别名 颜色
b 蓝色
g 绿色
r 红色
c 青色
m 品红
y 黄色
k 黑色
w 白色

HTML 颜色字符串:matplotlib 可以将 HTML 颜色字符串解释为实际颜色。 这样的字符串定义为#RRGGBB,其中RR,GG和BB是十六进制的红色,绿色和蓝色分量的 8 位值。

灰度字符串:matplotlib 将浮点值的字符串表示形式解释为灰色阴影,例如0.75用于中等浅灰色。

xkcd:sky blue-这是xkcd颜色调查中的一种颜色。xkcd:必须在实际颜色代码之前。 请在此站点上找到颜色的完整列表。

颜色代码(b,g,r,c,m,y,k,w)及其扩展名(blue,green,red,cyan,magenta,yellow,black,white)。

tab:blue,tab:orange,tab:green,tab:red,tab:purple,tab:brown,tab:pink,tab:gray,tab:olive,tab:cyan)是来自表格的颜色T10分类调色板(这也是默认的颜色周期)。 我们可以在它们之前使用tab:来指定这些颜色,也可以不使用tab来指定这些颜色。 两者都是可以接受的。

我们也可以指定 RGB 或 RGBA 格式的十六进制值。 任何通道的十六进制值范围从00到FF。 因此,RBG 的范围从000000到FFFFFF,而 RGBA 的范围从00000000到FFFFFFFF。A代表 Alpha,代表颜色的透明度; 朝向00高度透明,朝向FF不透明。所有这些都不区分大小写,因此我们可以使用大写或小写字母。

另外一个选项是CN,其中C区分大小写,并且必须是大写字符,后跟数字,这是默认颜色周期中颜色的索引。 如上所述,默认周期中的第一种颜色是蓝色,然后是橙色,绿色,红色,紫色,等等。 因此,C0代表蓝色,C1代表orange,依此类推。

以下是许多颜色规格的演示:
xkcd:sky blue:xkcd颜色调查的名称
green:CSS4 颜色名称
1F1F1F1F:RGBA 格式的十六进制值; 数字范围为 0-F。
b:CSS4 颜色的缩写
1C0B2D:RGB 格式的十六进制值
pink:色表
C4:属性周期中的颜色; 这是区分大小写的,必须将C大写

1.5.1 颜色设置的属性

  1. colors/color,(c)
  2. cmap
  3. facecolor(fc),edgecolor(ec)
  4. markerfacecolor,markeredgecolor

1.5.1.1 color参数(饼图是colors)

大多数图形几乎都有color参数,根据所绘制的内容,可以为图形的元素添加颜色,比如点,线,块等。我们可以为所有的部分设置一种颜色,有时我们也可以为每一个点设置一个颜色。或者为每一种点设置一个颜色(给相同种类的点赋予同样一份颜色)。

对于一些对象,一般是通过set_color()设置

1.5.1.2 camp参数(颜色表的使用)

我们知道当color参数传递的是值列表时,如果此时设置cmap则是将这个值对应到cmap中的某种颜色表。有hsv和hot等。

颜色表在,,matplotib.cm模块中定义。 该模块提供函数来创建和使用颜色表。 它还提供了预定义颜色表的详尽选择。函数pyplot.scatter()接受color参数的值列表。 提供颜色表(带有cmap参数)时,这些值将被解释为颜色表索引,散点图等图具有camp参数,但是条形图没有。

plt.clim(-1, 1)将颜色(实际上是数据范围)限制在 -1 和 1 之间。

当某些图不支持cmap参数,但是我们又想要使用颜色表的颜色时,可以实现将值映射到颜色表,然后再使用。

这一次,我们将直接使用颜色表对象,而不是让渲染函数自动使用它。 我们还将需要matplotlib.colors模块,其中包含与颜色相关的工具函数,如以下脚本所示:

cm.ScalarMappable(值,颜色表)来构建映射
col.Normalize(vmin,vmax)可以生成可以用来映射的数字
cmap.to_rgba()可以将值列表转化为颜色列表显示了
cm.binary也是一种颜色表

指定要使用的色谱。 每年将以不同的颜色表示:

颜色表使用方式总结:

  1. 使用camp参数,将colors值列表转化为cm中的某种颜色表
  2. 直接选择颜色表,比如cm.hot(np.linspace()),通过取值生成想要数量的颜色
  3. 使用plt.colors,生成一系列可以转化为颜色的数字列,前提是先用cm.ScalarMappable将该数字值映射到颜色表中

颜色表有:cm.OrRd,cm.hot,cm.hsv,cm.binary等。

1.5.1.3 edgecolor参数(ec)

设置边缘颜色,包括条形图,饼图,轴域,画布等。但是轴域的设置必须从全局设置mpl.rc,即该脚本的轴域边缘颜色必须只有一种。

画布虽然可以设置,但是效果并不明显。

1.5.1.4 facecolor参数(fc)

设置内部颜色,或者是轴域,画布等背景颜色。

plt.figure(facecolor=‘y’) plt.axes(facecolor=‘r’) plt.plot([12,3],color=‘g’)

1.5.2 颜色设置的函数

  1. plt.fill()
  2. plt.fillbetween(),plt.fillbetweenx()

plt.fill(x,y,color/facecolor),x为x轴点列,y为y轴点列,color为颜色。会连接这些点在内部填充。

plt.fill_between(x,y1,y2,facecolor),x为x轴范围,y1为y轴上界范围,y2为y轴下界范围,默认为0,facecolor设置填充色。

plt.fill_betweenx()设置y轴范围,和x左边界,y右边界。

1.5.3 自定义颜色和颜色表

  1. 连续型颜色表
  2. 离散型颜色表
  3. 使用自定义的颜色

cm.get_cmap('coolwarm', 3)从颜色表中获取三种颜色

from matplotlib.colors import LinearSegmentedColormap这个模块是用来自定义颜色表的。

cmap_name = ’custom_RGB_cmap’定义第一个用户定义的颜色表的名称。 如果我们必须注册它以将其包括在标准颜色表库中,这将很有用。

cm = LinearSegmentedColormap.from_list(cmap_name, colors2, N=3)使用先前定义的三种颜色的列表定义颜色表。

如果colors是颜色列表形式,则是离散的,比如colors = [(1, 0, 0), (0, 1, 0), (0, 0, 1)],每一个颜色不存在渐变的效果。

如果colors是字典形式,定义一个元素有一个渐变的效果,比如。

cdict1 = {'red':   ((0.0, 0.0, 0.25), (0.5, 0.4, 0.4), (1.0, 0.8,  1.0)),
        'green': ((0.0, 0.0, 0.25), (0.25, 0.5, 0.5), (0.75, 0.75,  0.75), (1.0, 0.9, 1.0)),
        'blue':  ((0.0, 0.0, 0.25), (0.5, 0.5, 0.5), (1.0, 0.75, 1.0))}

cdict1中有三种元素,每一种元素里面又是渐变的效果。

1.6 图例

图例是给定轴域上每个图的描述。 每个轴域都有其自己的图例。

1.6.1 图例生成方式

plt.legend

  1. 图形生成时设置label,之后直接调用plt.legend()
  2. 获取图形对象,为图形对象使用set_label(’’)设置标签,然后调用plt.legend()
  3. 在plt.legend([obj],[label])中设置标签,可以通过对象名对应,也可以不设置对象,直接按顺序对应
  4. 可以只为一部分图形设置标签,如果图形和legend都设置了标签,以legend为准。

1.6.2 图例位置

  1. 固定位置。loc参数:数字0到10或者字符串参数[‘best’,‘upper left’,‘lower left’,‘lower right’,‘right’,‘center left’,‘center right’,‘lower center’,‘upper center’,‘center’,‘left’]。
  2. 自定义位置:bbox_to_anchor参数:设置相对轴域位置,内部参数为(left,bottom,width,height,ncol=‘2’,mode=“expand”, borderaxespad=0.5),比如plt.legend(bbox_to_anchor=(0, 1.02, 1., .102), ncol=2, mode="expand", borderaxespad=0.5)与图的大小成比例,从左起 0,从底部起 1.02,宽度为 1.0,高度为 0.102)。ncol=2指定标签应放在两列中,而不是两行中,这是默认设置。

1.6.3 同一个轴域中图例的分离

如果对一个轴域多次调用legend,则只以最后一次为准,所以我们无法通过多次调用legend来实现图例的分离

我们需要为图形对象分别生成图例,然后把前n-1个图像通过plt.gca().add_artist(‘legend_name’),添加到轴域中,而最后一个图形正常添加。

plt.gca()获取当前轴域,plt.gca().add_artist(图例对象),在轴域中添加图例。

1.7 使用标注 plt.annotate()

pyplot.annotate()函数显示与pyplot.text()相同行的文本。 但是,也会显示一个箭头。 要显示的文本是第一个参数。 xy参数指定箭头的目的地。 xytext参数指定文本位置。 与pyplot.text()相似,可以通过horizontalalignment和verticalalignment参数进行文本对齐。 shrink参数控制箭头的端点和箭头本身之间的间隙。

a = plt.annotate("(3,0)", xy=(3, 0), xycoords='data', xytext=(4.0, 
                0.5), textcoords='data',
            arrowprops=dict(arrowstyle="->", color="green", lw=5, 
            connectionstyle=("arc3,rad=0.")))

箭头的方向由传递给 arrowprops参数的字典控制:
'arrowstyle':参数''<-'',''<'',''-'',''wedge'',''simple''和"fancy"控制箭头的样式
'facecolor':这是箭头所使用的颜色。 它将用于设置背景和边缘颜色
'edgecolor':这是箭头形状边缘使用的颜色
'alpha': 这用于设置透明度,以便箭头与背景融合
plt.annotate()方法使用指定的详细信息标注图形。
(3, 0)指定要显示为描述的文本。
xy = (3, 0)指定图形上要标注的点的坐标。
xycoords='data'指定所指定的xy坐标是相对于数据(输入数据中的点)的。
arrowprops()指定从文本到要标注的点要使用的箭头的style,linewidth,color,connectionstyle。
plt.setp()将文本(3, 0)的字体大小设置为25。

1.9 文本和字体设置

1.9.1 字体设置

定义font字典以应用于绘图中的所有文本:

font = {‘family’: ‘DejaVu Sans’, ‘name’: ‘Times New Roman’, ‘style’: ‘italic’, ‘color’: ‘orange’, ‘weight’: ‘bold’, ‘size’: 16}

font是我们要应用于每个文本项的各种文本属性的字典: family和name代表字体系列和字体名称 style表示它是斜体还是正常 weight表示它是否为粗体 size代表字体大小

1.9.2 latex形式

只需要在标签中加上$$即可,但是反斜杠需要注意意义。所以可以写成r'$label$'这样反斜杠就不会被解释错误。

1.9.3 plt.text添加文本

  1. 文本对齐控制(va和ha)

文本由框限制。 此框用于使文本与传递给pyplot.text()的坐标相对对齐。 使用verticalalignment和horizontalalignment参数(相应的快捷方式分别为va和ha),我们可以控制对齐方式。

垂直对齐选项如下:

‘center’:相对于文本框的中心

‘top’:相对于文本框的上侧

‘bottom’:相对于文本框的下侧

‘baseline’:相对于文本的基线

水平对齐选项如下:

‘center’:相对于文本框的中心

‘left’:相对于文本框的左侧

‘right’:相对于文本框的右侧

还有一个rotation参数控制旋转角度

  1. 边界控制

pyplot.text()函数支持bbox参数,其中将字典作为输入。 该词典定义了文本框的各种设置。

将传递给bbox参数的字典定义了以下键值对:

'facecolor':这是用于包装盒的颜色。 它将用于设置背景和边缘颜色
'edgecolor':这是用于盒子形状边缘的颜色
'alpha':用于设置透明度级别,以使框与背景融合
'boxstyle':设置框的样式,可以是'round','square',"circle","darrow","larrow","rarrow","square","sawtooth"和"roundtooth"
'pad':如果'boxstyle'设置为'square',则定义文本和框的两边之间的填充量

offset=72用于指定要放置文本框的坐标。 该偏移量相对于要标注的点的xy坐标。x 坐标的正偏移量表示该点的右侧,而负值表示该点的左侧。 同样 y 坐标的正偏移量表示该点上方,而负值表示该点下方。

1.9.5 小数,常规数学表达式和符号

我们将学习如何将小数,二项式,符号和数学表达式嵌入绘图以及属性(例如标签和标题)。 在每个图上绘制的函数与其中嵌入的各种文本元素均不相关。 它们全部旨在演示如何在图上打印各种文本元素。

mathcal打印书法字体,mathrm打印罗马字体,mathit打印斜体字体

在r'$\Delta_i^j \hspace{0.4} \mathrm{versus} \hspace{0.4}和r'\Delta_{i+1}^j$'中,'连接两个正则表达式,它们跨越两行:

Delta_i^j代表大写希腊字母Δ,其中下标为i和上标为j
hspace{0.4}代表之间的空白
mathrm{versus}以罗马字体打印versus(mathrm中的rm代表罗马)
Delta_{i+1}^j是Δ,带有下标i + 1和上标j
在r'$\frac{2}{3} \binom{2}{3} \stackrel{2}{3}$'中:

frac{2}{3}在 3 上打印 2,中间有一条水平线,frac代表小数
binom{2}{3}在括号内打印 2 和 3
stackrel{2}{3}在 3 上面堆叠打印 2
在r'$\left(\frac{3 - \frac{1}{x}}{2}\right)$'中:

'left('打印横跨整个表达式的左方括号"("
"right)"打印右关闭括号")"
frac是分数,其工作方式与之前所述的相同
在r'$\mathcal{R}\prod_{i=\alpha_{i+1}}^\infty \gamma_i\/\sin(2 \pi f x_i)$'中,以下内容适用

mathcal{R}以书法字体打印R(mathcal中的cal代表书法):
prod以大字体打印大写希腊字母Π
prod之后的"*_*"是下标,但与prod和sum之类的大符号一起使用时,它的工作原理略有不同。
alpha是小写希腊字母α
infty打印无穷大符号∞
gamma打印小写希腊字母γ
\/打印空白(类似于hspace)
sin代表正弦函数
pi打印小写希腊字母π。

1.9.6 二维的词嵌入

对于自然语言处理(NLP)应用,由于机器只能处理数字数据,因此需要以数字格式表示单词。 在数字数组中表示单词的过程称为“单词嵌入”,因为这些数组(单词表示形式)中的每一个都是 n 维空间中的一个点,其中n是维数/特征数(数组)代表每个单词。

根据 NLP 应用的类型,对机器学习(ML)算法进行了训练,以学习单词表示。 单词表示的典型长度可以在 50 到 300 维之间变化,这是无法可视化或理解的。 使用降维技术(例如 PCA 或 t-SNE),可以将该高维空间缩小为二维或三维空间,以便可以将其绘制在图形上以可视化相似词是否彼此接近 。 如果是这样,那么我们的机器学习算法就可以正常工作; 否则,事实并非如此。

对于此示例,我采用了用跳过语法算法学习的单词表示,并使用 t-SNE 算法将其简化为二维空间。 在此秘籍中绘制了最终的二维输出。

导入所需的库。 请注意,pickle是一个 Python 包,用于以二进制格式保存和检索文件。 我们将在这里使用它来加载以前保存的二维单词表示形式和一个单词字典,该单词字典将数字表示形式映射到将在绘图上显示的文本单词:

import matplotlib.pyplot as plt
import pickle
#使用pickle加载数据:
twod_embeddings = pickle.load(open('twod_embeddings','rb'))
reverse_dictionary = pickle.load(open('word_reverse_dictionary','rb'))
#使用rcParams设置图形参数:
plt.rcParams['axes.labelsize'] = 20
plt.rcParams['axes.labelweight'] = 'bold'
plt.rcParams['xtick.labelsize'] = 15
plt.rcParams['ytick.labelsize'] = 15
#定义图形和轴域:
fig, ax = plt.subplots(figsize=(20,20))
#绘制散点图并使用annotate嵌入单词:
num_points = 400
words = [reverse_dictionary[i] for i in range(1, num_points+1)]
for i, label in enumerate(words):
    x, y = twod_embeddings[i,:]
    ax.scatter(x, y)
    ax.annotate(label, xy=(x, y), xytext=(5, 3), textcoords='offset points',ha='right', va='bottom')
#设置标签:
ax.set_xlabel('X')
ax.set_ylabel('Y')
#在屏幕上显示图:
plt.show()

twod_embeddings = pickle.load(open('twod_embeddings','rb'))加载二维单词表示。 如前所述,pickle是 Python 包,用于以二进制格式保存和检索文件。 我们正在从twod_embeddings文件加载数据,'rb'表示以二进制格式读取。
reverse_dictionary = pickle.load(open('word_reverse_dictionary','rb'))加载用于将数字映射到相应文本单词的单词字典,该单词字典将显示在绘图上。
plt.rcParams['axes.labelsize'] = 20设置 x 和 y 轴labelsize。
plt.rcParams['axes.labelweight'] = 'bold'设置 x 和 y labelweight。
plt.rcParams['xtick.labelsize'] = 15设置 x 轴刻度值的大小。
plt.rcParams['ytick.labelsize'] = 15设置 y 轴刻度值的大小。
fig, ax = plt.subplots(figsize=(20,20))定义并实例化绘制绘图的图形和轴域。
num_points = 400,我们仅绘制前 400 个单词。 我们使用 t-SNE 算法在减小大小的同时设置了此限制,因为超过此数量可能会导致绘图中的单词重叠。
words = [reverse_dictionary[i] for i in range(1, num_points+1)]创建一个包含 400 个单词的列表,reverse_dictionary存储这些单词,它们的索引从 1 到 400+(训练集的总词汇量)开始。
x, y = twod_embeddings[i,:]从twod_embeddings降维数组中读取单词的坐标,并将其映射到x和y。
ax.scatter(x, y)绘制由x和y坐标表示的单词。
ax.annotate(label, xy=(x, y), xytext=(5, 3), textcoords='offset points',ha='right', va='bottom')在绘制的点旁边绘制相应的单词,label表示该单词。 此外,xy表示要标注的点的坐标,xytext表示要绘制文字的坐标;textcoords指定xytext 的坐标系,最后ha和va指定文本的水平和垂直对齐。
ax.set_xlabel('X')设置 x 轴标签。
ax.set_ylabel('Y')设置 y 轴标签。
plt.show()在屏幕上显示绘图。

1.10 线条设置

对于有线条的都可以设置线条格式,比如条形图的边框,网格等都是由线条组成的。

1.10.1 设置线条样式linestyle属性(ls)

linestyle取值:

'-'       solid line style
'--'      dashed line style
'-.'      dash-dot line style
':'       dotted line style
'-.'
' '        实线,最后一条实线用于演示属性设置函数plt.setp()的可用的steps样式。 此选项不能像其他线型一样直接使用。

既可以用符号,也可以用字符,如‘dashed’

1.10.2 设置线条宽度linewidth(lw)

利用浮点值

linewidth=1

1.10.3 添加图形

plt.Rectangle((x,y),width,height)#(x,y)为左下角的点
plt.Polygon((x,y))#x,y为点列
plt.Circle((x,y),radius)#圆心半径

1.10.4 添加线条

当您有非常具体的需求时,matplotlib 提供的数据可能对您没有太大帮助。 matplotlib 制作的所有图形均由基本图元组成。 在演示如何更改箱形图的颜色时,我们提到大多数 matplotlib 绘图函数都会返回线条和形状的集合。 现在,我们将演示如何直接使用基本图元。

在此脚本中,我们绘制了 16 条独立的线。 pyplot.Line2D()函数创建一个新的Line2D对象。 强制性参数是该行的端点。 可选参数是我们之前针对基于线的图形所见的所有参数。 因此,您可以使用linestyle,linewidth,marker,markersize,color等。

pyplot.Line2D()函数创建了该行,但是除非您明确要求,否则不会渲染该行; 这是使用pyplot.gca().add_line()完成的。 pyplot.gca()函数返回负责跟踪渲染内容的对象。 调用gca().add_line()只是表示我们要渲染一条线。

需要使用pyplot.axis(‘scaled’)函数以确保图形使用统一的比例尺:与 x 和 y 轴上使用的比例尺相同。 这与默认行为’tight’形成对比,其中默认值 matplotlib 将为 x 和 y 轴赋予不同的比例,以使图形尽可能紧密地适合显示表面。

1.10.5 添加补丁(形状)patches

无论显示哪种形状,原理都相同。 在内部,形状被描述为在 matplotlib API 中称为“补丁”的路径。 matplotlib.patches模块中提供了几种形状的路径。 实际上,该模块包含用于所有附图的补丁。 与线条一样,创建路径不足以渲染它。 您将必须表示要渲染它。 这是通过pyplot.gca().add_patch()完成的。

许多路径构造器都可用。 让我们回顾一下示例中使用的那些:

**Circle**:将其中心坐标和半径作为参数
**Ractangle**:将其左下角的坐标及其大小作为参数
**Ellipse**:将其中心坐标和两个轴的半长作为参数
FancyBox :这就像一个矩形,但带有一个附加的boxstyle参数('larrow','rarrow','round','round4','roundtooth','sawtooth'或'square')

除了在patches中可以设置形状,也可以直接在plt中设置。

patches,line2D可以看成是已经定义好的路径,通过plt.gca()实现这些路径的渲染,呈现为图形。或者也可以用自己自定义的路径,然后添加,不过path模块自带添加补丁的操作。

所有路径都有我们先前已经探讨过的几个属性:linewidth,linestyle,edgecolor,facecolor,hatch等

1.11 点设置

1.11.1 设置标记的样式marker

可以通过以下各种方式将标记指定为:

预定义标记:它们可以是预定义形状,可以将表示为[0, 8]范围内的数字,也可以包含一些字符串

顶点列表:这是值对的列表,用作形状的路径的坐标

正多边形:它将正 N 边形表示为带有旋转角度的三元组(N, 0, 角度)

正多角星:它将正 N 角星表示为带有旋转角度的三元组(N, 1, 角度)

marker style
'.'       point marker
','       pixel marker
'o'       circle marker
'v'       triangle_down marker
'^'       triangle_up marker
'<'       triangle_left marker
'>'       triangle_right marker
'1'       tri_down marker
'2'       tri_up marker
'3'       tri_left marker
'4'       tri_right marker
's'       square marker
'p'       pentagon marker
'*'       star marker
'h'       hexagon1 marker
'H'       hexagon2 marker
'+'       plus marker
'x'       x marker
'D'       diamond marker
'd'       thin_diamond marker
'|'       vline marker
'_'       hline marker

1.11.2 对于折线图设置

只能设置一种

markersize = 9#设置点的大小
markeredgewidth = 1.5,#设置点边缘的宽度
markerfacecolor = '.75',#设置点的填充颜色
markeredgecolor = 'k',#设置点的边缘宽度
marker = 'o',#设置点的格式
markevery = 32#设置没过多少个点画一个点。

1.11.3 对于散点图设置

s=设置大小,可以为列表
c=设置颜色,可以为列表
fc=设置填充颜色,可以为列表
ec=设置边缘颜色,可以为列表
marker=设置点的格式,只能一种

如果想要为一幅图中的不同类型的点设置不同的样式,需要对每一种类型的点画一次图,然后聚合在一起。

1.12 属性循环

Matplotlib 具有默认的颜色循环,当我们在给定轴域上绘制更多图形时,该颜色循环将重复出现。 通过属性循环器,我们可以在单个函数中为多个属性定义此类循环器。 如果要绘制具有重复图案的轴域,则可以使用属性循环器实现。

from cycler import cycler
custom_cycler = cycler('color', ['g', 'blue', 'y', 'c']) + \  #属性名称和属性值列表。
                cycler('hatch', ['+*', 'xx', '+x', '+O.'])
ax.set_prop_cycle(custom_cycler)
cycler()用两个属性以及每个属性的四个值定义属性周期。 如果我们为每个属性提供更多值,则在覆盖列表中的所有值后,将重复和循环。
ax.set_prop_cycle(custom_cycler)激活先前定义的自定义属性循环器。

我们还可以在全局参数rcParams文件中设置属性循环器,该文件随后成为给定会话的默认循环器。

import matplotlib as mpl
from cycler import cycler
mpl.rc('axes', prop_cycle=cycler('color', ['r', 'orange', 'c', 'y']) +\
                        cycler('hatch', ['x', 'xx-', '+O.', '*']))

1.13 路径效果

path_effetcts

from matplotlib.patheffects import PathPatchEffect, SimpleLineShadow, Normal
path_effects[]指定要应用于文本对象的PathPatchEffects的列表。
PathPatchEffect()启用具有各种属性的自定义路径效果。
plt.plot()再次使用path_effects[]绘制了一个 Sigmoid 曲线。 在这里,我们使用,预定义路径效果SimpleLineShadow()和Normal()。

t = plt.text(-10., 1.15, 'Sigmoid with Path Effects', fontsize=40, 
            weight=50, va='center', path_effects=[PathPatchEffect(offset=(3, -3),   
            hatch='xxxx', facecolor='gray'),
            PathPatchEffect(edgecolor='white', linewidth=1.1, 
            facecolor='black')])
#使用,指定的路径效果绘制 Sigmoid 曲线,并在屏幕上显示该图:
plt.plot(x, y, linewidth=8, color='blue', path_effects=
                            [SimpleLineShadow(), Normal()])
plt.show()

1.14 使用转换

要引用图形上的特定点,我们需要其坐标。 Matplotlib 使用四种参考数据,轴域,图形和显示的坐标系。 在本秘籍中,我们将学习如何使用这些坐标系以及如何从一个坐标系转换为另一个坐标系:

数据:数据坐标系以输入数据点为坐标,并由xlim和ylim参数控制以在图上限制要绘制的数据范围。 从数据坐标系转换为显示坐标系的方法是ax.transData。这个就是根据数据点的坐标

轴域:轴域坐标系引用的轴域对象,(0, 0)为的轴域的左下角,而(1, 1)是轴域的右上角。 指向轴域中心的点的坐标为(0.5, 0.5)。 从轴域坐标系转换为的显示坐标系的方法是ax.transAxes。这是相对位置,范围为0,1

图形:这是图形对象的引用。 同样,(0, 0)表示图的左下角,而(1, 1)表示图的右上角。 从图形坐标系转换为显示坐标系的方法是ax.transFigure。

显示:这引用输出图形的输出设备,并且以像素坐标表示。各种输出设备的默认设置有所不同。 这就是为什么不经常使用显示坐标的原因。 它们仅在需要捕获键盘或鼠标事件的交互式绘图中有用。

我们还可以使用混合坐标系,其中一个轴使用数据坐标系,另一个轴使用轴域坐标系。

很少使用显示和图形坐标。数据和轴域坐标系使用得更频繁。

我们将有两个秘籍,一个用来演示数据坐标的转换以显示坐标,另一个演示数据的轴域和混合坐标系统

1.14.2 使用轴域和混合坐标系转换

#将的 y 坐标转换为轴域坐标,并将 x 坐标保持为数据坐标:
trans = transforms.blended_transform_factory(ax2.transData, ax2.transAxes)
#用矩形框突出显示 0.05 到 0.25 stddev区域,在数据中显示 x 坐标,并且在轴域上显示 y 坐标:
rect = patches.Rectangle((0.05, 0), width=0.2, height=1,transform=trans, 
                        color='green', alpha=0.3)

1.15 使用ConnectionPatch

用ConnectionPatch()方法连接同一图形上的两个点或同一图形上的两个不同图形。 当试图显示绘图上两个点之间的关系时,这很方便。

from matplotlib.patches import ConnectionPatch

con = ConnectionPatch(pointA, pointB, coordsA, coordsB, arrowstyle="fancy", 
                    shrinkA=5, shrinkB=5, fc="k")
con = ConnectionPatch(xyA=pointC, xyB=pointC, coordsA=coordsC, 
                    coordsB=coordsD, axesA=ax2, axesB=ax1, 
                    arrowstyle="wedge", shrinkB=5)

1.16 面向对象的api绘图

如“Matplotlib 的剖析”中所述,Matplotlib 具有三层架构。 顶层称为脚本层,并通过pyplot() API 实现。 该 API 是为没有太多编程经验的用户设计的,因此它使用户免受使用底部两层(艺术家和后端)创建和渲染图的复杂性的困扰。 对于使用高级功能(例如补丁,集合,使用事件,回调,动画和窗口小部件的交互式绘图)的复杂应用,我们将必须使用面向对象的 API。 但是,要利用此 API 的全部潜能,需要大量的 Python 编码经验。 随着新版本 Matplotlib 的发布,越来越多的这些功能正在移入pyplot API 中,从而减少了对面向对象 API 的依赖。

面向对象的 API 名称有点让人困惑,因为它可能给人以pyplot API 不是面向对象的印象,这是不正确的。 这仅意味着面向对象的 API 会直接使用艺术家和后端层,而绕过脚本层(不使用pyplot API)。 这提供了使用 Matplotlib 提供的完整功能的灵活性,而pyplot API 提供了它的一个子集。

应该注意的是,对于任何绘图或图形,都不必是pyplot API 或面向对象的 API; 它可以是两者的结合。 实际上,到目前为止,我们开发的许多图形都将两者结合使用。 当我们必须使用复杂的网格结构在图形中放置图时,我们使用了面向对象的 API。 当分别绘制每个图形并创建图形对象和基础画布时,我们使用了pyplot API。 一旦我们看到了两种 API 之间的差异,您将了解两种 API 的结合使用。

from matplotlib.figure import Figure #创建画布
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas #在这里,我们要导入FigureCanvasAgg,它提供了绘制图形的空间并将其映射到定义的后端设备.
from matplotlib.backends import backend_agg # matplotlib.backends具有一组支持的后端。
from matplotlib.patches import Ellipse, Polygon #添加补丁
from matplotlib import collections #添加集合
from IPython.core.display import display #IPython.core.display可以将绘图显示在输出设备上。

1.17 保存图形

支持的格式为\['png', 'pdf', 'svg', 'svgz','eps','ps'\]

1.17.1 plt.savefig()

plt.save(‘文件名’,参数)

在plt.savefig()调用中,可以使用facecolor和edgecolor和许多其他选项来修改图形,然后再将其保存为所选格式.

为了在边界上创建一些额外的空间,我们使用pad_inches=1参数
bbox_inches='tight'参数时生成的输出。 这实质上是尝试使整个图适合输出中包括标签文本的整个图形。 现在,您可以在 y 轴上看到直方图标签:
labelpad=30,标签与轴之间的空隙

1.17.2 保存轴域中的部分图形

标记要保存区域的边界,并以 PNG 和 PDF 格式保存该区域:

bounds = np.array([[0.0,0.0], [4.1, 6.0]])#图形的左下角坐标和右上角坐标
plt.savefig('polar.png', bbox_inches=Bbox(bounds)) 
plt.savefig('polar.pdf', bbox_inches=Bbox(bounds))

1.17.3 图形分辨率

打印输出的质量取决于图像(保存的图像)中的像素数量,要在其上打印纸张的页面大小以及打印机分辨率。

通常,图像中的像素数取决于相机的分辨率,例如 5MP,7MP,10MP 等。 纸张大小由称为每英寸像素(PPI)的设置控制。 像素是图像的最小可测量元素,并且是微小的小正方形。 如果我们有一个600 x 400像素的图像,并使用 100 PPI,则纸张大小将为6 x 4英寸。 这就是用给定数量的像素,PPI 和以英寸为单位的大小创建图像的方式。

当要打印图像时,打印机具有另一种影响打印输出质量的分辨率,称为每英寸点数(DPI)。 它以英寸的长度(宽度相同)指定打印机需要喷射的墨水点数。 DPI 越高,一英寸长度内的墨水量越大,因此打印输出的质量越好。

因此,PPI 是创建图像时使用的分辨率的输入端。 DPI 是打印图像时使用的分辨率的输出端。 对于给定的设备,PPI 和 DPI 由制造商预先确定; 例如,计算机显示器具有固定的 PPI,而打印机具有固定的 DPI。

plt.savefig()方法具有dpi参数,该参数与图形大小一起以像素数确定图像(图形)的大小。 在这里,DPI 是错误的称呼; 理想情况下,它应该是 PPI。

在plt.savefig()中用dpi参数来设计

plt.figure(figsize=(6,4))将图形大小设置为6 x 4。
plt.hist(nd)绘制直方图。
由于我们使用的是dpi=300,它将创建具有1,800 x 1200像素(6 * 300 x 4 * 300)的图形图像。
histogram_300.png中保存的图形如下:
如果必须在100 DPI 打印相同的1800 x 1200像素图形,则需要18 x 12的图形大小。我们再次使用18 x 12的大小和dpi=100保存图形。 这是保存的输出的外观:
应该注意的是,与我们之前用dpi=300和figsize=(6, 4)保存的图形相比,刻度标签和网格线已经变得更小。 当您在较小的区域上展开相同数量的像素(宽度和高度)时,像素的密度将很高,质量也将很高。 因此,在创建和保存图形时,请选择图形大小和 DPI 设置以根据所需打印输出的质量为图形的宽度和高度创建尽可能多的像素。 宽度和高度的像素数越高,打印输出的质量越好。

1.17.4 透明度

transparent=True使您可以在没有任何背景颜色的情况下打印图表。

1.17.5 创建多页pdf报告

import datetime
import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import calendar
#以下代码块绘制了所需的图表,并将它们作为三个单独的页面保存到 PDF 文档中。 所有这些图都已在较早的章节中使用过,因此绘制每个图的细节已经为您所熟悉。 在这里,重点是如何排列这些图表以将其保存在 PDF 文档的各个页面中:
#设置可重复性的种子:
np.random.seed(19681211)
#定义一个绘制极坐标图的函数:
def Plot_Polar():
    plt.figure(figsize=(6, 4))
    N = 250
    r = 10 * np.random.rand(N)
    theta = 2 * np.pi * np.random.rand(N)
    area = r**2 
    colors = theta
    ax1 = plt.subplot(121, projection='polar')
    ax1.scatter(theta, r, c=colors, s=area, cmap='plasma', 
                alpha=0.6)
    ax1.set_title('Polar Plot', color='m', size=15, weight='bold') 
#定义一个函数来绘制直方图:
def Plot_Histogram():
    ax2 = plt.subplot(122)
    nd = np.random.normal(25, 5, 10000)
    n, bins, patches = ax2.hist(nd, color='c', alpha=0.6)
    n, bins, patches = ax2.hist(nd, color='c', alpha=0.6, density=1)
    mu, sigma = 25, 5
    y = ((1 / (np.sqrt(2 * np.pi) * sigma)) * np.exp(-0.5 * (1 / 
          sigma * (bins - mu))**2))
    ax2.plot(bins, y, '--')
    ax2.set_title('Histogram', color='b', size=15, weight='bold')
#定义一个绘制饼图的函数:
def Plot_Pie(): 
    plt.figure(figsize=(8, 6))
    ax1 = plt.subplot(121)
    labels = ['grocery', 'transportation', 'apparel', 'education', 
              'capital', 'savings', 'others']
    percentage = [15, 5, 19, 8, 30, 13, 10]
    explode = [0, 0, 0, 0, 0.1, 0, 0]
    ax1.pie(percentage, labels=labels, explode=explode, 
            autopct='%.1f%%', shadow=True)
    ax1.set_title('Expenses Pie Chart', color='r', size=15, 
                   weight='bold')
    ax1.axis('equal')
#定义一个函数以绘制Iris群集图:
def Plot_iris():
    from sklearn import datasets
    ax2 = plt.subplot(122)
    iris = datasets.load_iris()['data']
    target=datasets.load_iris()['target']
    x,y = iris[:,2], iris[:,3]
    classes = set(target)
    for name in classes:
        index = target == name
        ax2.scatter(x[index], y[index], s=20*x[index]*y[index], 
                    marker='o', label=name, alpha=0.6)
    ax2.legend()
    ax2.set_title('Iris Classification', color='g', size=15, 
                   weight='bold')
#定义一个绘制条形图的函数:
def Plot_Bar():
    fig = plt.figure(figsize=(10, 8))
    ax1 = plt.subplot(121)
    month_num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    units_sold = [500, 600, 750, 900, 1100, 1050, 1000, 950, 800, 
                  700, 550, 450]
    plot = ax1.bar(month_num, units_sold)
    plt.xticks(np.arange(12)+1, calendar.month_name[1:13], 
               rotation=75)
    for rect in plot:
        height = rect.get_height()
        ax1.text(rect.get_x() + rect.get_width()/2., 
                 1.002*height,'%d' % int(height), 
                 ha='center', va='bottom')
    ax1.set_title('Batteries Sold', color='y', size=15, 
                   weight='bold')
    return fig
#定义一个绘制流图的函数:
def Plot_Steamplot(fig):
    ax2 = plt.subplot(122)
    x, y = np.linspace(-3,3,100), np.linspace(-2,4,50)
    X, Y = np.meshgrid(x, y)
    U = 1 - X**2 
    V = 1 + Y**2 
    speed = np.sqrt(U*U + V*V)
    # Varying line width along a streamline
    lw = 5*speed / speed.max()
    strm = ax2.streamplot(X, Y, U, V, density=[0.5, 1], color=V, linewidth=lw)
    fig.colorbar(strm.lines, plt.axes([0.95, 0.125, 0.03, 0.75]))
    ax2.set_title('Varying Density, Color and Line Width')
#定义一个函数来更新文档属性:
def Set_Doc_Properties():
    doc_prop = pdf.infodict()
    doc_prop['Title'] = 'Multipage PDF Reports'
    doc_prop['Author'] = 'P Srinivasa Rao'
    doc_prop['Subject'] = 'saving matplotlib plots in a pdf  document'
    doc_prop['Keywords'] = 'PdfPages multipage author title subject'
    doc_prop['CreationDate'] = datetime.datetime(2018, 7, 24)
    doc_prop['ModDate'] = datetime.datetime.today()
#定义用于创建多页 PDF 报告的主程序:
with PdfPages('pdf_reports.pdf') as pdf:
    # Page1
    Plot_Polar()
    Plot_Histogram()
    plt.suptitle('Page One', color='C5', size=20, weight='bold')
    plt.tight_layout(pad=5, w_pad=2)
    pdf.attach_note("polar & histogram")
    pdf.savefig(dpi=300) 
    plt.show()
    plt.close()
    # Page2
    Plot_Pie()
    Plot_iris()
    plt.suptitle('Page Two', color='C8', size=20, weight='bold')
    pdf.attach_note("pie and scatter")
    plt.tight_layout(pad=5, w_pad=10)
    pdf.savefig(dpi=300) 
    plt.show()
    plt.close()
    # Page3
    fig = Plot_Bar()
    Plot_Steamplot(fig)
    plt.suptitle('Page Three', color='C9', size=20, weight='bold')
    pdf.attach_note("bar & stream")
    pdf.savefig(dpi=300) 
    plt.show()
    plt.close()
    # Set document properties
    Set_Doc_Properties()

pdf文件

1.18 交互式绘图

事件是用户与绘图进行交互时所执行的操作,例如鼠标操作,键盘单击或只是在可视化文件上输入和退出图形和轴域。 回调是事件触发时对事件的响应。 程序运行时引发的异常也是事件。 但是,除了KeyboardInterrupt以外,大多数都不涉及用户干预。

对于交互式绘图,通常的%matplotlib inline不起作用,因为它将静态图形输出到屏幕,需要使用 Matplotlib 支持的后端之一。 您可能还记得后端是 Matplotlib 架构的最底层,其中发送了 Matplotlib 创建的输出图进行显示。 后端有两种类型:一种允许用户与输出交互并用于交互式绘图,另一种用于保存图形以供打印或嵌入到其他应用中。

本章中的所有秘籍均通过以下后端进行了测试:nbAgg Qt5Agg TkAgg WXAgg

使用后端的方式

import matplotlib
matplotlib.use('nbAgg')
#或使用此:
import matplotlib.pyplot as plt
plt.switch_backend('nbAgg')

如果选择第一个选项,则必须在导入matplotlib.pyplot模块之前执行此代码,因为pyplot模块将加载所选后端所需的所有元素。 默认情况下,pyplot会按照和rcParams文件的定义加载后端,如果这些语句是在导入pyplot之后执行的,则模块可能与此后端冲突。

如果您选择第二个选项,则pyplot将通过加载新后端的相关模块将当前后端替换为新后端。 为了使其正常工作,在切换到新后端之前应该已经设置了一些后端。

1.18.1 事件

事件 类型 含义
‘button_press_event’ MouseEvent mouse button is pressed
‘button_release_event’ MouseEvent mouse button is released
‘close_event’ CloseEvent figure is closed
‘draw_event’ DrawEvent canvas has been drawn (but screen widget not updated yet)
‘key_press_event’ KeyEvent key is pressed
‘key_release_event’ KeyEvent key is released
‘motion_notify_event’ MouseEvent mouse moves
‘pick_event’ PickEvent artist in the canvas is selected
‘resize_event’ ResizeEvent figure canvas is resized
‘scroll_event’ MouseEvent mouse scroll wheel is rolled
‘figure_enter_event’ LocationEvent mouse enters a new figure
‘figure_leave_event’ LocationEvent mouse leaves a figure
‘axes_enter_event’ LocationEvent mouse enters a new axes
‘axes_leave_event’ LocationEvent mouse leaves an axes
  • 定义事件的回调函数

MouseEvent:参数为事件,事件拥有属性event.button.由我们对鼠标的操作而产生,左键:传递参数为1,右键传递参数为3,滚动传递参数为2.
同时还拥有event.xdata,event.ydata
代表鼠标点击位置的数据坐标位置.同时还拥有event.x,event.y代表鼠标点击时的显示坐标系的坐标位置。
motion_notify_event没有button属性,拥有inaxes属性,判断鼠标位置是否在轴域中。

KeyEvent:参数为事件,事件拥有属性为key,由我们的按键动作产生值。我们可以通过event.key设置条件,比如当按下某个按键执行某种操作。请注意,后端导航具有一些具有特殊功能的键的映射,例如对于主页的h,对于主网格的g,在 y 轴上的对数刻度的l,以及用于平移, 缩放,后退,前进,全屏等的一些其他键。 当按下这些键中的任何一个时,您将在绘图上看到其定义的功能,因此请不要与用户定义的功能混淆。 您可能要避免为这些键定义自己的功能,以免发生冲突。

PickEvent:拾取事件,用来选择艺术家(artist),比如图例,线条等。参数为event,参数拥有属性artist代表鼠标点击的艺术家
在回调函数外还可以设置选择器的范围。加入现在有leg_line代表所有图例线条的列表。leg_line.set_picker(5)设置图例标签行的选择器。 数字 10 表示,即鼠标单击被捕获以触发相应对应选择事件的点数。 1 点是 1/72 英寸。 如果此数字太大,则单击可能会变得足够接近多个图例项目,并且所有这些项目可能会同时被触发! 因此,请将其设置得足够小以避免给定鼠标单击时图例行之间的重叠。选择器的此参数还有其他选项,None表示禁用选择器,布尔值True表示在图例行上单击时触发事件; 它也可以是用户定义的函数。

LocationEvent:光标位置在画布内,画布外,轴域内,轴域外,对于画布,可以设置event.canvas.figure.patch.set_facecolor(),对于轴域,可以设置event.inaxes.patch.set_facecolor(),event.inaxes.get_lines()[0]等

这些回调函数一般要跟fig.canvas.draw(),用来刷新图像。

  • 定义事件连接的方式

plt.connect('button_press_event', on_click)将按键按下事件与对应的回调函数on_click()连接起来。 plt.disconnect(连接实例的标识符)

fig.canvas.mpl_connect('button_press_event', onbuttonpress)捕获按键按下事件,并调用回调函数来响应该事件。

请注意plt.connect()方法将该事件与相应的回调函数连接,而使用canvas类的方法mpl_connect()。 区别在于plt.connect()是pyplot API 的一部分,而mpl_connect()是面向对象的 API 的一部分.

ax_c.callbacks.connect("ylim_changed", refresh_scales)这个就是自定义名称,并且给与函数。实现同步变化

1.18.2 小部件

定义游标:

当您将鼠标悬停在图形/轴域上时,Cursor小部件会用十字突出显示图形中的特定点。 这类似于我们在“运动通知和鼠标按下事件”秘籍中所做的操作,但是在这里我们将使用易于使用的小部件。

from matplotlib.widgets import Cursor
实例化光标小部件:
cursor = Cursor(ax, color='red', linewidth=5)#给定轴域,设置光标属性。

定义按键:按下按键后实现某种效果

from matplotlib.widgets import Button
axprev = plt.axes([0.7, 0.005, 0.1, 0.05])#确定轴域,这个轴域定义的是按键的位置
axnext = plt.axes([0.81, 0.005, 0.1, 0.05])
实例化上一个和下一个按键:
bnext = Button(axnext, 'Next')#当把这个轴域给按键化,就能变成按键的形式,并且命名
bprev = Button(axprev, 'Previous')
将的回调函数映射到prev和next的on_clicked事件:
bnext.on_clicked(cluster.next)#cluster.next是实现定义在cluster中的函数
bprev.on_clicked(cluster.prev)

复选按键:CheckButtons,可以选择多个

from matplotlib.widgets import CheckButtons
#准备CheckButtons所需的每条曲线的数据轴域,标签和可见性状态:
lines = [l1, l2, l3, l4, l5, l6, l7, l8]
cax = plt.axes([0.05, 0.27, 0.15, 0.5])
labels = [str(line.get_label()) for line in lines]
visibility = [line.get_visible() for line in lines]
#使用先前准备的必需属性实例化CheckButtons对象。
check = CheckButtons(cax, labels, visibility)
#定义响应复选框点击的回调函数:
def onclick(label):
    index = labels.index(label)
    lines[index].set_visible(not lines[index].get_visible())
    plt.draw()
check.on_clicked(onclick)

单选按键:RadioButtons,任何时候只有一个属性处于活动状态

rax = plt.axes([0.05, 0.5, 0.15, 0.25], facecolor='skyblue')
radio = RadioButtons(rax, ('USA', 'China', 'UK'))#位置和标签
#定义单击RadioButtons之一时执行的回调函数:
countrydict = {'USA': [US_GDP, 'g', '-.'], 'China': [China_GDP, 'b', 
            '--'], 'UK': [UK_GDP, 'm', '-']}
def country(label):
    ydata, color, ls = countrydict[label]#点击标签后获取相应的数据
    line.set_ydata(ydata)
    line.set_color(color)
    line.set_linestyle(ls)
    plt.draw()
#将点击事件连接到先前定义的对应的回调函数:
radio.on_clicked(country)

文本框

TextBox小部件是求值任何表达式的自由格式实现。 如果您想检查各种不同的数学表达式/函数,这将非常方便。

on_submit定义连接函数

from matplotlib.widgets import TextBox
#定义提交TextBox中的新表达式时要执行的回调函数:
def submit(text):
    ydata = eval(text)#通过eval实现了文本字符串的表达式效果
    l.set_ydata(ydata)
    ax.set_ylim(np.min(ydata), np.max(ydata))
    plt.draw()
#定义TextBox实现所需的轴域和initial_text:
axbox = plt.axes([0.1, 0.05, 0.8, 0.075])
initial_text = "x ** 5"
#实例化TextBox对象:
text_box = TextBox(axbox, 'Evaluate', initial=initial_text)
#将提交事件与先前定义的对应的回调函数连接:
text_box.on_submit(submit)

1.18.3 动画

动画是用于根据原始数据创建故事绘图的强大工具。 它是一系列视觉图表框架,这些框架连接在一起以创建视频。 Matplotlib 中的动画图可以另存为.mp4文件,可以像其他任何视频一样使用媒体播放器进行播放。

主要是两个函数:

FuncAnimation:用来定义函数实现逐帧播放。

ani = FuncAnimation(fig, animate, 1000, init_func=init, blit=True, interval=2, save_count=50,  repeat=False, repeat_delay=1000)激活动画。 由于我们需要维护对象的状态,因此必须将其分配给变量,如此处所做的:ani。 这也有助于将动画保存到.mp4文件,我们将在下一个秘籍中学习如何做:
fig是正在动画的图形。
animate是用于指示将和动画应用于绘图的方式的函数:
i是系统变量,包含正在处理的当前帧的帧号。
我们将 x 轴数据保持不变,但将 y 轴数据更改为帧号的函数。
1000是完成动画的帧数。 该数字可以是任意数字,具体取决于您希望动画运行多长时间。 这也可以是为animate函数提供数据的另一个功能。 我们将在后续秘籍中学习。
init_func=init一次指定要在开始时应用的初始化函数。 这是一个可选函数,也可以省略。 仅在重新启动blit=True时有用。 在这种情况下,我们只是将数据设置为nan(不是数字)。
blit=True指定仅刷新从前一帧更改为当前帧的图形部分。 这提高了处理速度。
interval=2指定连续帧之间的时间延迟为 2 毫秒。
save_count=50指定要保存在和高速缓存中的帧数,以提高性能。
repeat=False指定在完成所有 1,000 帧后停止动画。 如果我们说True,那么它将一次又一次地重复 1,000 帧的循环,直到结束会话为止。
repeat_delay=1000指定在完成上一个周期后的 1000 毫秒开始下一个周期。

这里的帧数既可以用数字,也可以用生成器函数。

ArtistAnimation:用来针对艺术家列表实现函数的播放

lines = [l1, l2, l3, l4, l5, l6, l7, l8]是在动画步骤 2 中定义的所有艺术家的列表,并将其作为参数传递给ArtistAnimation。

ani = ArtistAnimation(fig, lines, blit=True, interval=1000, repeat=True, repeat_delay=2500)通过以 1,000 毫秒的时间间隔一次显示一位艺术家来激活动画,并以 2500 毫秒的时间延迟重复循环。

1.18.3.1 动画保存

有两种方法可以保存图形:

import os
ffmpegpath = os.path.abspath("D://ffmpeg/ffmpeg-2021-02-02/bin/ffmpeg.exe")
mpl.rcParams["animation.ffmpeg_path"] = ffmpegpath
ani.save("sigmoid.mp4")         

您也可以这样保存它:

from matplotlib.animation import FFMpegWriter
import os
ffmpegpath = os.path.abspath("D://ffmpeg/ffmpeg-2021-02-02/bin/ffmpeg.exe")
mpl.rcParams["animation.ffmpeg_path"] = ffmpegpath
writer = FFMpegWriter(fps=25, metadata=dict(title='expdecay',artist='line'), 
                    bitrate=1800)
ani.save("sigmoid.mp4", writer=writer)

ani.save(“sigmoid.mp4”)将ani动画保存到工作目录中,名称为sigmoid.mp4。

第二个选项也做同样的事情,但是通过传递各种参数,在保存文件的方式上提供了更大的灵活性。 您可以参考文档详细了解这些参数,以及 Matplotlib 支持的其他编写器函数。 有关详细信息,请参见这里。

1.18.4 代码和图像展示

键盘按下和释放事件

+
    import numpy as np
    import matplotlib.pyplot as plt
    plt.switch_backend('Qt5Agg')
    from time import time
    #这是带有图例和标题的sin和cos函数的绘图,并捕获键盘事件和相关的回调函数以响应键盘事件的代码:
    #定义一个响应key_press_event的回调函数:
    def press(event):
        global prst
        prst = time()
        print('press', event.key)
    #定义一个响应key_release_event的回调函数:
    def release(event):
        relt = time()
        ht = relt - prst
        print('hold time:',round(ht,2))
        if event.key == 'x':
            visible = lg.get_visible()
            lg.set_visible(not visible)
            tm = 'hold time: ' + str7(round(ht, 2))
            t = plt.text(np.random.randint(1,4), 
                        np.random.randint(-3,4), tm)
            plt.setp(t, color='r', size=15, weight='bold')
            ax.add_artist(t)
            fig.canvas.draw()
    #准备要绘制的曲线的数据:
    x = np.arange(1, 2.6, 0.1) 
    y = 3*np.sin(2 * np.pi * x)
    y1 = 3*np.cos(2 * np.pi * x) 
    #实例化图形和轴域对象:
    fig, ax = plt.subplots()
    #在轴域上绘制曲线:
    ax.plot(x ,y, 'go-', label='sin')
    ax.plot(x, y1, 'bd-', label='cos')
    #设置图例和标题:
    lg = ax.legend(loc='upper center', fontsize=15)
    ax.set_title('Press a key', size=25)
    #捕获事件并为每个事件映射回调函数:
    fig.canvas.mpl_connect('key_press_event', press)
    fig.canvas.mpl_connect('key_release_event', release)
    #在设置的后端上显示该图:
    plt.show() 
    

鼠标按下事件

+
#鼠标按下事件
#在本秘籍中,我们将学习如何捕获鼠标按键按下事件,并使用坐标在主窗口上按下和鼠标按键的点周围缩放绘图,并将其显示在[ 缩放窗口。
#导入所需的库:
import matplotlib.pyplot as plt
import numpy as np
#在主窗口和缩放窗口中定义图形和轴域:也就是创建了两个画布
figmain, axmain = plt.subplots()
figzoom, axzoom = plt.subplots()
#设置主轴域和缩放轴域的属性:
axmain.set(xlim=(-5, 5), ylim=(-75, 175), autoscale_on=False, title='Click to zoom')
axzoom.set(xlim=(-2, 2), ylim=(-8, 8), autoscale_on=False, title='Zoom window')
#准备绘图数据:
x = np.arange(-5, 5, 0.1)
y = x ** 3
#在主轴域和缩放轴域上绘制相同的曲线:
axmain.plot(x, y, 'g-d')
axzoom.plot(x, y, 'b-.o')
#定义响应鼠标按键按下事件的回调函数:
def onbuttonpress(event):
    if event.button == 1:             # left = 1, scroll=2, right=3
        x, y = event.xdata, event.ydata
        axzoom.set_xlim(x - 1, x + 1)
        axzoom.set_ylim(y - 10, y + 10)
        figzoom.canvas.draw()
#将按键按下事件连接到回调函数:
figmain.canvas.mpl_connect('button_press_event', onbuttonpress)
#在指定的后端显示数字:
plt.show()
'''
figmain, axmain = plt.subplots()定义主窗口的图形和轴域,figzoom, axzoom = plt.subplots()定义缩放窗口的图形和轴域。
axmain.set(xlim=(-5, 5), ylim=(-75, 175), autoscale_on=False, title='Click to zoom')设置属性,例如 x 和 y 轴限制,自动缩放是打开还是关闭,以及主轴域标题。 axzoom.set(xlim=(-2, 2), ylim=(-8, 8), autoscale_on=False, title='Zoom window')为缩放轴域定义了和相同的属性。
x = np.arange(-5, 5, 0.1)和y = x ** 3是用于绘制非线性曲线的数据。
axmain.plot(x, y, 'g-d')在主轴域上绘制非线性曲线,axzoom.plot(x, y, 'b-.o')在变焦轴域上绘制非线性曲线。
onbuttonpress(event)是响应按键按下事件的回调函数。 通常,event是函数接收的参数:
if event.button == 1:检查是否按下了左键(滚动按键代码为2按键代码为3)。 如果是按左键,则执行后续步骤,如下所示。 否则,它将不执行任何操作而完成该函数。
x, y = event.xdata, event.ydata捕获绘制点上按下鼠标按键的点的坐标,在数据坐标系中。 应当注意,event.x和event.y在显示坐标系中具有相同的坐标。
axzoom.set_xlim(x - 1, x + 1)将缩放轴域的 x 轴限制从按下鼠标键的位置(鼠标单击)设置为+/-1。 因此,仅在这些限制内的曲线上的点将出现在缩放窗口中。
axzoom.set_ylim(y - 10, y + 10)将缩放轴域的 y 轴限制从按下鼠标键的点开始设置为+/- 10。 因此,仅在这些限制范围内的曲线上的点将出现在缩放窗口中。
figzoom.canvas.draw()用新的限制绘制数字。
figmain.canvas.mpl_connect('button_press_event', onbuttonpress)捕获按键按下事件,并调用回调函数来响应该事件。
plt.show()将输出发送到指定的后端。
'''


鼠标按下和鼠标移动事件

+
#运动通知和鼠标按键按下事件
#在本秘籍中,我们将学习如何捕获motion_notify_event和button_press_event并显示发生这些事件的点的坐标。
import matplotlib.pyplot as plt
import numpy as np
from time import time
#设置要绘制的图的数据:
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2 * np.pi * t)
#定义图形和轴域:
fig, ax = plt.subplots()
#绘制图形:
ax.plot(t, s)
#在str7_time变量中捕获开始时间:
str7_time = time()
#定义响应鼠标移动事件的回调函数:
def on_move(event):
    if event.inaxes:
        print('onmove data coords %.2f %.2f' % (event.xdata, 
               event.ydata))
    elapsed_time = time() - str7_time
    print('elapsed time', elapsed_time)
    if elapsed_time > 10:
        print('Closing onmove event after 10 sec')
        plt.disconnect(binding_id)
#定义响应鼠标按键按下事件的回调函数:
def on_click(event):
    if event.inaxes is not None:
        if event.button == 1:
            print('left click data coords %.2f %.2f' % (event.xdata, event.ydata))
            ax.text(event.xdata, event.ydata, 'left click here', 
                    weight='bold', color='m')
        elif event.button == 2:
              print('scroll click data coords %.2f %.2f' % (event.xdata, event.ydata))
              ax.text(event.xdata, event.ydata, 'scroll click here', 
                      weight='bold', color='m')
        elif event.button == 3:
              print('right click data coords %.2f %.2f' % (event.xdata, event.ydata))
              ax.text(event.xdata, event.ydata, 'right click here', weight='bold', color='m')
        fig.canvas.draw()
#将事件连接到对应的回调函数:
binding_id = plt.connect('motion_notify_event', on_move)
plt.connect('button_press_event', on_click)
#在指定的后端显示图形:
plt.show()
'''
on_move(event)是响应鼠标移动事件的回调函数:
if event.inaxes检查鼠标移动事件是否在轴域内或轴域外发生。 如果在轴域内,则执行下一组指令 ; 否则,事实并非如此。
print()打印数据坐标系中的坐标,在鼠标移至sysout的轴域上的点的时候。 您可以在笔记本的输出单元中看到它。
elapsed_time是从程序开始到现在的经过时间。 这用于停用move_event回调函数,因为鼠标移动事件会产生大量sysout ] 通过打印语句。
if elapsed_time > 10检查经过时间是否大于 10 秒; 如果是,它将closing onmove event after 10 sec打印到sysout,并且plt.disconnect(binding_id)断开on_move事件的连接。binding_id是定义事件和回调之间的连接时捕获的标识。
on_click(event)是响应鼠标单击(按键按下)事件的回调函数。 鼠标上有三个按键:左侧为 1,滚动为2,右侧为3。 每次单击按键时,它会在绘图本身上打印相应消息:
if event.button == 1:检查按下的按键是否为左键,然后将坐标打印到sysout和ax.text(event.xdata, event.ydata, 'left click here', weight='bold', color='m')创建要在绘图上显示的文字艺术家,当调用draw()函数时,该艺术家将可见。
按键 2(滚动)和 3(右)重复相同的功能。
binding_id = plt.connect('motion_notify_event', on_move)将运动通知事件与相应回调函数on_move()相连,并且其标识保存在binding_id和中,如果以后要断开此事件,则需要使用此标识。
plt.connect('button_press_event', on_click)将按键按下事件与对应的回调函数on_click()连接起来。
请注意,在此秘籍中,我们已使用plt.connect()方法将该事件与相应的回调函数连接,而之前我们使用canvas类的方法mpl_connect()。 区别在于plt.connect()是pyplot API 的一部分,而mpl_connect()是面向对象的 API 的一部分,我们在第 5 章“使用面向对象的 API 进行绘图”中了解。
运行该程序时,您应该看到以下图表,并将鼠标悬停在该图表上时,在输出单元格中的 10 秒钟内,您将在sysout中看到文本消息elapsed time 0.6132094860076904,  onmove data coords 0.14 -1.04。 实际的经过时间和坐标对您而言将有所不同,具体取决于您将鼠标悬停在绘图上的时间和位置:
'''

拾取事件

+
import random
y=[sorted([random.random() for j in range(10)]) for i in range(8) ]
#绘制所有折线图:
plt.plot([0, 1], [0, 1], 'k--')
l1, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[0], label='LogReg',color='purple')
l2, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[1],label='KNN',color='green')
l3, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[2], label='DecisionTree', color='orange')
l4, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[3], label='Random Forest',color='yellow')
l5, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[4], label='MLP',color='red')
l6, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[5], label='SVC',color='violet')
l7, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[6], label='GNB',color='grey')
l8, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[7], label='SGD', color='pink')
#将 alpha(透明度)设置为0.4来设置标签,标题和图例:
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC curve')
lgd = plt.legend(loc='lower right', fancybox=True, shadow=True)
#创建一个字典以使用和对应的图例标签映射绘图线:
pltlines = [l1, l2, l3, l4, l5, l6, l7, l8]
leg_ln_map = dict()
for leg_line, plot_line in zip(lgd.get_lines(), pltlines):
    leg_line.set_picker(10) 
    leg_ln_map[leg_line] = plot_line
#定义响应和on_pick事件的回调函数:
def onpick(event):
 # on the pick event, find the plot line corresponding to the legend line, and toggle the visibility
    leg_line = event.artist
    plot_line = leg_ln_map[leg_line]
    vis = not plot_line.get_visible()
    plot_line.set_visible(vis)
 # Change the alpha on the line in the legend so we can see what lines have been toggled
    if vis:
        leg_line.set_alpha(1.0)
    else:
        leg_line.set_alpha(0.2)
    fig.canvas.draw()
#将事件与对应的回调函数连接:
fig.canvas.mpl_connect('pick_event', onpick)
#将输出图形发送到选定的后端:
plt.show()

图和轴域的进入离开事件

+
#图和轴域的进入和离开事件
#在本秘籍中,我们将学习如何捕获图形输入和离开事件以及轴域进入和离开事件,并使用它们来更改图形和轴域的属性,并使轴域上的线形图可见/不可见。
import matplotlib.pyplot as plt
import numpy as np
#定义图形ax1和ax2,并设置图形标题:
fig = plt.figure()
fig.suptitle('mouse hover over figure or axes to trigger events')
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
#准备用于绘制正弦和余弦函数的数据:
x = np.arange(1, 2.0, 0.1) 
y = np.sin(2 * np.pi * x)
y1 = np.cos(2 * np.pi * x)
#在ax1上绘制正弦函数,在ax2上绘制余弦函数:
ax1.plot(x,y, color='g')
ax2.plot(x, y1, color='b')
#为figure_enter_event定义回调函数:
def figure_enter(event):
    print('figure_enter', event.canvas.figure)
    event.canvas.figure.patch.set_facecolor('grey')
    event.canvas.draw()
#为figure_leave_event定义回调函数:
def figure_exit(event):
    print('figure_exit', event.canvas.figure)
    event.canvas.figure.patch.set_facecolor('red')
    event.canvas.draw()
#为axes_enter_event定义回调函数:
def axes_enter(event):
    print('axes_enter', event.inaxes)
    event.inaxes.patch.set_facecolor('white')
    event.inaxes.get_lines()[0].set_visible(True)
    event.canvas.draw()
#为axes_leave_event定义回调函数:
def axes_exit(event):
    print('axes_exit', event.inaxes)
    event.inaxes.patch.set_facecolor('orange')
    event.inaxes.get_lines()[0].set_visible(False)
    event.canvas.draw()
#将事件与对应的回调函数连接:
fig.canvas.mpl_connect('figure_enter_event', figure_enter)
fig.canvas.mpl_connect('figure_leave_event', figure_exit)
fig.canvas.mpl_connect('axes_enter_event', axes_enter)
fig.canvas.mpl_connect('axes_leave_event', axes_exit)

自定义同步更新事件

+
import numpy as np
np.random.seed(19681211)
plt.switch_backend('Qt5Agg')
#定义函数,将摄氏温度转换为和其他三个测量单位:
def c2f(temp):
    return (9. / 5.) * temp + 32
def c2k(temp):
    return temp + 273.15
def c2r(temp):
    return (9. / 5.) * temp + 427.9
#根据主轴域上的摄氏刻度的当前限制来定义更新所有刻度的函数:
def refresh_scales(ax_c):
    y1, y2 = ax_c.get_ylim()
    ax_f.set_ylim(c2f(y1), c2f(y2))
    ax_f.figure.canvas.draw()
    ax_k.set_ylim(c2k(y1), c2k(y2))
    ax_k.figure.canvas.draw()
    ax_r.set_ylim(c2r(y1), c2r(y2))
    ax_r.figure.canvas.draw()
#定义图形,主轴域和三个从属轴域,其他三个测量单位各一个:
fig, ax_c = plt.subplots()
ax_f = ax_c.twinx()
ax_r = ax_c.twinx()
ax_k = ax_c.twinx()
#在图的右侧定义两个从属轴域,远离图的默认右轴域:
ax_k.spines["right"].set_position(("axes", 1.15))
ax_r.spines["right"].set_position(("axes", 1.30))
#将ylim_changed事件连接到相应的回调函数:
ax_c.callbacks.connect("ylim_changed", refresh_scales)
#在主轴域上以摄氏度为单位绘制30天的随机温度:
ax_c.plot(np.random.uniform(low=-40., high=40., size=(30,)))
ax_c.set_xlim(0, 30)
#为所有四个比例绘制图形标题和 y 轴标签:
ax_c.set_title('Temperature on Four different Scales')
ax_c.set_ylabel('Celsius', color='g')
ax_f.set_ylabel('Fahrenheit')
ax_k.set_ylabel('Kelvin')
ax_r.set_ylabel('Rankine')
#为所有轴域设置 y 轴标签的颜色:
ax_f.yaxis.label.set_color('b')
ax_k.yaxis.label.set_color('r')
ax_r.yaxis.label.set_color('m')
#设置的颜色,所有 y 轴的刻度和刻度标签:
ax_c.tick_params(axis='y', colors='g')
ax_f.tick_params(axis='y', colors='b')
ax_k.tick_params(axis='y', colors='r')
ax_r.tick_params(axis='y', colors='m')
#设置所有 y 轴轴线的颜色:
ax_c.spines["left"].set_edgecolor('g')
ax_f.spines["right"].set_edgecolor('b')
ax_k.spines["right"].set_edgecolor('r')
ax_r.spines["right"].set_edgecolor('m')
#在屏幕上显示该图:
plt.show()

func动画-sigmoid

+
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.switch_backend('Qt5Agg')
from matplotlib.animation import FuncAnimation
import os
ffmpegpath = os.path.abspath("D://ffmpeg/ffmpeg-2021-02-02/bin/ffmpeg.exe")
mpl.rcParams["animation.ffmpeg_path"] = ffmpegpath
#定义图形和轴域:
fig, ax = plt.subplots()
#准备要绘制的图形的数据,在这种情况下为 Sigmoid,然后进行绘制:
x = np.arange(-10, 10, 0.01)
y = 1 / (1 + np.exp(-x))
line, = ax.plot(x, y)
#定义初始化函数init():
def init(): 
    line.set_ydata([np.nan] * len(x))
    return line,
#定义动画函数animate():
def animate(i):
    line.set_ydata(1 / (1 + np.exp(-(x+i/100)))) # keep refreshing frame by frame
    return line,
#激活动画:
ani = FuncAnimation(fig, animate, 1000, init_func=init, blit=True, 
                    interval=2, save_count=50, 
                    repeat=False, repeat_delay=1000)
#将输出发送到指定的后端:
from matplotlib.animation import FFMpegWriter
writer = FFMpegWriter(fps=25, metadata=dict(title='expdecay',artist='line'), 
                      bitrate=1800)
ani.save("sigmoid.mp4", writer=writer)

func动画-指数衰减

+
#定义图形和轴域:
fig, ax = plt.subplots()
#绘制空白直线:
xdata, ydata = [], []
line, = ax.plot(xdata, ydata)
#将限制和网格设置为True:
ax.set_xlim(0, 10)
ax.set_ylim(-3.0, 3.0)
ax.grid()
#定义生成数据的函数,该函数将代替和帧数使用:
def frame_gen(x=0):
    while x < 50:
        x += 0.1
        yield x, np.tan(2*np.pi*x) * np.exp(-x/5.)
#定义用于引导动画的函数:
def animate(data):
    x, y = data
    xdata.append(x)
    ydata.append(y)
    xmin, xmax = ax.get_xlim()
    if x >= xmax:
         ax.set_xlim(xmin, 2*xmax)
         ax.figure.canvas.draw()
    line.set_data(xdata, ydata)
    return line,
#激活动画:
ani = FuncAnimation(fig, animate, frame_gen, blit=True, interval=2, repeat=False)
writer = FFMpegWriter(fps=25, metadata=dict(title='expdecay',artist='line'), 
                      bitrate=1800)
ani.save("指数衰减.mp4", writer=writer)

artist动画

+
import pandas as pd
from matplotlib.animation import ArtistAnimation
fig = plt.figure(figsize=(10,8))
import random
y=[sorted([random.random() for j in range(10)]) for i in range(8) ]
#绘制所有折线图:
plt.plot([0, 1], [0, 1], 'k--')
l1= plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[0], label='LogReg',color='purple', animated=True)
l2 = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[1],label='KNN',color='green', animated=True)
l3= plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[2], label='DecisionTree', color='orange', animated=True)
l4 = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[3], label='Random Forest',color='yellow', animated=True)
l5= plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[4], label='MLP',color='red', animated=True)
l6= plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[5], label='SVC',color='violet', animated=True)
l7= plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[6], label='GNB',color='grey', animated=True)
l8= plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[7], label='SGD', color='pink', animated=True)
plt.xlabel('False Positive Rate', size=15, color='m')
plt.ylabel('True Positive Rate', size=15, color='m')
plt.title('ROC curve', size=25, color='b')
plt.legend(loc='lower right', fancybox=True, shadow=True)
lines = [l1 ,l2, l3 ,l4, l5, l6, l7, l8]
ani = ArtistAnimation(fig,lines,blit=True, interval=1000, repeat=True, repeat_delay=2500)
plt.show()
from matplotlib.animation import FFMpegWriter
writer = FFMpegWriter()
ani.save("line.mp4", writer=writer)

artist动画-图片

+
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.pyplot import imshow, imread
plt.switch_backend('Qt5Agg')
from matplotlib.animation import ArtistAnimation
import os
ffmpegpath = os.path.abspath("D://ffmpeg/ffmpeg-2021-02-02/bin/ffmpeg.exe")
mpl.rcParams["animation.ffmpeg_path"] = ffmpegpath
#定义图形和轴域:
fig = plt.figure(figsize=(5,5), dpi=50)
ax = fig.add_axes([0, 0, 1, 1], frameon=False)
#阅读和所需的图像,并创建所有这些图像的列表:
images = []
image1 = imshow(imread('./data/iu.jpg'), animated=True)
images.append([image1])
image2 = imshow(imread('./data/iu2.jpg'), animated=True)
images.append([image2])
image3 = imshow(imread("./data/iu3.jpg"), animated=True)
images.append([image3])
image4 = imshow(imread("./data/iu4.jpg"), animated=True)
images.append([image4])
#激活动画:
ani = ArtistAnimation(fig, images, interval=1000, blit=False, repeat=True, repeat_delay=2500)
#将输出发送到指定的后端:
plt.show()
from matplotlib.animation import FFMpegWriter
writer = FFMpegWriter()
ani.save("iu.mp4", writer=writer)

小部件-button

-
#按键
#单击按键可启用某些功能。 通常,它们用于通过prev和next按键来回滚动数据。 我们将学习如何使用此功能。
#使用prev和next方法定义类以表示要显示的群集:
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.widgets import Button
from sklearn import datasets
plt.switch_backend('Qt5Agg')
#使用prev和next方法定义类以表示要显示的群集:
class Cluster(object):
   ind = 0    # index to move back and forth as we click prev and   next buttons
## Method for next button click
   def next(self, event):
       self.ind += 1
       i = self.ind % len(species)
       index = target == species[i]
       axs.clear()
       axs.scatter(x[index], y[index], s=50, marker='o')
       axs.set_title(species[i], size=25, color='r')
       plt.draw()
## Method for prev button click
   def prev(self, event):
       self.ind -= 1
       i = self.ind % len(species)
       index = target == species[i]
       axs.clear()
       axs.scatter(x[index], y[index], s=50, marker='o')
       axs.set_title(species[i], size=25, color='r')
       plt.draw()
#实例化cluster对象:
cluster = Cluster()
#读取和Iris数据,并设置属性,以绘制三个群集:
from sklearn import datasets
iris= datasets.load_iris()['data']
target= datasets.load_iris()['target']
species = [0, 1, 2]
x,y = iris[:,2], iris[:,3]
index = target == species[cluster.ind]
#定义图形和轴域:
fig, axs = plt.subplots()
#绘制第一个群集:
axs.scatter(x[index], y[index], s=50, marker='o')
axs.set_title(species[cluster.ind], size=25, color='r')
#定义上一个和下一个按键的轴域:
axprev = plt.axes([0.7, 0.005, 0.1, 0.05])
axnext = plt.axes([0.81, 0.005, 0.1, 0.05])
#实例化上一个和下一个按键:
bnext = Button(axnext, 'Next')
bprev = Button(axprev, 'Previous')
#将的回调函数映射到prev和next的on_clicked事件:
bnext.on_clicked(cluster.next)
bprev.on_clicked(cluster.prev)
#在指定的后端显示图形:
plt.show()



小部件-复选框

-
from matplotlib.widgets import CheckButtons
#复选按键
#复选框用于选择或取消选择一组属性以可视化数据。 在本秘籍中,我们将学习如何使用,CheckButtons小部件来实现复选框功能。
fig = plt.figure(figsize=(10,8))
import random
y=[sorted([random.random() for j in range(10)]) for i in range(8) ]
#绘制所有折线图:
plt.plot([0, 1], [0, 1], 'k--')
l1, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[0], label='LogReg',color='purple')
l2, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[1],label='KNN',color='green')
l3, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[2], label='DecisionTree', color='orange')
l4, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[3], label='Random Forest',color='yellow')
l5, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[4], label='MLP',color='red')
l6, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[5], label='SVC',color='violet')
l7, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[6], label='GNB',color='grey')
l8, = plt.plot([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],y[7], label='SGD', color='pink')
#设置图形的属性,并在和左侧调整空间,以容纳和复选框:
plt.xlabel('False Positive Rate', size=20, color='m')
plt.ylabel('True Positive Rate', size=20, color='m')
plt.title('ROC curve', size=25, color='b')
plt.subplots_adjust(left=0.35)
#准备CheckButtons所需的每条曲线的数据轴域,标签和可见性状态:
lines = [l1, l2, l3, l4, l5, l6, l7, l8]
cax = plt.axes([0.05, 0.27, 0.15, 0.5])
labels = [str(line.get_label()) for line in lines]
visibility = [line.get_visible() for line in lines]
#使用先前准备的必需属性实例化CheckButtons对象。
check = CheckButtons(cax, labels, visibility)
#定义响应复选框点击的回调函数:
def onclick(label):
    index = labels.index(label)
    lines[index].set_visible(not lines[index].get_visible())
    plt.draw()
#将事件映射到对象上的回调函数。
check.on_clicked(onclick)#将点击事件与对应的回调函数连接起来。
plt.show()#将输出发送到指定的后端。


小部件-单选框

-
#单选按键
#RadioButtons与CheckButtons相似,只是在任何时候它的一个属性都将处于活动状态。 在本秘籍中,我们将学习如何使用RadioButtons小部件。
#我们将为该秘籍定义美国,中国的 GDP 数据以及和英国的 Python 列表,并将其用于此秘籍。
#导入所需的库:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RadioButtons
#定义图形和轴域,然后在左侧的上调整空间以容纳RadioButtons:
fig, axs = plt.subplots()
plt.subplots_adjust(left=0.3)
#准备要在轴域上绘制的数据:
## Data taken from https://data.worldbank.org/country
Year = ['2007', '2008', '2009', '2010', '2011', '2012', '2013', 
        '2014', '2015', '2016']
China_GDP = [3.552, 4.598, 5.11, 6.101, 7.573, 8.561, 9.607, 10.482, 
             11.065, 11.191]
US_GDP = [14.478, 14.719, 14.419, 14.964, 15.518, 16.155, 16.692, 
          17.428, 18.121, 18.624]
UK_GDP = [3.074, 2.891, 2.383, 2.441, 2.62, 2.662, 2.74, 3.023, 
          2.886, 2.651]
#绘制图形并设置标签,标题和轴限制:
line, = axs.plot(Year, US_GDP, lw=5, color='g', ls='-.')
axs.set_ylim(1,20)
axs.set_title('GDP(in trillion $)')
axs.set_xlabel('Year')
#定义将绘制单选按键的轴域,并实例化对象:
rax = plt.axes([0.05, 0.5, 0.15, 0.25], facecolor='skyblue')
radio = RadioButtons(rax, ('USA', 'China', 'UK'))
#定义单击RadioButtons之一时执行的回调函数:
countrydict = {'USA': [US_GDP, 'g', '-.'], 'China': [China_GDP, 'b', 
               '--'], 'UK': [UK_GDP, 'm', '-']}
def country(label):
    ydata, color, ls = countrydict[label]
    line.set_ydata(ydata)
    line.set_color(color)
    line.set_linestyle(ls)
    plt.draw()
#将点击事件连接到先前定义的对应的回调函数:
radio.on_clicked(country)
#将输出发送到指定的后端:
plt.show()



小部件-文本框

-
#文本框
#TextBox小部件是求值任何表达式的自由格式实现。 如果您想检查各种不同的数学表达式/函数,这将非常方便。
from matplotlib.widgets import TextBox
#定义图形和轴域,并在底部调整空间以适应TextBox:
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.2)
#准备要绘制的初始数据:
x = np.arange(-5.0, 5.0, 0.01)
y = x ** 5
#绘制数据:
l, = plt.plot(x, y, lw=2)
#定义提交TextBox中的新表达式时要执行的回调函数:
def submit(text):
    ydata = eval(text)
    l.set_ydata(ydata)
    ax.set_ylim(np.min(ydata), np.max(ydata))
    plt.draw()
#定义TextBox实现所需的轴域和initial_text:
axbox = plt.axes([0.1, 0.05, 0.8, 0.075])
initial_text = "x ** 5"
#实例化TextBox对象:
text_box = TextBox(axbox, 'Evaluate', initial=initial_text)
#将提交事件与先前定义的对应的回调函数连接:
text_box.on_submit(submit)
#将输出发送到指定的后端:
plt.show()



1.19 在图形用户界面中嵌入绘图

2 mplot3d绘制3d图形

3 axisartist工具包

4 axes_grid1工具包

5 Cartopy绘制包绘制地理图形

Cartopy

6 Seaborn工具包的探索性分析

Seaborn

7 参考文献