“matplotlib具有广泛的代码库,可能会使许多新用户望而却步” ————懒惰的中文手册
参考资料:
官网中文手册
Matplotlib简易教程|csdn|作者:汪雯琦
绘图需要在一系列级别上进行操作,实现从构想到命令再到细节操作控制,matplotlib中的所有内容都是按层次结构组织的。
顶层结构: matplotlib.pyplot ,模块提供的“状态机环境” 。此级别使用简单功能将绘图元素添加到当前图形中的当前轴。
面向对象的界面的第一层: 在此级别上,用户使用pyplot来创建图形,通过这些图形,可以创建一个或多个轴对象。然后将这些轴对象用于大多数绘图动作。
figure: 画布
axes: 坐标系
axis: 坐标轴
Artist: 基本上你可以在图中看到的一切都是一个Artist(甚至 Figure,Axes和Axis对象)。
绘制图形后,所有Artist都被绘制到画布上。大多数Artist都被绑在axes上。这样的Artist不能被多个轴共享,也不能从一个轴移动到另一个轴
一个figure上,可以有多个区域axes,我们在每个axes上绘图,每个axes中都有一个axis。
如图:
输入类型:通常,您将使用numpy数组。
实际上,所有序列都在内部转换为numpy数组 !!!
所以一开始就用numpy数组会使后续更加方便
所有绘图功能均预期np.array或np.ma.masked_array作为输入
Matplotlib本机仅支持PNG图像
matplotlib,pyplot和pylab关系
Matplotlib是整个软件包,
matplotlib.pyplot是其中的模块。
pylab是一个方便的模块,可以在单个名称空间中批量导入 (用于绘图)和(用于数学以及使用数组)。
对于pyplot样式,脚本顶部的导入通常为:
import matplotlib.pyplot as plt
import numpy as np
然后调用一个,例如,np.arange,np.zeros,np.pi,plt.figure,plt.plot,plt.show等。使用pyplot接口创建图形,然后使用对象方法进行其余操作:
x = np.arange(0, 10, 0.2)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()
pyplot:创建新图形的最简单方法,作用于当前图形(figure)的当前坐标系(axes)。
开始前,推荐先浏览初级绘制 , 对文章中提到的每个方法有过印象后继续阅读下列教程。
在看完本文该部分后再回头看看上附文中的例子,结合每一部分教程,体会精美作图
参数说明
num 新图的编号,默认递增
figsize 宽度,高度,以英寸为单位
dpi 分辨率,整数
facecolor 背景颜色
edgecolor 边框颜色
frameon 若为False,则没有边框
clear 若为True,如果图的编号已存在则先清除
plt.figure(num=1)
plt.plot(X,C)
#plt.close()
plt.figure(2)
plt.plot(X,S)
plt.figure(3)
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
plt.show()
# 会连续展现三张图
使用方法:
fig,ax = plt.subplots(nrows=1,ncols=2,figsize = (20,8), dpi=100)
# 相当于先新建个figure,再add_subplot,如果要多个画板则多次使用此命令: fig1,ax1 = plt.subplots()
ax[0].plot()
ax[1].plot()
ax[0].set_title() #面向对象设置格式
plt.subplot(221)
plt.plot(X,C) #面向过程设置格式
或
a = plt.subplot(221) #面向对象设置格式
a.plot(X,C)
b = plt.subplot(2,2,2)
b.plot(X,S)
对比 plt.subplot()、plt.subplots()、add_subplots以及add_axes
plt.函数名()相当于面向过程的画图方法,axes.set_方法名()相当于面向对象的画图方法
subplots 把画板规划好了,可以直接指定画板的大小,返回一个坐标数组对象
subplot 每次只能返回一个坐标对象
每条subplot命令只会创建一个子图,而一条subplots就可以将所有子图创建好
plt.subplot(221)
plt.plot(X,C)
plt.subplot(2,2,2) #可以隔开,也可以不隔开(一位数时)
plt.plot(X,S)
plt.subplot(212)
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
# 方法一 ,面向过程
plt.figure(figsize=(8,6), dpi=80)
plt.suptitle('画板标题')
plt.subplot(2,2,1)
plt.plot(X,C)
plt.title('子图标题1')
plt.subplot(2,2,2)
plt.plot(X,S)
plt.title('子图标题2')
# 方法二 ,面向对象
a = plt.figure(figsize=(8,6), dpi=80)
a.suptitle('画板标题')
b = plt.subplot(2,1,1)
b.plot(X,C)
b.set_title('子图标题1')
c = plt.subplot(2,1,2)
c.plot(X,S)
c.set_title('子图标题2')
fig,ax = plt.subplots(nrows=1,ncols=2,figsize = (20,8), dpi=100)
fig.suptitle("画板标题")
ax[0].plot(X, C)
ax[1].plot(X, C)
ax[0].set_title("子标题1")
ax[1].set_title("子标题2")
参数说明:
x 要在x坐标轴显示label的位置,label默认与位置号同
labels 对应x的位置的显示的标记
rotation lable显示的旋转角度
#只给出x则只显示给出的x数字
plt.xticks(np.linspace(-4,4,9,endpoint=True))
#设置将刻度映射为具体标签
xticks(arange(5), ("Tom", "Dick", "Harry", "Sally", "Sue") )
#正则表达式处理特殊符号
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
plt.yticks([-1, 0, +1],
[r'$-1$', r'$0$', r'$+1$'])
# 通过调整边框透明度防遮挡,bbox参数后面会见到
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65 ))
plt.grid(True, linestyle='--', alpha=0.5)
常用参数说明
b 是否显示网格线
which 取'major', 'minor','both' ,默认'major'
axis 绘制某个方向的网格线,取"both", "x","y"
color/c 网格线的颜色
linestyle/ls 设置网格线的风格
linewidth 设置网格线的宽度
参数说明
(1)设置图例位置
plt.legend(loc='upper center')
0: ‘best' 1:‘upper right'
2: ‘upper left' 3: ‘lower left'
4: ‘lower right' 5: ‘right'
6: ‘center left' 7: ‘center right'
8: ‘lower center' 9: ‘upper center'
10: ‘center'
(2)设置图例字体大小
fontsize : 直接写数字:int or float
或者写:{‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’}
(3)设置图例边框及背景
plt.legend(loc='best',frameon=False) #去掉图例边框
plt.legend(loc='best',edgecolor='blue') #设置图例边框颜色
plt.legend(loc='best',facecolor='blue') #设置图例背景颜色,若无边框,参数无效
对于边框还可以采用面向对象方式:
legend = plt.legend(["First", "Second"])
frame = legend.get_frame()
frame.set_facecolor('blue')
(4)设置图例标题
legend = plt.legend(["CH", "US"], title='China VS Us')
(5)设置图例名字及对应关系
legend = plt.legend([p1, p2], ["CH", "US"])
或者在plot中参数标注label *推荐
代码例: p1 = plt.scatter(train_x, train_y_1, c='red', marker='v' )
p2= plt.scatter(train_x, train_y_2, c='blue', marker='o' )
legend = plt.legend([p1, p2], ["CH", "US"], facecolor='blue')
plt.text(x, y, s, fontsize, verticalalignment, horizontalalignment, rotation , **kwargs)
参数说明
x,y 标签的坐标
fontsize 字体大小,int
verticalalignment 垂直对齐方式 ‘center’ ,‘top’ , ‘bottom’,‘baseline’ 等
horizontalalignment 水平对齐方式 ‘center’ , ‘right’ ,‘left’ 等
rotation 旋转角度,逆时针计算,int
family 设置字体
style 设置字体的风格
weight 字体的粗细
bbox 给字体添加框,如 bbox=dict(facecolor='red', alpha=0.5)
#批量给散点加标签
for i in range(len(x)):
plt.text(x[i]*1.01, y[i]*1.01, label[i], fontsize=10, color = "r",
style = "italic", weight = "light", verticalalignment='center',
horizontalalignment='right',rotation=0)
annotate(s='str' , xy=(x1,y1) , xytext=(x2,y2) , arrowprops)
参数说明
s 为注释文本内容
xy 为被注释的坐标点
xytext 为注释文字的坐标位置
xycoords 选择指定的坐标轴系统
textcoords 设置注释文字偏移量
arrowprops 箭头参数,参数类型为字典dict
width 点箭头的宽度
headwidth 点的箭头底座的宽度
headlength 点箭头的长度
shrink 总长度为分数从两端“缩水”
facecolor 箭头颜色
bbox 给字体添加框
# 设置坐标的常见案例
x = np.arange(0, 6)
y = x * x
plt.plot(x, y, marker='o')
for xy in zip(x, y):
plt.annotate("(%s,%s)" % xy, xy=xy, xytext=(-20, 10), textcoords='offset points')
plt.show()
# 设置箭头
plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),arrowprops = dict(facecolor='black', shrink=0.05))
# 一个完美的例子
plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
xy=(t, np.cos(t)), xycoords='data',
xytext=(-90, -50), textcoords='offset points', fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
坐标系有四条边框(脊柱)围成,轴线和上面的记号连在一起就形成了脊柱(Spines),它记录了数据区域的范围。
每幅图有四条脊柱(上下左右),为了将脊柱放在图的中间,我们必须将其中的两条(上和右)设置为无色,然后调整剩下的两条到合适的位置------数据空间的 0 点。
ax = gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none') # 隐藏top和right边框
ax.xaxis.set_ticks_position('bottom') # x轴'top': ticks值显示在top坐标轴上
ax.spines['bottom'].set_position(('data',0))# data 表示position是相对于数据坐标系
ax.yaxis.set_ticks_position('left') # y轴'right': 刻度值显示在right坐标轴上
ax.spines['left'].set_position(('data',0))
plt.savefig('test1.png') #默认保存在当前程序所在文件夹
plt.savefig('./test2.jpg')
pyplot并不默认支持中文显示,需要rcParams修改字体来实现
rcParams的属性:
‘font.family’ 用于显示字体的名字
‘font.style’ 字体风格,正常’normal’ 或斜体’italic’
‘font.size’ 字体大小,整数字号或者’large’ ‘x-small’
# 设定绘制区域的全部字体变成 华文仿宋,字体大小为20
matplotlib.rcParams[‘font.family’] = ‘STSong’
matplotlib.rcParams[‘font.size’] = 20
# 只希望在某地方绘制中文字符,不改变别的地方的字体
# 在有中文输出的地方,增加一个属性: fontproperties
plt.xlabel(‘横轴:时间’, fontproperties = ‘simHei’, fontsize = 20)
各种方法中常常用到同一类参数,附以下补充
参数可以简写
linestyle /ls {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
linewidth /lw float
markeredgecolor /mec color
markeredgewidth /mew float
markerfacecolor /mfc color
markersize /ms float
size /s 大小
color /c 颜色
多方法都用到的参数值如下
字体大小fontsize : 直接写数字:int or float
或者写:{‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’}
有文字的方法参数都是通用的,线条也是如此,比如设置bbox等。参数使用时大同小异
颜色字符 风格字符
r 红色 - 实线
g 绿色 -- 虚线
b 蓝色 -. 点划线
w 白色 : 点虚线
c 青色 ’ ’ 留空、空格
m 洋红
y 黄色
k 黑色
RGB16进制都可
fig = plt.figure(figsize=(8,6), dpi=80)
# 创建一个 8 * 6 点(point)的图,并设置分辨率为 80,
# 只绘制一个图的话不用去设置绘图区域
fig.suptitle('图名') # 命名图
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="b", linewidth=1.0, linestyle="-",label="正弦")
plt.plot(X, S, color="green", linewidth=1.0, linestyle='--', label="正弦")
# 绘制折线图
# 使用多次plot可以画多个折线
plt.legend(loc="best") # 显示图例
plt.xlim(-4.0,4.0) # 设置横轴的上下限
plt.xticks(np.linspace(-4,4,9,endpoint=True))# 设置横轴要显示的刻度值
plt.ylim(-1.0,1.0) # 设置纵轴的上下限
plt.yticks(np.linspace(-1,1,5,endpoint=True))# 设置纵轴要显示的刻度值
plt.grid(True, linestyle='--', alpha=0.5) #添加网格线 linestyle线型 alpha透明度
plt.savefig('./安徽省宣城市泾县未来一周最低气温折线图.png',dpi=72)
# 以分辨率 72 来保存图片,savefig必须在show之前
plt.show() # 在屏幕上显示
#创建画布
fig,ax = plt.subplots(nrows=1,ncols=2,figsize = (20,8), dpi=100)
#绘制两个折线图
x = range(60)
y_jingxian = [random.uniform(15,18) for i in x]
y_beijing = [random.uniform(3,8) for i in x]
ax[0].plot(x,y_jingxian , label = '泾县')
ax[1].plot(x,y_beijing , label = '北京' , color='r')
plt.rcParams['font.family']=['SimHei']
#添加描述信息
ax[0].set_xlabel('时间',fontsize = 20)
ax[0].set_ylabel('温度',fontsize = 20)
ax[0].set_title('安徽省宣城市泾县每分钟的温度变化折线图',fontsize = 30)
ax[1].set_xlabel('时间',fontsize = 20)
ax[1].set_ylabel('温度',fontsize = 20)
ax[1].set_title('北京市每分钟的温度变化折线图',fontsize = 30)
# 添加坐标轴刻度
x_tick_label = ["11点{}分".format(i) for i in x]
ax[0].set_xticks(x[::5])
ax[0].set_xticklabels(x_tick_label[::5])
ax[1].set_xticks(x[::5])
ax[1].set_xticklabels(x_tick_label[::5])# [::5]是每隔五个选一个,后面的也要对应上
y_range = range(40)
ax[0].set_yticks(y_range[::5])
ax[1].set_yticks(y_range[::5])
# 添加网格线
ax[0].grid(linestyle='--', alpha=0.8)
ax[1].grid(linestyle='--', alpha=0.8)
#添加图例 loc指定图例的位置
ax[0].legend(loc = 'best')
ax[1].legend(loc = 'best')
#保存图像
plt.savefig('./安徽省宣城市泾县对比北京市11点到12点1小时内每分钟的温度变化折线图.png')
#显示图像
plt.show()#如果不用show的话,只是在缓存中
# 构造中文轴刻度标签典型例子
x_ticks_label = ["11点{}分".format(i) for i in x]
y_ticks = range(40)
plt.xticks(x[::5], x_ticks_label[::5])
plt.yticks(y_ticks[::5])
散点图
plt.scatter(x,y,s=20,c='b',marker='')
或者:plt.plot_date(date, y, '-')
#plt的plot_date默认画的的是散点
参数说明
x,y X和Y是长度相同的数组
s size,点的大小,标量或与数据长度相同的数组
c color,点的颜色,标量或与数据长度相同的数组
marker MarketStyle,可选,点的形状,默认'o'
cmap Colormap,可选,默认'None'
norm Normalize,亮度设置,0-1
vmin,vmax 亮度设置
alpha 透明度,0-1
linewidths 线宽
其中散点的形状参数marker如下:
#绘制彩色泡泡效果
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = (30 * np.random.rand(N))**2 # 0 to 15 point radii
plt.scatter(x, y, s=area, c=colors, alpha=0.5)
plt.show()
线图
plt.plot(x, y, fmt)
参数说明:
x, y 数据
fmt format,格式,形状,例如,'ro--'表示红圈虚线
data 标有数据的对象,可选
plt.plot()是一个通用命令,将(x, y)绘制成线条或散点图。
如果为命令提供单个列表或数组 ,则默认是y值的序列,并自动生成x值(从0开始与y数量相当)
其中,线条的格式还可以使用如下线属性:
alpha float,透明度
fillstyle {'full', 'left', 'right', 'bottom', 'top', 'none'}
linestyle/ls {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
linewidth/lw float
marker marker style
markeredgecolor /mec color
markeredgewidth /mew float
markerfacecolor /mfc color
markersize /ms float
设置格式有两种方法:当线属性与fmt冲突时,线属性优先:
plt.plot(X, C, 'go--') # fmt
plt.plot(X, S, color='green', marker='o', linestyle='--') # 线属性
# 一个是fmt,一个是线属性,但是它们的格式是一样的
也可以只用一个命令,绘制 多行 具有不同格式样式的线条
plt.plot(X, C, 'go--', X, S, 'go--', X, X**3, 'g^')
#与上一个代码图相同
# 填充包围面积
plt.plot (X, Y-1, color='blue', alpha=1.00)
plt.fill_between(X, -1, Y-1, (Y-1) > -1, color='blue', alpha=.25)
plt.fill_between(X, -1, Y-1, (Y-1) < -1, color='red', alpha=.25)
条形图
plt.bar(x, height, width=0.8, bottom=None, ***, align='center', data=None, **kwargs)
参数说明
x 数值位置
height 柱状图的高度,相当于y
width 柱状图的宽度
align 条形的中心与刻度的对齐方式,{‘center’, ‘edge’},默认 ‘center’
botton 条形的起始位置,y轴的起始坐标!
color 柱状图的颜色
edgecolor 边框的颜色
linewidth 边框的宽度,像素,默认无,int
tick_label 下标的标签 可以是元组类型的字符组合
log y轴是否使用科学计算法表示,bool
orientation 是竖直条还是水平条
竖直:"vertical",水平条:"horizontal"
水平条形图
1. 用bar
水平条形图需要把:orientation="horizontal",然后x,与y的数据交换,再添加bottom=x,即可。
N = 5
x = [20, 10, 30, 25, 15]
y = np.arange(N)
# 绘图 x= 起始位置, bottom= 水平条的底部(左侧), y轴, height 水平条的宽度, width 水平条的长度
p1 = plt.bar(x=0, bottom=y, height=0.5, width=x, orientation="horizontal")
2. 用barh
#barh()函数表示水平方向画柱状图
使用barh()时,bottom改为left, 然后宽变高,高变宽。
# 数据
N = 5
x = [20, 10, 30, 25, 15]
y = np.arange(N)
# 绘图 y= y轴, left= 水平条的底部, height 水平条的宽度, width 水平条的长度
p1 = plt.barh(y, left=0, height=0.5, width=x)
并列条形图
# 数据
x = np.arange(4)
Bj = [52, 55, 63, 53]
Sh = [44, 66, 55, 41]
bar_width = 0.3
# 绘图 x 表示从那里开始,关键在改变第二个图的x位置
plt.bar(x, Bj, bar_width)
plt.bar(x+bar_width, Sh, bar_width, align="center")
层叠条形图:
# 数据
x = np.arange(4)
Bj = [52, 55, 63, 53]
Sh = [44, 66, 55, 41]
bar_width = 0.3
# 绘图,关键让y从上一个图的位置衔接,利用bottle
plt.bar(x, Bj, bar_width)
plt.bar(x, Sh, bar_width, bottom=Bj)
直方图
plt.hist(x,bins=10,clolor='blue',normed=True)
饼状图
n = 20
Z = np.ones(n)
Z[-1] *= 2
plt.axes([0.025, 0.025, 0.95, 0.95])
plt.pie(Z, explode=Z*.05, colors=['%f' % (i/float(n)) for i in range(n)],
wedgeprops={"linewidth": 1, "edgecolor": "black"})
plt.gca().set_aspect('equal')
极轴图
ax = plt.axes([0.025,0.025,0.95,0.95], polar=True)
N = 20
theta = np.arange(0.0, 2*np.pi, 2*np.pi/N)
radii = 10*np.random.rand(N)
width = np.pi/4*np.random.rand(N)
bars = plt.bar(theta, radii, width=width, bottom=0.0)
for r,bar in zip(radii, bars):
bar.set_facecolor( plt.cm.jet(r/10.))
bar.set_alpha(0.5)
等高线图
def f(x,y):
return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)
n = 256
x = np.linspace(-3,3,n)
y = np.linspace(-3,3,n)
X,Y = np.meshgrid(x,y)
plt.axes([0.025,0.025,0.95,0.95])
plt.contourf(X, Y, f(X,Y), 8, alpha=.75, cmap=plt.cm.hot)
C = plt.contour(X, Y, f(X,Y), 8, colors='black', linewidth=.5)
plt.clabel(C, inline=1, fontsize=10)
灰度图(Imshow)
def f(x,y):
return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)
n = 10
x = np.linspace(-3,3,3.5*n)
y = np.linspace(-3,3,3.0*n)
X,Y = np.meshgrid(x,y)
Z = f(X,Y)
plt.axes([0.025,0.025,0.95,0.95])
plt.imshow(Z,interpolation='bicubic', cmap='bone', origin='lower')
plt.colorbar(shrink=.92)
量场图(quiver)
n = 8
X,Y = np.mgrid[0:n,0:n]
T = np.arctan2(Y-n/2.0, X-n/2.0)
R = 10+np.sqrt((Y-n/2.0)**2+(X-n/2.0)**2)
U,V = R*np.cos(T), R*np.sin(T)
plt.axes([0.025,0.025,0.95,0.95])
plt.quiver(X,Y,U,V,R, alpha=.5)
plt.quiver(X,Y,U,V, edgecolor='k', facecolor='None', linewidth=.5)
plt.xlim(-1,n), plt.xticks([])
plt.ylim(-1,n), plt.yticks([])
本文章使用limfx的vsocde插件快速发布