Matplotlib精品学习笔记002-Pyplot详解,
matplotlib.pyplot集合了一系列功能,运行起来和MATLAB相似。
每个pyplot功能都会对画布(figure)进行修改:包括创建画布,在画布上创建一个画图区,向画图区里绘制一些线条,给画图区挂上标签等等。
在matplotlib.pyplot中,调用函数会保存不同的声明,因此pyplot会始终追踪锁定当前画布和当前画图区,绘画函数会直接作用于当前轴区(axes)。这也是隐式接口的特性
==pyplot(隐式)API虽然更简洁,但不如显式API灵活。==有兴趣可以阅读matplotlib显式接口与隐式接口
通过pyplot快速绘图
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
- 知识点: 如果向plot()传入一个列表或数组(array),matplotlib会默认是y数据,并自动生成x数据,也就是x=range(len(array)),x数据从0开始。
定义画图区的样式(plot style)
对于每对x,y参数,都有一个可选参数,它可以通过格式化字符串规定画图区的颜色和线条样式。格式化字符串的字母和符号都来自MATLAB。颜色字符串+线条样式字符串。
- 知识点: 默认格式化是’b-',表示蓝色线条。
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')
# 样式为红色的点
plt.axis([0, 6, 0, 20])
plt.show()
- 知识点: 上方代码块中的plt.axis()函数接受[xmin, xmax, ymin, ymax]这样的列表,能规定轴区(axes)的视野。
如果matplotlib只能读取列表,那可以说是毫无用处
比起列表,更常见的是使用numpy的array。
知识点: matplotlib都会在内部将接收到的数据转换为numpy的array类型。
简单了解一下matplotlib如何使用numpy绘图:
import numpy as np
# 从0-5,每隔0.2取数
t = np.arange(0., 5., 0.2)
# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
利用实参传入键对值字符串绘图
matplotlib允许通过实参data传入numpy.recarray和pandas.DataFrame等对象。之后,你就可以通过字符串获取对应的变量值来绘图。
例如:
data = {'a': np.arange(50),
'c': np.random.randint(0, 50, 50),
'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
plt.scatter('a', 'b', c='c', s='d', data=data)
plt.xlabel('entry a')
plt.ylabel('entry b')
plt.show()
也可以使用分类变量创建一个图表。Matplotlib允许您将分类变量直接传递给许多绘图函数。
names = ['group_a', 'group_b', 'group_c']
values = [1, 10, 100]
plt.figure(figsize=(9, 3))
plt.subplot(131)
plt.bar(names, values)
plt.subplot(132)
plt.scatter(names, values)
plt.subplot(133)
plt.plot(names, values)
plt.suptitle('Categorical Plotting')
plt.show()
自定义线条属性
线条自带许多属性。你可以对线宽、线条样式、平滑等属性设定。设定属性的方法不止一种。
使用关键字参数(keyword argument):
plt.plot(x, y, linewidth=2.0)
使用Line2D实例的属性设置方法。
plot(绘图)将返回一个包含Line2D实例的列表,比如:line1, line2 = plot(x1, y1, x2, y2)。我们就可以针对线条实例进行属性设置。
line, = plt.plot(x, y, '-')
line.set_antialiased(False) # 关闭平滑
通过setp。
下面的例子将展示利用MATLAB风格的函数对若干线条设置多项属性。你既可以使用python的关键字参数,也可以使用MATLAB风格的字符串/值对。
lines = plt.plot(x1, y1, x2, y2)
# 使用关键字参数
plt.setp(lines, color='r', linewidth=2.0)
# MATLAB风格
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)
Line2D实例的属性表
属性名称 | 值类型 |
---|---|
alpha透明度 | 浮点数 |
animated动图 | True or False |
antialiased or aa平滑 | True or False |
clip_box夹框 | matplotlib.transform.Bbox实例 |
clip_on夹框显示 | True or False |
clip_path夹框路径 | Path实例和Transform实例,Patch |
color或c 颜色 | 任意matplotlib可识别的颜色 |
contains | 命中测试函数 |
dash_capstyle虚线顶部样式 | ‘butt’, ‘round’, ‘projecting’ |
dash_joinstyle | ‘miter’, ‘round’, ‘bevel’ |
dashes虚线 | 点是否连续 |
data数据 | (np.array xdata, np.array ydata) |
figure图形 | matplotlib.figure.Figure实例 |
lable标签 | 字符串 |
linestyle或ls线条样式 | [ ‘-’ |
linewidth或lw线条宽度 | 浮点数 |
marker标记 | [ ‘+’ |
markeredgecolor或mec标记边缘颜色 | 任意matplotlib可识别的颜色 |
markeredgewidth或mew标记边缘宽度 | 浮点数 |
markerfacecolor或mfc标记颜色 | 任意matplotlib可识别的颜色 |
markersize或ms标记大小 | 浮点数 |
markevery | [ None |
picker选择 | 用于线条选择交互 |
pickradius选择半径 | 线条选择的半径 |
solid_capstyle | [‘butt’ |
solid_joinstyle | [‘miter’ |
transform变型 | matplotlib.transforms.Transform实例 |
visible可视 | True or False |
xdata横轴数据 | np.array |
ydata竖轴数据 | np.array |
zorderZ轴 | 任意数字 |
要获取已绘制线条的属性,可以通过调用setp函数,以线条为参数:
lines = plt.plot([1, 2, 3])
plt.setp(lines)
操作多个画布和轴区(figures and axes)
MATLAB和pyplot都会定位当前画布和当前轴区。因此所有的绘图函数都会作用于当前轴区。gca函数返回当前轴区,即一个matplotlib.axes.Axes实例;而gcf函数返回当前画布,即一个matplotlib.figure.Figure实例。==通常,你不必担心是否在当前画布和轴区上绘图,因为matplotlib已经在内部完成了这项工作。
譬如:
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure()
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()
plt.figure()可有可无,因为如果没有画布存在的话,matplotlib会自动创建一个;正如调用subplot()时如果没有轴区则会自动新建一个。subplot()需要三个参数:numrows, numcols, plot_number,其中plot_number的范围是1至numrows乘numcols。如果numrows*numcols<10,逗号也是可以忽略的。比如subplot(211)等价于subplot(2, 1, 1)。
matplotlib允许创建任意数量的subplots和axes。如果你想手动放置axes的位置,比如不想按照网格排列,使用axes([left, bottom, width, height])可以调整axes的位置,(这4个参数范围均从0至1)。
你可以多次调用figure()生成多个画布。每个画布随你所愿地可以包含数个轴区或subplots。
import matplotlib.pyplot as plt
plt.figure(1) # 第一个 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) # 第二个 figure
plt.plot([4, 5, 6]) # creates a subplot() by default
plt.figure(1) # first figure current;
# subplot(212) still current
plt.subplot(211) # make subplot(211) in the first figure
# current
plt.title('Easy as 1, 2, 3') # subplot 211 title
可以用clf清空当前画布,用cla清空当前轴区。
注意: 当你绘制大量画布时,它们会占用内存,只有调用close函数后figure才会关闭。仅仅关掉画布的调用或不显示都不会清除内存占用。
操作文本(Text)
利用text可以往指定位置添加文本。 xlabel, ylabel 和 title会向特定位置添加文本。
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# the histogram of the data
n, bins, patches = plt.hist(x, 50, density=True, facecolor='g', alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
plt.title('Histogram of IQ')
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()
text函数会返回一个matplotlib.text.Text实例。可以通过关键字参数或setp函数改变它的属性。
t = plt.xlabel('my data', fontsize=14, color='red')
使用数学表达式
Matplotlib在任何文本表达式中接受TeX方程表达式。例如在标题中添加表达式,你可以用美元符号包围TeX表达式:
plt.title(r'$\sigma_i=15$')
标题字符串前面的r很重要——它表明该字符串是一个原始字符串,而不是将反斜杠视为python转义。
matplotlib有一个内置的TeX表达式解析器和布局引擎,并且提供了自己的数学字体。因此,您可以跨平台使用数学文本,而不需要安装TeX。对于那些安装了LaTeX和dvipng的人,你也可以使用LaTeX来格式化文本,并将输出直接合并到你的显示图形或保存的postscript中。
注释文本
使用上面的text函数将文本放置在轴上的任意位置。文本的一个常见用途是注释图形的某些特性,annotate方法提供了辅助功能,使注释变得容易。在注释中,有两点需要考虑:被注释的位置由参数xy表示,以及文本xytext的位置。这两个参数都是(x, y)元组。
ax = plt.subplot()
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)
plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)
plt.ylim(-2, 2)
plt.show()
在这个基本示例中,xy位置(箭头提示)和xytext位置(文本位置)都是数据坐标。
对数轴和其他非线性轴
matplotlib.pyplot不仅支持线性轴缩放,还支持对数和logit缩放。这通常用于数据跨越多个数量级。改变坐标轴的比例很简单:
plt.xscale('log')
下面是四个具有相同数据和不同y轴比例的图形的示例。
# Fixing random state for reproducibility
np.random.seed(19680801)
# make up some data in the open interval (0, 1)
y = np.random.normal(loc=0.5, scale=0.4, size=1000)
y = y[(y > 0) & (y < 1)]
y.sort()
x = np.arange(len(y))
# plot with various axes scales
plt.figure()
# linear
plt.subplot(221)
plt.plot(x, y)
plt.yscale('linear')
plt.title('linear')
plt.grid(True)
# log
plt.subplot(222)
plt.plot(x, y)
plt.yscale('log')
plt.title('log')
plt.grid(True)
# symmetric log
plt.subplot(223)
plt.plot(x, y - y.mean())
plt.yscale('symlog', linthresh=0.01)
plt.title('symlog')
plt.grid(True)
# logit
plt.subplot(224)
plt.plot(x, y)
plt.yscale('logit')
plt.title('logit')
plt.grid(True)
# Adjust the subplot layout, because the logit one may take more space
# than usual, due to y-tick labels like "1 - 10^{-3}"
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
wspace=0.35)
plt.show()