matplotlib 常用图形绘制与官方文档 |
- matplotlib.org
- Python库matplotlib 图形绘制
- 官方教程目录
- matplotlib.pyplot
- matplotlib.pyplot.plot
- matplotlib.axes
- matplotlib.use(‘agg’)的作用
- 一文彻底搞懂numpy的结构化数组
- python matplotlib中axes与axis的区别
- matplotlib.pyplot.figure
- mathematical expressions
- Text in Matplotlib Plots
- 【Markdown】markdown 输入数学符号
- matplotlib.pyplot.axis
- 误差线
- matplotlib可视化番外篇bar()–带误差棒的柱状图
- 箱形图box plot 和 小提琴图violin plot
- 箱形图和小提琴图
- 可视化之为什么要使用箱线图?
- 核密度分析(KDE)原理总结
- 修改坐标轴位置
- 【Matplotlib】 移动spines
- The mplot3d Toolkit
- 热力图官方文档
1. 使用指南
1.1 写在前面的话
参考资料2中介绍了使用Pyplot
的一些基本绘图,但是对整体知识结构没有系统的介绍。本文基于参考2,对官网中用法指导以及Pyplot
教程进行详细介绍(尽可能)。为了避免篇幅过长,省略了很多图,在官网都能详细查看到。关于版本,每个版本都有些许差别,尽量安装最新版本,所有方法都是通用的。
1.2 画布组件
画布一般理解为Figure,但实际上是canvas,而Figure是一个更广泛的概念,不用纠结。每次绘图都会创建一张画布,画布上添加各种元素(标题、点线、轴等),或者多个子图。
创建画布:
from matplotlib.pyplot as plt
fig = plt.figure() # 创建一张空的画布,返回画布实例
ax=plt.subplot() # 创建只有一个子图的画布,返回一个Axes的子类
fig, ax = plt.subplots() # 单个子图的画布,返回当前画布和子图
fig, axs = plt.subplots(2, 2) # 多个子图的画布
1.3 Axes 和 Axis
Axes可以理解为画布上的一个小小的数据空间,即小子图的空间,可以是2D或者3D,每个Axes
对象只能存在一张画布上,画布上可以有多个这样的数据空间。注意区分 Axes 和 Axis
前者表示一个数据空间,里面可以包含很多数据属性或者说数据限制,需要被设定比如axes.Axes.set_xlim()
;返回的一个个数据空间即axes.Axes
实例
而后者仅仅代表数据轴,负责刻度即轴上的标记,以及刻度标签即标记刻度的字符串。
1.4 输入数据
绘图所接收的数据最好是 numpy.array
类型的,也可以是列表,列表比较少用。但是不能是 pandas.DataFrame
类型或者numpy.matrix
1.5 面向对象的接口和Pyplot接口
创建画布和数据空间的这种方式称为面向对象OO模式(object-oriented (OO) style)。而另一种就是依赖pyplot功能自动对画布和数据空间进行管理 。
在绘制多子图的时候,使用OO模式比较方便管理,避免混淆,这也是本文的目的之一。
1.6 pylab
官网提到了一种旧方法: from pylab import *
这种方法就相当于将 pyplot
和numpy
中的所有东西都导入了,有点类似MATLAB使用模式。但是这种方法已经不推荐使用了,可能在比较古老的代码中还能看到它的存在。
1.7 封装自己的绘制功能
def my_plotter(ax, data1, data2, param_dict):
"""
A helper function to make a graph
Parameters
----------
ax : Axes
The axes to draw to
data1 : array
The x data
data2 : array
The y data
param_dict : dict
Dictionary of kwargs to pass to ax.plot
Returns
-------
out : list
list of artists added
"""
out = ax.plot(data1, data2, **param_dict)
return out
fig, (ax1, ax2) = plt.subplots(1, 2) # 或者可以返回一个子空间列表,用下标的方式进行传递
my_plotter(ax1, data1, data2, {'marker': 'x'})
my_plotter(ax2, data3, data4, {'marker': 'o'})
这种方式在比较简单的图形中就显得有点得不偿失了,但是如果图形比较复杂或者习惯使用了也比较方便。
1.8 后端与交互模式
占坑
2. Pyplot教程
matplotlib.pyplot
集成了各种功能,如创建画布、子空间、数据控制等。但是pyplot
API并没有OO模式灵活。
完整的 pyplot
文档见:官方文档matplotlib.pyplot
2.1 简单的plot - 列表元素
在绘制直线或者折线时,只传入y也是可以的:plt.plot([1, 2, 5, 4])
,这样会自动生成x从0开始,python默认从下标0开始。
当然也支持x和y同时传入,自动按坐标点绘出每一条线段,在这种实例中,传入的是最简单的列表,系统自动获取最值。
import matplotlib.pyplot as plt
plt.plot([1, 2, 5, 4], [1, 4, 9, 16])
plt.show()
2.2 自定义样式
对于每个坐标点,还可以通过第三个超参数选项设置格式字符串指定颜色和绘制的样式(点、虚实线等)。格式字符串和MATLAB的用法一致,并且可以将颜色字符串和样式字符串进行组合。默认的格式字符串为:b-
,b
表示blue,-
表示实线线段
也可以分开指定超参数:
color=
,颜色,[‘b’, ‘g’, ‘r’, ‘c’, ‘m’, ‘y’,‘k’, ‘w’],或者16进制颜色编号marker=
指定坐标点的样式,用圆点、方格、还是× 等等。对应markersize=
指定大小。linestyle=
指定相邻两个坐标点之间的连线样式,对应linewidth=
指定连线宽度。alpha=
可以指定整体透明度,数值[0,1],1表示不透明。label=
指定线条标签,组合使用.legend()
方法显示标签,
完整的格式样式表见: 官方文档
2.3 plot 同时绘制多条线 - numpy元素
plot
还支持同时绘制多条线: plot([x], y, [fmt], [x2], y2, [fmt2], …, **kwargs)
因为列表不便于做数值分析,而实际中numpy格式使用比较多,并且内部都是将序列转化为了numpy。
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0., 5., 0.2) # 等间距采样
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^') # red dashes, blue squares and green triangles
plt.show()
2.4 多图与多子图
MATLAB
和 pyplot
都有当前坐标系的概念,所有的绘制都是实施在当前坐标系上。
使用.gca()
返回当前坐标系,即一个子空间matplotlib.axes.Axes
实例。
使用.gcf()
返回当前画布,即matplotlib.figure.Figure
实例。
使用.clf()
清空当前画布
使用.cla()
清空当前坐标系
2.4.1 多子图
这里使用的是pyplot
接口的多子图。
在大多数实际应用中,一般只需要一张画布即可完成需要的可视化。在这种情况下,可以不用手动创建画布:plt.figure()
,但是如果需要指定画布属性(见2.4.2),还是有必要的。
如果需要多子图,使用plt.subplot()
指定当前坐标系即可,比如:plt.subplot(211)
,表明numrows 2行,numcols一列,共2×1个子图,指定第一张子图,这种方法和 plt.subplot(2,1,1)
功能是一样的,一般 numrows × numcols<10 使用这种面向接口的方法。
2.4.2 多图
即多画布,每个画布可以独立完成各种工作。
来看plt.figure()
常用参数:
num
,整数类型,可选,默认为1。指定第几张画布,注意按依次递增顺序调用figsize
,元组类型,可选,默认(6.4, 4.8)dpi
,没英寸像素点数量,分辨率。默认100.0,越大清晰度越高facecolor
,画布的颜色,默认为白色edgecolor
,画布边缘的颜色,默认为白色,实际显示的只是坐标系的范围
import matplotlib.pyplot as plt
plt.figure(1) # the first figure
plt.subplot(211) # the first subplot in the first figure
plt.plot([1, 2, 3])
plt.subplot(212) # the second subplot in the first figure
plt.plot([4, 5, 6])
plt.figure(2) # a second figure
plt.plot([4, 5, 6]) # creates a subplot(111) by default
plt.figure(1) # figure 1 current; subplot(212) still current
plt.subplot(211) # make subplot(211) in figure1 current
plt.title('Easy as 1, 2, 3') # subplot 211 title
在关闭画布图的时候,使用.close()
才能完全释放内存,使用windos管理窗口并不会杀死pyplot的内部引用。
2.4.3 关于 .subplot()
和 .subplots()
两种方法都是创建多子图。
.subplot()
,Add a subplot to the current figure。即在当前画布下添加一个子图,如果子图存在则切换到当前子图下,传入三个int型参数,默认111,返回一个Axes的子类。subplots()
,Create a figure and a set of subplots。返回一个当前画布实例和一个子图数组(ndarray类型)。传入两个int型参数,nrows 和 ncols。这种方法就比较倾向于当 nrows × ncols ≥ 10的时候,面向每个实例对象,单独绘制。
2.5 文本
文本可以通过指定任意位置进行添加,实际上xlabel
和ylabel
以及标题title
等都是文本,所以以下方法是通用的。
另外,.text
是在子空间或者说子图上任意位置添加的 ,.figtext
则是在画布上任意位置添加文本。给画布添加标题的方法:.suptitle
字符串还支持数学表达式,Matplotlib 集成了大量的数学表达式符号,和普通的markdown语法类似
$\mu=100,\ \sigma=15$
:
μ
=
100
,
σ
=
15
\mu=100,\ \sigma=15
μ=100, σ=15
$h_{data}(x)$
:
h
d
a
t
a
(
x
)
h_{data}(x)
hdata(x)
plt.text(x, y, 'this is a text')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
上述这种表达,返回的是matplotlib.text.Text
的实例,这种实例都支持:Axes.set_title, Axes.set_xlabel, Axes.text 的方式添加文本
同样,可以通过超参数设置文本样式:
style
orfontstyle
,字体,[ ‘normal’ | ‘italic’ | ‘oblique’ ]alpha
,透明度,[0,1],1表示不透明color
、backgroundcolor
,字体颜色和文本框的背景颜色label
,文本框的标签,可以通过.legend
显示rotation
, [ angle in degrees | ‘vertical’ | ‘horizontal’ ]size
orfontsize
,文本大小weight
orfontweight
,加重,[ ‘normal’ | ‘bold’ | ‘heavy’ | ‘light’ | ‘ultrabold’ | ‘ultralight’]
完整样式见:官方文档
2.6 坐标轴
2.6.1 对数轴刻度
一般所使用的轴刻度都是线性的,而有的数据跨越了多个数量级,这个时候使用对数轴刻度就比较方便了。
有四种刻度方式:
linear
,线性轴刻度,默认log
,对数轴刻度symlog
,symlog类似于log,支持负值,允许定义一个接近零的值范围,在该范围内绘图是线性的,以避免使绘图趋于零附近的无穷大logit
,分类评定模型
以上四种方式可以通过:plt.xscale('log')
或者 plt.yscale('log')
改变对应轴的刻度规模
2.6.2 自定义坐标轴刻度及标签
.xticks()
:matplotlib.pyplot.xticks(ticks=None, labels=None, **kwargs)
,获取或者设置x轴刻度标签。一般用来设置,ticks=
指定原来的刻度位置,labels=
设置显示的标签,返回的也是这两个属性。还可以用rotation=
指定标签的旋转角度.yticks
,同上,指定y轴的刻度标签。
2.6.3 限制轴刻度显示范围
.xlim()
,plt.xlim(left=, right=)
,设置或者获取x轴数值显示范围.ylim()
,同上,plt.yim(bottom=, top=)
,或者plt.ylim(ymin=, ymax=)
,这四个参数不能同时传递,否则报错。
2.6.4 坐标轴关闭与打开
axis('off')
,默认为’on’打开坐标轴,如果关闭,则上图线框与数字将消失。还可以设置成’equal’,强行将x轴与y轴的刻度范围变成一致,默认变大。如果单纯调用这个.axis()
返回坐标系范围,即四个最值。.box
,matplotlib.pyplot.box(on=)
,可以设置为bool型或者None,默认为None,如果设为False,则上图线框关闭,数字刻度还在.minorticks_on()
,将刻度打开,默认关闭。即原本坐标刻度间的小刻度是默认关闭的,.minorticks_off()
,对应上述方法
2.7 其他常用操作
2.7.1 画直线
.axline
: 给定两个点的坐标,画一条直线,两个点坐标要用元组形式给出.axhline
:matplotlib.pyplot.axhline(y=0, xmin=0, xmax=1, **kwargs)
指定y轴刻度,以及x轴的比例范围,画一条水平线 。
与之类似还有一种方法:matplotlib.pyplot.hlines(y, xmin, xmax, colors=None, linestyles='solid', label='', *, **kwargs)
,y也可以是一个列表,同时画多条水平线.axvline
,与.axhline
同理,画一条竖直线,同样指定的是y轴的比例范围。
而matplotlib.pyplot.vlines(x, ymin, ymax, colors=None, linestyles='solid', label='', *, **kwargs)
也同理,x传入一个列表,画多条竖线,样式一致
2.7.2 画矩形框
.axhspan(ymin=,ymax=)
.axvspan(xmin=,xmax=)
画水平框或者竖直框。分别指定横纵坐标最值即可。对于另外一轴采用比例的方式[0,1],如果不指定则默认整体坐标系。
import matplotlib.pyplot as plt
x=np.linspace(-5,5,100)
y=1/(1+np.exp(-x))
plt.plot(x, y)
plt.axline((-5,0),(5,1),linewidth=1,linestyle='-.',color='r') # 画直线
plt.axhline(0.5,xmin=0.1,xmax=0.9,linestyle='--',color='m') # 画水平线,水平和竖直线指定范围都是用比例的形式
plt.axvline(x=0.0,ymin=0.1,ymax=1,linestyle='--',color='m') # 画竖直线
plt.axhspan(ymin=0.4,ymax=0.6,xmin=0.1,xmax=0.9,alpha=0.2) # 画水平框
plt.axvspan(xmin=-1,xmax=1,alpha=0.2) # 画竖直框
plt.show()
2.7.3 网格操作
pyplot.grid(self, b=None, which='major', axis='both', **kwargs)
配置网格线,里面也有一些参数:
b=
,bool型,是否显示网格线,默认不显示axis=
,{‘both’, ‘x’, ‘y’},默认显示两个轴方向的网格线,'x’表示只显示竖直方向- 其他参数也可以设定,比如宽度、颜色、样式、透明度等
2.7.4 标签显示
.legend(self, *args, **kwargs)[source]
函数方法比较灵活,可以在绘制的时候指定label,然后直接调用即可。
也可以:.legend((line1, line2, line3), ('label1', 'label2', 'label3'))
这样进行指定,line表示所绘制的曲线返回的实例对象。
其他常用参数:
loc=
,如果选择’best’在图形比较复杂的时候需要耗费很多时间进行自动选择最佳位置
title=
,给标签框设置标题,见3.1.3;还可以给标题设置字体样式,标签框的布局可以灵活改变。详见:.legend
2.7.5 全局显示
matplotlib.pyplot.show(block=None)
在子图配置的时候想到一个问题:为什么只有pyplot
封装了.show
方法,而无法使用axs.show()。所以对这个方法简单介绍。
功能:显示所有打开的画布,注意是画布。在非交互模式下,block=
参数默认为False,即阻塞型。
详见: show(self, warn=True)
3. Axes - 面向对象接口
matplotlib.axes.Axes
实例提供了非常丰富的接口,pyplot
方法能实现的功能Axes
同样能实现,只不过接口稍微有点变化,功能甚至比pyplot
还全面。这里根据官网的介绍顺序将常用的功能接口简单介绍一下,在后面会使用这些方法绘制各种图形,加强理解。
3.1 基本绘制
3.1.1 普通线条
常用axs.plot()
进行调用,这个接口和之前介绍了基本无差别,同样支持平面线条绘制,或者同时绘制多条平面线条:plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
。见2.2 自定义样式
3.1.2 散点图
绘制散点图:Axes.scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=<deprecated parameter>, edgecolors=None, *, plotnonfinite=False, data=None, **kwargs)
- x,y 即传入的数据坐标,维度为(n,)。
s=
表示指定size,可以是一个浮点数或者一个一维数组,如果不够指定所有的点,则所有的点依次循环指定散点大小c=
表示指定颜色,=None
表示可选参数,有默认参数。可以是一个一维颜色数组,或者单个颜色编号字符串,或者2维的RGB颜色表,或者从cmp指定的颜色映射。marker=
指定散点样式,默认’o’。散点样式表见 : matplotlib.markersalpha=
,透明度linewidths=
,散点边缘的宽度,可以是一个数组,也可以循环使用edgecolors
,散点边缘的颜色,也可以是一个颜色列表或者{‘face’, ‘none’},face
表示同样颜色,none
表示不画出边界
pyplot
中的散点画法几乎一致。只需了解常用参数即可,需要时可查表。
3.1.3 阶梯图
.step(x,y)
。阶梯图即两个点之间不是直接的连接,而是通过直角连接。
通过哪种直角取决于一个参数:where=
,默认pre
,表示先y轴方向再x轴方向,post
表示先x轴方向再y轴方向;mid
表示x方向走一半再走y方向再走x方向。
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(14)
y = np.sin(x / 2)
ax=plt.subplot()
# fig,ax=plt.subplots() # 和上一行定义类似
ax.step(x, y + 2, label='pre (default)') # 默认'pre'
ax.plot(x, y + 2, 'o--', color='grey', alpha=0.3)
ax.step(x, y + 1, where='mid', label='mid')
ax.plot(x, y + 1, 'o--', color='grey', alpha=0.3)
ax.step(x, y, where='post', label='post')
ax.plot(x, y, 'o--', color='grey', alpha=0.3)
ax.grid(axis='x', color='0.95') # 只显示x方向
ax.legend(title='Parameter where:')
ax.set_title('plt.step(where=...)')
plt.show()
3.1.4 区域填充
Axes.fill_between(self, x, y1, y2=0, where=None, interpolate=False, step=None, *, data=None, **kwargs)
对指定范围进行填充,注意y1和y2大小无关,只注意竖直方向的一个范围。
- x 表示横坐标范围,(n, ),y1和y2表示填充区域,
where=
,这个参数是一个判断型参数,可以对x范围进行选择,比如where=(y1>y2)
,那么就指定了填充宽度interpolate=
这个参数表示插值,即完全将两条曲线之间的范围填充,默认只填充指定的x区域- 其他参数也可以设置颜色、透明度等等
import matplotlib.pyplot as plt
x = np.array([0, 1, 2, 3])
y1 = np.array([0.8, 0.8, 0.2, 0.2])
y2 = np.array([0, 0, 1, 1])
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.set_title('interpolation=False')
ax1.plot(x, y1, 'o--')
ax1.plot(x, y2, 'o--')
ax1.fill_between(x, y1, y2, where=(y1 > y2), color='C0', alpha=0.3)
ax1.fill_between(x, y1, y2, where=(y1 < y2), color='C1', alpha=0.3)
ax2.set_title('interpolation=True')
ax2.plot(x, y1, 'o--')
ax2.plot(x, y2, 'o--')
ax2.fill_between(x, y1, y2, where=(y1 > y2), color='C0', alpha=0.3,
interpolate=True)
ax2.fill_between(x, y1, y2, where=(y1 <= y2), color='C1', alpha=0.3,
interpolate=True)
plt.show()
还有一种填充和上面类似,即横向填充:Axes.fill_betweenx(self, y, x1, x2=0, where=None, step=None, interpolate=False, *, data=None, **kwargs)
,这个时候指定的是x1和x2,其余几乎无异。
3.1.5 条形图 - 柱状图
这里不区分条形图或者柱状图,两种说法均可。这种类型的图经常用来做数据分析,趋势、对比等。
Axes.bar(self, x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
- x为指定的横坐标,也可以是一维的字符串列表,比如[‘2010’, ‘2015’, ‘2020’]
height
,对应位置的高度,和x维度一样,需要对应width=
,柱型的宽度,默认0.8bottom=
,柱状图可以叠加,默认为0。即指定所基于的heightxerr=
、yerr=
,提到柱状图就不得不了解一下误差棒或者误差线,即在柱型顶端工字型线,这种线衡量了一个误差范围,一般用标准差,也反映了每个数据标志的不确定程度。xerr
是横向误差,另一个是纵向误差。接收2维及以内的数据,如果是标量数据,则所有的±差异一致,如果是一维的(n, ),则指定每个柱形的±差异,如果是二维的(2,n),则第一行是负向差异,第二行是正向差异。
labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 35, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]
men_std = [[2, 3, 4, 1, 2],[1,1,1,1,1]] # 分开指定±误差
women_std = [3, 5, 2, 3, 3]
width = 0.35 # the width of the bars: can also be len(x) sequence
fig, ax = plt.subplots()
ax.bar(labels, men_means, width, yerr=men_std, label='Men',ecolor='m') # bottom默认为0,ecolor指定误差棒的颜色
ax.bar(labels, women_means, width, bottom=men_means, yerr=women_std, label='Women',ecolor='m')
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.legend()
plt.show()
当然也可以不采用叠加的方式绘制柱形图。指定x-width与 x+width即可,然后重新设置x刻度和标签。
3.1.6 饼状图
饼状图能直观反映比例情况,其原理是每一部分的值除以总的值即其占比
Axes.pie(self, x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=0, 0, frame=False, rotatelabels=False, *, normalize=None, data=None)
- x即所给出的各个部分的值,一维
explode=
,指定每个部分的偏移,即离开整体,间距大小,取[0,1]即可。同样需要是一维的长度和x一致,可选。labels=
,每个部分的标签,自动显示autopct=
,指定小数点精度,是个格式字符串,比如:autopct='%1.2f%%'
startangle=
,从哪个角度开始,x轴正方向为0度角。
3.2 线条和区域
这块内容和2.7.2几乎一致,简单介绍一下:
Axes.axhline(self, y=0, xmin=0, xmax=1, **kwargs)
,画水平线,指定y轴刻度和x轴比例范围[0,1],线条样式可自定义Axes.axvline(self, x=0, ymin=0, ymax=1, **kwargs)
,画垂直线,指定x轴刻度和y轴比例范围[0,1],线条样式可自定义Axes.axline(self, xy1, xy2=None, *, slope=None, **kwargs)
,画直线,用元组传入两个点的坐标Axes.axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs)
,画水平矩形,指定y轴数值范围,和x轴比例范围[0,1],样式可自定义如颜色、透明度等Axes.axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs)
,画竖直矩形,指定x轴数值范围,和y轴比例范围[0,1],样式可自定义。
详见官方文档:spans
3.3 统计图
3.3.1 箱型图
3.3.2 小提琴图
3.3.3 直方图
直方图是数值数据分布的精确图形表示。这是一个连续变量(定量变量)的概率分布的估计。
Axes.hist(self, x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, *, data=None, **kwargs)
返回一个三元组(n, bins, patches) 或者 ([n0,n1, …], bins, [patches0, patches1, …])。
- x是一维数组或者多维数组,长度可以不同。
bins=
,整数或者序列或者字符串类型,默认为10。将小直方条进行组合显示range=
,指定直方图数据的上下界,元组类型,默认最值。如果bin是一个序列,那么此处失效。density=
,是否将直方图频数转换为频率,默认False。
np.random.seed(19680801)
# example data
mu = 100 # mean of distribution
sigma = 15 # standard deviation of distribution
x = mu + sigma * np.random.randn(437)
num_bins = 50
fig, ax = plt.subplots()
n, bins, patches = ax.hist(x, num_bins, density=True) # the histogram of the data
# add a 'best fit' line
y = ((1 / (np.sqrt(2 * np.pi) * sigma)) *
np.exp(-0.5 * (1 / sigma * (bins - mu))**2)) # 高斯核概率密度估计
ax.plot(bins, y, '--')
ax.set_xlabel('Smarts')
ax.set_ylabel('Probability density')
ax.set_title(r'Histogram of IQ: $\mu=100$, $\sigma=15$')
plt.show()
3.3.4 等高线 - 轮廓曲线
等高线也有两种,如果没有进行颜色填充,那就叫轮廓线:Axes.contour(self, *args, data=None, **kwargs)
。
有填充的用:Axes.contourf(self, *args, data=None, **kwargs)
。两个版本相差不大,返回值相同。
调用方法:.contour([X, Y,] Z, [levels], **kwargs)
。等高线描绘的是三维曲面的情况,同一条等高线上的值相同,因此不同的等高线显示出层次关系。
- x和y表示z的索引,要么和z一样是二维的,要么都是一维的,然后可以用
numpy.meshgrid()
生成网格。即在二维平面上若干网格点,对应高度就是z。 levels=
,int型或类似数组,可选参数,确定轮廓线/区域的数量和位置
其他可选参数
alpha=
,透明度cmap=
,字符串或者颜色表Colormap,默认‘viridis’。一个颜色表实例或者注册过的颜色表名字会按指定的levels进行颜色编排。Colormap用于将数据值(浮点数)从间隔转换为相应Colormap表示的RGBA颜色。用于将数据缩放到间隔中看 。如果想显示热力图:cmap=plt.cm.hot
,将color map映射成 hot热力图。Colormap reference
def f(x,y):
return x**2 + y**2 + x*y
delta=0.2
X=np.arange(-2.5,2.5,delta)
Y=np.arange(-2.5,2.5,delta)
X,Y=np.meshgrid(X,Y)
fig,axs=plt.subplots(ncols=2,nrows=2,figsize=(10,8),sharey=True,sharex=True)
cont1=axs[0][0].contour(X,Y,f(X,Y)) # 指定每个axes
plt.colorbar(cont1,ax=axs[0][0]) # 为对应的axes生成色阶,第一个参数传递色阶信息,第二个参数指定axes
cont2=axs[0][1].contourf(X,Y,f(X,Y))
plt.colorbar(cont2,ax=axs[0][1])
cont3=axs[1][0].contour(X,Y,f(X,Y),cmap=plt.cm.hot)
plt.colorbar(cont3,ax=axs[1][0])
cont4=axs[1][1].contourf(X,Y,f(X,Y),levels=15,cmap=plt.cm.hot) # 颜色越深,值越小;levels越大,显示越密集,或者指定列表,显示对应值的等高线
plt.colorbar(cont4,ax=axs[1][1])
plt.show()
3.3.5 稀疏图
绘制二维阵列的稀疏模式 ,将非零值进行可视化,用marker进行标记,这里只针对普通的二维数值数组。
Axes.spy(self, Z, precision=0, marker=None, markersize=None, aspect='equal', origin='upper', **kwargs)
- Z,二维的数值数组
precision=
,浮点数或者’present’,默认为0。即绝对值大于这个精度才显示。- 其他选项可选择标记符号
marker=
,markersize=
,这两个参数指定一个axes颜色就变成蓝色。否则默认黑色
fig, axs = plt.subplots(2, 2)
ax1,ax2,ax3,ax4=axs[0][0],axs[0][1],axs[1][0],axs[1][1]
x = np.random.randn(20, 20)
x[5, :] = 0.
x[:, 12] = 0.
ax1.spy(x, marker='1',markersize=5)
ax2.spy(x, precision=0.1, markersize=5)
ax3.spy(x)
ax4.spy(x, precision=0.1)
plt.show()
3.4 文本
Axes.text(self, x, y, s, fontdict=None, **kwargs)[source]
给当前坐标系下添加文本,指定坐标,以及要添加的文本s,支持格式字符串。也可以设置字体fontstyle =
、颜色color=
、大小fontsize=
、透明度alpha=
、填充backgroundcolor=
、角度rotation=
等。见 2.5
3.5 外观与坐标轴配置
其实在 2.6 已经讲过大部分了。但是面向对象接口稍微有点差别。
3.5.1 外观
Axes.axis(self, *args, emit=True, **kwargs)
,设置或者获取坐标轴属性,获取的是四个值表示坐标范围。设置可直接放入参数 ‘on’、‘off’、'equal’等,分别表示打开(默认)、关闭坐标轴,另一个是将坐标轴拉到相同刻度范围Axes.set_axis_off(self)
,无参数,相当于Axes.axis('off')
,将坐标轴关闭,对应Axes.set_axis_on(self)
- 默认Axes.set_frame_on(self, b)
,将四条线框打开还是关闭(刻度还在),b=True
默认Axes.grid(self, b=None, which='major', ='both', **kwargs)
,默认b=False
,axis=
可选’x’或者’y’表示只显示一个方向,其他参数比如线条样式等都可正常设置。Axes.set_title(self, label, fontdict=None, loc=None, pad=None, *, y=None, **kwargs)
,设置坐标系标题。因为传入的label
是文本,所有很多对文本的参数选项都适用,如大小、字体、透明度、颜色等等,默认居中。Axes.get_title(self)
获取当前标题,其实还有loc=
,返回哪个标题。Axes.legend(self, *args, **kwargs)
,设置标签显示,2.7.4
3.5.2 坐标轴 - 显示
Axes.get_xaxis()
、Axes.get_yaxis()
,获取x轴和y轴实例,可以对轴进一步操作。Axes.set_xlim(self, left=None, right=None, emit=True, auto=False, *, xmin=None, xmax=None)
,设置x轴显示范围并返回左右值,Axes.get_xlim(self)
只返回左右值。Axes.set_ylim(self, bottom=None, top=None, emit=True, auto=False, *, ymin=None, ymax=None)
,同上,设置y轴显示范围并返回上下界。Axes.get_ylim(self)
返回上下界。Axes.set_xlabel(self, xlabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)
,设置x轴标签,注意这个和刻度标签不一样。xlabel
传入文本。Axes.get_xlabel()
获取x轴标签。Axes.set_ylabel(self, ylabel, fontdict=None, labelpad=None, *, loc=None, **kwargs)
,同上,Axes.get_ylabel()
同上。Axes.set_xscale(self, value, **kwargs)
和Axes.set_yscale(self, value, **kwargs)
都是设置刻度规模,value=
{“linear”, “log”, “symlog”, “logit”, …}。2.6.1已经介绍过。
3.5.3 坐标轴 - 刻度
Axes.set_xticks(self, ticks, *, minor=False)
,设置坐标轴刻度,这个和2.6.2有点区别,这里只重新设置x轴显示的刻度,而plt.xticks()
可以同时设置刻度和显示标签。对原来的刻度进行匹配,显示指定的刻度范围。如果主图是根据y的长度确定x,那么x从0开始。Axes.set_xticklabels(self, labels, *, fontdict=None, minor=False, **kwargs)
,上面是指定显示的刻度数字,这里是显示将原本的刻度数字替换成要显示的标签,组合使用。labels
传入要显示的字符串列表,长度要和上面的刻度数量一致。Axes.set_yticks(self, ticks, *, minor=False)
,原理同x轴Axes.set_yticklabels(self, labels, *, fontdict=None, minor=False, **kwargs)
,原理同x轴
4. 3D工具包
前面所有的内容都是基于2D的,如果要绘制三维图形,需要额外设定,生成对应的实例:mpl_toolkits.mplot3d.axes3d.Axes3D
这个类中封装了各种方法,大部分和前面所介绍的都是相同的,常用的案例中,只需额外设定z轴即可。
4.1 生成3D实例
有两种方式生成,但本质是一样的。
- 画布添加子图,此时只返回一个子图实例,每个子图都需要指定
projection=3d
才能生成3D实例
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
- 上述是在画布中添加,还有一种直接生成所有子图并返回画布,这个时候参数稍微有些不同,用字典指定
subplot_kw
参数,其实本质还是通过调用add_subplot
来创建每个子图,并且所有子图都是3D实例
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
4.2 Axes3D实例对象
之前介绍的返回的是 Axes实例对象,并在 3 中介绍了一些常用的接口。这里也设置了一些自己的接口方法,与 2D实例几乎无差别,直接沿用即可。
4.2.1 坐标轴设置
3.5 中已经详细介绍了x轴和y轴的设置,这里方法是通用的,所以只介绍针对z轴的设置:
Axes3D.set_axis_off()
,将坐标轴关闭,包括轴线、刻度、刻度标签等。3.5.1已有介绍,这里将z轴也同样关闭,只留下图形。Axes3D.set_title(self, label, fontdict=None, loc='center', **kwargs)
,设置标题Axes3D.set_zlim(self, bottom=None, top=None, emit=True, auto=False, *, zmin=None, zmax=None)
,设置z轴实际显示出来的范围Axes3D.set_zlabel(self, zlabel, fontdict=None, labelpad=None, **kwargs)
,设置z轴标签Axes3D.set_zticks(self, ticks, *, minor=False)
,设置z轴刻度齿Axes3D.set_zticklabels(self, labels, *, fontdict=None, minor=False, **kwargs)
,设置z轴刻度齿的标签,替换原来的数字Axes3D.text(self, x, y, z, s, zdir=None, **kwargs)
,在指定位置显示文本。
4.2.2 图形绘制接口
接口名称与 Axes毫无差别,但是参数稍微有点变化,在下一节会详细介绍主要的3D图形
4.3 常用的3D图形
注意,先生成3D实例对象,然后通过接口进行调用。
4.3.1 曲线图
.plot(self, xs, ys, *args, zdir='z', **kwargs)
,绘制2D或者2D数据,在直线基础上添加一维参数即可,x和y都是一维形式的数组,而z可以是浮点数也可以是一维数组。
特殊情况是在3D空间绘制2D数据,只能设置z为常数,zdir=
(‘x’, ‘y’ or ‘z’)中的其一,用来指定z轴的方向,数据对应关系也会改变。
ax.plot(x, y, z, label='parametric curve')
ax.legend()
4.3.2 散点图
Axes3D.scatter(self, xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True, *args, **kwargs)
。x和y都是数组形式的,z可以是浮点数也可以是数组形式,默认为0。
4.3.3 线框图与曲面图
这两个图的参数几乎一致,曲面图是更密集的曲线或者线框,每个x,y组成的网格点上都对应一个z值。从图形上来看,有点像是进行过填充的线框。
线框图: Axes3D.plot_wireframe(self, X, Y, Z, *args, **kwargs)
,x、y、z都是2维数据。rcount
和ccount
分别指定行和列的最大采样点,默认50。rstride
和cstride
分别指定了行和列的采样间隔步长。这四个参数只能指定其中一对。
曲面图:Axes3D.plot_surface(self, X, Y, Z, *args, norm=None, vmin=None, vmax=None, lightsource=None, **kwargs)
,既然带颜色,那么也能指定颜色参数 cmap=
。rcount
和ccount
、rstride
和cstride
两对参数和上面一致。x、y、z都是2维数据。可以残毒指定颜色 c=
。
4.3.4 柱形图
Axes3D.bar(self, left, height, zs=0, zdir='z', *args, **kwargs)
,left
指定柱形的左侧x坐标,一维形式。height
也是一维形式,指定了高度。zs
是浮点数或者一维形式,zdir
指定哪个轴做z轴方向。
- Create 2D bar graphs in different planes
在这个例子中,如果设置zdir='z'
,则这些柱面都与底面平行了。