1. 安装和文档
pip install matplotlib
为了方便显示图像,还使用了ipython qtconsole方便显示。具体怎么弄网上搜一下就很多教程了。
pyplot模块是提供操作matplotlib库的经典Python接口。
# 导入pyplot
import matplotlib.pyplot as plt
2. 初探pyplot
plot()的参数表
matplotlib.pyplot.plot(*args, **kwargs)
The following format string characters are accepted to control the line style or marker:
character
description
'-'
solid line style
'--'
dashed line style
'-.'
dash-dot line style
':'
dotted line 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
'
'
'_'
hline marker
The following color abbreviations are supported:
character
color
‘b’
blue
‘g’
green
‘r’
red
‘c’
cyan
‘m’
magenta
‘y’
yellow
‘k’
black
‘w’
white
演示
plt.axis([0,5,0,20]) # [xmin,xmax,ymin,ymax]对应轴的范围
plt.title('My first plot') # 图名
plt.plot([1,2,3,4], [1,4,9,16], 'ro') # 图上的点,最后一个参数为显示的模式
Out[5]: []
plt.show() # 展示图片

In [11]: t = np.arange(0, 2.5, 0.1)
...: y1 = list(map(math.sin, math.pi*t))
...: y2 = list(map(math.sin, math.pi*t + math.pi/2))
...: y3 = list(map(math.sin, math.pi*t - math.pi/2))
...:
In [12]: plt.plot(t, y1, 'b*', t, y2, 'g^', t, y3, 'ys')
Out[12]:
[,
,
]
In [13]: plt.show()

In [14]: plt.plot(t,y1,'b--',t,y2,'g',t,y3,'r-.')
Out[14]:
[,
,
]
In [15]: plt.show()

3. 处理多个Figure和Axes对象
subplot(nrows, ncols, plot_number)
In [19]: plt.subplot(2,1,1)
...: plt.plot(t,y1,'b-.')
...: plt.subplot(2,1,2)
...: plt.plot(t,y2,'r--')
...:
Out[19]: []
In [20]: plt.show()

In [30]: plt.subplot(2,1,1)
...: plt.plot(t,y1,'b-.')
...: plt.subplot(2,1,2)
...: plt.plot(t,y2,'r--')
...:
Out[30]: []
In [31]: plt.show()

4. 添加更多元素
4.1. 添加文本
添加标题:title()
添加轴标签:xlabel()和ylabel()
在图形的坐标添加文本:text(x, y, string, fontdict=None, **kwargs),分别表示坐标和字符串以及一些关键字参数。
还可以添加LaTeX表达式,绘制边框等。
In [40]: plt.axis([0,5,0,20])
...: plt.title('_Kazusa', fontsize=20, fontname='Times New Roman')
...: plt.xlabel('x_axis', color='orange')
...: plt.ylabel('y_axis', color='gray')
...: plt.text(1, 1.5, 'A')
...: plt.text(2, 4.5, 'B')
...: plt.text(3, 9.5, 'C')
...: plt.text(4, 16.5, 'D')
...: plt.text(0.5, 15, r'$y=x^2$', fontsize=20, bbox={'facecolor':'yellow','alpha':0.2})
...: plt.plot([1,2,3,4],[1,4,9,16],'ro')
...:
Out[40]: []
In [41]: plt.show()

4.2. 其他元素
网格:grid(True) 表示显示网格
图例:matplotlib.pyplot.legend(*args, **kwargs)
图例的位置参数:
loc : int or string or pair of floats, default: ‘upper right’
The location of the legend. Possible codes are:
Location String
Location Code
‘best’
0
‘upper right’
1
‘upper left’
2
‘lower left’
3
‘lower right’
4
‘right’
5
‘center left’
6
‘center right’
7
‘lower center’
8
‘upper center’
9
‘center’
10
Alternatively can be a 2-tuple giving x, y of the lower-left corner of the legend in axes coordinates (in which case bbox_to_anchor will be ignored).
In [44]: plt.axis([0,5,0,20])
...: plt.title('_Kazusa', fontsize=20, fontname='Times New Roman')
...: plt.xlabel('x_axis', color='orange')
...: plt.ylabel('y_axis', color='gray')
...: plt.text(1, 1.5, 'A')
...: plt.text(2, 4.5, 'B')
...: plt.text(3, 9.5, 'C')
...: plt.text(4, 16.5, 'D')
...: plt.text(0.5, 10, r'$y=x^2$', fontsize=20, bbox={'facecolor':'yellow','alpha':0.2})
...: plt.plot([1,2,3,4],[1,4,9,16],'ro')
...: plt.grid(True)
...: plt.plot([1,2,3,4],[0.6,2.3,14.5,15.8], 'g^')
...: plt.plot([1,2,3,4],[0.2,9.7,11.6,13.9],'b*')
...: plt.legend(['First series', 'Sencond series', 'Third series'], loc=0)
...:
Out[44]:
In [45]: plt.show()

5. 保存
%save mycode 44
# %save魔术命令后,跟着文件名和代码对于的命令提示符号码。例如上面In [44]: plt.axis([0,5,0,20])号码就是44,运行之后会在工作目录生成'mycode.py'文件,还可以是'数字-数字',即保存从一个行数到另一个行数的代码
ipython qtconsole -m mycode.py
#可以打开之前的代码
%load mycode.py
#可以加载所有代码
%run mycode.py
#可以运行代码
#保存图片的话,可以在生成图标的一系列命令之后加上savefig()函数把图标保存为PNG格式。
#在保存图像命令之前不要使用plt.show()否则会得到空白图像
In [30]: plt.subplot(2,1,1)
...: plt.plot(t,y1,'b-.')
...: plt.subplot(2,1,2)
...: plt.plot(t,y2,'r--')
...: plt.savefig('pic.png')
6. 线形图
替换坐标轴的刻度的标签:xticks()和yticks()。传入的参数第一个是存储刻度的位置的列表,第二个是存储刻度的标签的列表。要正确显示标签,要使用含有LaTeX表达式的字符串。
显示笛卡尔坐标轴:首先用gca()函数获取Axes对象。通过这个对象,指定每条边的位置:上下左右,可选择组成图形边框的每条边。使用set_color()函数,设置颜色为'none'(这里我不删除而是换了个颜色方便确认位置),删除根坐标轴不符合的边(右上)。用set_positon()函数移动根x轴和y轴相符的边框,使其穿过原点(0,0)。
annotate()函数可以添加注释。第一个参数为含有LaTeX表达式、要在图形中显示的字符串;随后是关键字参数。文本注释跟它所解释的数据点之间的距离用xytext关键字参数指定,用曲线箭头将其表示出来。箭头的属性由arrowprops关键字参数指定。
In [57]: x = np.arange(-2*np.pi, 2*np.pi, 0.01)
...: y1 = np.sin(3*x)/x
...: y2 = np.sin(2*x)/x
...: y3 = np.sin(x)/x
...: plt.plot(x,y1,color='y')
...: plt.plot(x,y2,color='r')
...: plt.plot(x,y3,color='k')
...: plt.xticks([-2*np.pi, -np.pi, 0, np.pi, 2 * np.pi], [r'$-2\pi$', r'$-\pi$', r'$0$', r'$+\pi$', r'$+2\pi$'])
...: plt.yticks([-1, 0, +1, +2, +3], [r'$-1$', r'$0$', r'$+1$', r'$+2$', r'$+3$'])
...: # 设置坐标轴标签
...: plt.annotate(r'$\lim_{x\to 0}\frac{\sin(x)}{x}=1$', xy=[0,1], xycoords='data', xytext=[30,30], fontsize=18, textcoords='offset points', arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=.2")) # 设置注释
...:
...: ax = plt.gca()
...: ax.spines['right'].set_color('r')
...: ax.spines['top'].set_color('b')
...: ax.xaxis.set_ticks_position('bottom')
...: ax.spines['bottom'].set_position(('data',0))
...: ax.yaxis.set_ticks_position('left')
...: ax.spines['left'].set_position(('data',0))
...: ax.spines['bottom'].set_color('g')
...: ax.spines['left'].set_color('k') # 设置笛卡尔坐标轴
...:
In [58]: plt.show()

为pandas数据结构绘制线形图##
把DataFrame作为参数传入plot()函数,就可以得到多序列线形图。
In [60]: data = {'series1':[1,3,4,3,5], 'series2':[2,4,5,2,4], 'series3':[5,4,4,1,5]}
...: df = pd.DataFrame(data)
...: x = np.arange(5)
...: plt.axis([0,6,0,6])
...: plt.plot(x,df)
...: plt.legend(data, loc=0)
...:
Out[60]:
In [61]: plt.show()

7. 直方图
hist()可以用于绘制直方图。
In [4]: array = np.random.randint(0, 50, 50)
In [5]: array
Out[5]:
array([43, 1, 16, 9, 22, 15, 1, 12, 9, 25, 37, 47, 31, 15, 25, 43, 3,
28, 21, 23, 11, 10, 14, 27, 10, 19, 40, 44, 26, 49, 13, 35, 19, 48,
7, 21, 37, 47, 2, 4, 15, 20, 47, 11, 2, 49, 31, 31, 1, 46])
In [8]: n, bins, patches = plt.hist(array, bins=10) # hist()第二个参数便是划分的面元个数,n表示每个面元有几个数字,bins表示面元的范围,patches表示每个长条
In [10]: n
Out[10]: array([ 7., 5., 8., 4., 4., 5., 3., 3., 4., 7.])
In [11]: bins
Out[11]:
array([ 1. , 5.8, 10.6, 15.4, 20.2, 25. , 29.8, 34.6, 39.4,
44.2, 49. ])
In [13]: for patch in patches:
...: print(patch)
...:
Rectangle(1,0;4.8x7)
Rectangle(5.8,0;4.8x5)
Rectangle(10.6,0;4.8x8)
Rectangle(15.4,0;4.8x4)
Rectangle(20.2,0;4.8x4)
Rectangle(25,0;4.8x5)
Rectangle(29.8,0;4.8x3)
Rectangle(34.6,0;4.8x3)
Rectangle(39.4,0;4.8x4)
Rectangle(44.2,0;4.8x7)
In [9]: plt.show()

8. 条状图
bar()函数可以生成垂直条状图
barh()函数可以生成水平条状图,设置的时候坐标轴参数和垂直条状图相反,其他都是一样的。
8.1 普通条状图
In [24]: index = np.arange(5)
...: values = [5,7,3,4,6]
...: plt.bar(index, values)
...: plt.title('_Kazusa')
...: plt.xticks(index,['A','B','C','D','E'])
...: plt.legend('permutation', loc = 0)
...:
Out[24]:
In [25]: plt.show()

8.2 多序列条状图
In [34]: index = np.arange(5)
...: val1 = [5,7,3,4,6]
...: val2 = [6,6,4,5,7]
...: val3 = [5,6,5,4,6]
...: gap = 0.31 # 把每个类别占的空间(总空间为1)分成多个部分,例如这里有三个,因为要增加一点空间区分相邻的类别,因此取0.31
...: plt.axis([0,5,0,8])
...: plt.title('_Kazusa')
...: plt.bar(index+0.2, val1, gap, color='b')
...: plt.bar(index+gap+0.2, val2, gap, color='y')
...: plt.bar(index+2*gap+0.2, val3, gap, color='k')
...: plt.xticks(index+gap+0.2, ['A','B','C','D','E']) # index+gap即标签偏移gap的距离
...:
Out[34]:
([,
,
,
,
],
)
In [35]: plt.show()

8.3 对序列堆积条状图
有时候需要表示总和是由几个条状图相加得到,因此堆积图表示比较合适。
使用bar()的时候添加参数bottom=来确定下面是什么。
In [41]: arr1 = np.array([3,4,5,3])
...: arr2 = np.array([1,2,2,5])
...: arr3 = np.array([2,3,3,4])
...: index = np.arange(4)
...: plt.axis([0,4,0,15])
...: plt.title('_Kazusa')
...: plt.bar(index + 0.5, arr1, color='r')
...: plt.bar(index + 0.5, arr2, color='b', bottom=arr1)
...: plt.bar(index + 0.5, arr3, color='y', bottom=(arr1+arr2))
...: plt.xticks(index + 0.5, ['A','B','C','D','E'])
...:
Out[41]:
([,
,
,
],
)
In [42]: plt.show()

8.4 为DataFrame绘制条状图
In [47]: data = {'arr1':[1,3,4,3,5], 'arr2':[2,4,5,2,4], 'arr3':[1,3,5,1,2]}
...: df = pd.DataFrame(data)
...: df.plot(kind='bar') # 若要堆积图,变成 df.plot(kind='bar', stacked=True)
...:
Out[47]:
In [48]: plt.show()

9. 饼图
pie()函数可以制作饼图
In [51]: labels = ['A','B','C','D'] # 标签
...: values = [10,30,45,15] # 数值
...: colors = ['yellow', 'green', 'red', 'orange'] # 颜色
...: explode = [0.3, 0, 0, 0] # 突出显示,数值0~1
...: plt.title('_Kazusa')
...: plt.pie(values, labels=labels, colors=colors, explode=explode, startangle=90, shadow=True, autopct='%1.1f%%') # shadow表示阴影, autopct表示显示百分比, startangle表示饼旋转的角度
...: plt.axis('equal')
...:
Out[51]:
(-1.1007797083302826,
1.1163737124158366,
-1.1306395753855039,
1.4003625034945653)
In [52]: plt.show()

10. 等值线图
由一圈圈封闭的曲线组成的等值线图表示三维结构的表面,其中封闭的曲线表示的是一个个处于同一层级或z值相同的数据点。
contour()函数可以生成等值线图。
In [57]: dx = 0.01; dy = 0.01
...: x = np.arange(-2.0, 2.0, dx)
...: y = np.arange(-2.0, 2.0, dy)
...: X, Y = np.meshgrid(x, y) # 这里meshigrid(x,y)的作用是产生一个以向量x为行,向量y为列的矩阵,而x是从-2开始到2,每间隔dx记下一个数据,并把这些数据集成矩阵X;同理y则是从-2到2,每间隔dy记下一个数据,并集成矩阵Y
...: def f(x,y): # 生成z的函数
...: return (1 - y**5 + x**5) * np.exp(-x**2 - y**2)
...: C = plt.contour(X, Y, f(X,Y), 8, colors='black') # 8表示分层的密集程度,越小越稀疏,colors表示最开始是什么颜色
...: plt.contourf(X, Y, f(X,Y), 8) # 使用颜色,8的意义同上
...: plt.clabel(C, inline=1, contsize=10) # 生成等值线的标签
...: plt.colorbar() # 侧边的颜色说明
...:
Out[57]:
In [58]: plt.show()

11. 3D图
3D图的Axes对象要替换为Axes3D对象。
from mpl_toolkits.mplot3d import Axes3D
11.1. 3D曲面
plot_surface(X, Y, Z, *args, **kwargs)可以显示面
Argument
Description
X, Y, Z
Data values as 2D arrays
rstride
Array row stride (step size)
cstride
Array column stride (step size)
rcount
Use at most this many rows, defaults to 50
ccount
Use at most this many columns, defaults to 50
color
Color of the surface patches
cmap
A colormap for the surface patches.
facecolors
Face colors for the individual patches
norm
An instance of Normalize to map values to colors
vmin
Minimum value to map
vmax
Maximum value to map
shade
Whether to shade the facecolors
In [9]: fig = plt.figure()
...: ax = Axes3D(fig)
...: X = np.arange(-2, 2, 0.1)
...: Y = np.arange(-2, 2, 0.1)
...: X, Y = np.meshgrid(X, Y)
...: def f(x,y):
...: return (1 - y ** 5 + x ** 5) * np.exp(-x ** 2 - y ** 2)
...: ax.plot_surface(X, Y, f(X,Y), rstride=1, cstride=1) # rstide/cstride表示 行/列数组的跨度
...: ax.view_init(elev=30,azim=125) # elev指定从哪个高度查看曲面,azim指定曲面旋转的角度
...:
In [10]: pt.show()

11.2. 3D散点图
Axes3D.scatter(xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True, *args, **kwargs)可以使用散点图
Argument
Description
xs, ys
Positions of data points.
zs
Either an array of the same length as xs and ys or a single value to place all points in the same plane. Default is 0.
zdir
Which direction to use as z (‘x’, ‘y’ or ‘z’) when plotting a 2D set.
s
Size in points^2. It is a scalar or an array of the same length as x and y.
c
A color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below).
depthshade
Whether or not to shade the scatter markers to give the appearance of depth. Default is True.
In [16]: x1 = np.random.randint(30, 40, 100)
...: y1 = np.random.randint(30, 40, 100)
...: z1 = np.random.randint(10, 20, 100)
...: x2 = np.random.randint(50, 60, 100)
...: y2 = np.random.randint(50, 60, 100)
...: z2 = np.random.randint(10, 20, 100)
...: x3 = np.random.randint(30, 40, 100)
...: y3 = np.random.randint(30, 40, 100)
...: z3 = np.random.randint(40, 50, 100)
...: fig = plt.figure()
...: ax = Axes3D(fig)
...: ax.scatter(x1, y1, z1)
...: ax.scatter(x2, y2, z2, c = 'r', marker = '^')
...: ax.scatter(x3, y3, z3, c = 'y', marker = '*')
...: ax.set_xlabel('X axis')
...: ax.set_ylabel('Y axis')
...: ax.set_zlabel('Z axis')
...:
Out[16]:
In [17]: plt.show()

11.3. 3D条状图
bar()函数
Axes3D.bar(left, height, zs=0, zdir='z', *args, **kwargs)
Argument
Description
left
The x coordinates of the left sides of the bars.
height
The height of the bars.
zs
Z coordinate of bars, if one value is specified they will all be placed at the same z.
zdir
Which direction to use as z (‘x’, ‘y’ or ‘z’) when plotting a 2D set.
In [22]: x = np.arange(5)
...: y1 = np.random.randint(0, 10, 5)
...: y2 = y1 + np.random.randint(0, 3, 5)
...: y3 = y2 + np.random.randint(0, 3, 5)
...: y4 = y3 + np.random.randint(0, 3, 5)
...: y5 = y4 + np.random.randint(0, 3, 5)
...: clr = ['yellow', 'red', 'blue', 'black', 'green']
...: fig = plt.figure()
...: ax = Axes3D(fig)
...: ax.bar(x, y1, 0, zdir = 'y', color = clr)
...: ax.bar(x, y2, 10, zdir = 'y', color = clr)
...: ax.bar(x, y3, 20, zdir = 'y', color = clr)
...: ax.bar(x, y4, 30, zdir = 'y', color = clr)
...: ax.bar(x, y5, 40, zdir = 'y', color = clr)
...: ax.set_xlabel('x Axis')
...: ax.set_ylabel('y Axis')
...: ax.set_zlabel('z Axis')
...: ax.view_init(elev=40)
...:
In [23]: plt.show()

12. 多面板图形
12.1. 在其他子图中显示子图
把主Axes对象(主图表)跟放置另一个Axes对象实例的框架分开。用figure()函数取到Figure对象,用add_axes()函数在它上面定义两个Axes对象。
add_axes(*args, **kwargs)
rect = l,b,w,h # (分别是左边界,下边界,宽,高)
fig.add_axes(rect)
In [28]: fig = plt.figure()
...: ax = fig.add_axes([0.1,0.1,0.8,0.8])
...: inner_ax = fig.add_axes([0.6,0.6,0.25,0.25])
...: x1 = np.arange(10)
...: y1 = np.array([1,2,7,1,5,2,4,2,3,1])
...: x2 = np.arange(10)
...: y2 = np.array([1,2,3,4,6,4,3,4,5,1])
...: ax.plot(x1,y1)
...: inner_ax.plot(x2,y2)
...:
Out[28]: []
In [29]: plt.show()

12.2. 子图网格
class matplotlib.gridspec.GridSpec(nrows, ncols, left=None, bottom=None, right=None, top=None, wspace=None, hspace=None, width_ratios=None, height_ratios=None)
add_subplot(*args, **kwargs)
In [30]: gs = plt.GridSpec(3,3) # 分成多少块
...: fig = plt.figure(figsize=(8,8)) # 指定图的尺寸
...: x1 = np.array([1,3,2,5])
...: y1 = np.array([4,3,7,2])
...: x2 = np.arange(5)
...: y2 = np.array([3,2,4,6,4])
# 可以看做分作一个3*3的格子,每次给一个表分配格子,[row,col],[0,0]表示左上角
...: p1 = fig.add_subplot(gs[1,:2])
...: p1.plot(x1, y1, 'r')
...: p2 = fig.add_subplot(gs[0,:2])
...: p2.bar(x2, y2)
...: p3 = fig.add_subplot(gs[2,0])
...: p3.barh(x2, y2, color='b')
...: p4 = fig.add_subplot(gs[:2,2])
...: p4.plot(x2, y2, 'k')
...: p5 = fig.add_subplot(gs[2,1:])
...: p5.plot(x1, y1, 'b^', x2, y2, 'yo')
...:
Out[30]:
[,
]
In [32]: plt.show()