Matplotlib是Python中最常用的可视化工具,可以非常方便的生成出版质量级的图片,只需几行代码,就可以生成直方图、功率谱、条形图、错误图、散点图、饼图以及基本的3D图表。在使用中一般使用如下载入matplotlib的绘图库:
import matplotlib.pyplot as plt
下面我们一步一步来介绍使用matplotlib进行绘图的过程:
- 创建绘图对象
figure(num = None,figsize = None,dpi = None, facecolor = None,edgecolor = None)
参数 | 用法说明 |
---|---|
num | 默认为None,如果参数未提供,将创建新图形,并且图形编号将递增。图形对象将此数字保存在number 属性中。如果提供了num,并且已存在具有此id的数字,请将其设置为活动状态,并返回对它的引用。如果此图不存在,则创建它并返回它。如果num是一个字符串,则窗口标题将设置为此图 num。 |
figsize | 整数元组,指定图形对象的宽度和高度,如未提供,默认为figure.figsize。 |
dpi | Dots Per Inch,每英寸点数,指每一英寸长度中,取样、可显示或输出点的数目。 DPI是打印机、鼠标等设备分辨率的度量单位。,如未提供,默认为figure.dpi |
facecolor | 设置图形对象的背景颜色,如未提供,默认为figure.facecolor。 |
edgecolor | 设置图形对象的边框颜色,如未提供,默认为figure.edgecolor。 |
更多参数请参考: matplotlib.pyplot.figure
- 绘制条形图
matplotlib.pyplot.bar(left, height, alpha, width, facecolor, edgecolor, label, lw)
绘制水平条形图时使用barh()参数用法相同
参数 | 用法说明 |
---|---|
left | 横坐标的位置序列 |
height | 纵坐标的数值序列,也就是柱形图的高度 |
alpha | 图形透明度 |
width | 柱形图的宽度,一般设为0.8 |
facecolor | 柱形图的填充颜色 |
edgecolor | 图形边缘的颜色 |
label | 图例 |
lw | 边缘线的宽度 |
我们通过几个例子来熟悉这些参数:
- 例1
import matplotlib.pyplot as plt
#城市
city = ['beijing','shanghai','chengdou','chongqing']
#gpd
gdp = [29876,32212,15015,21385]
plt.figure('City GDP',figsize=(8,4),dpi = 80)
#绘制柱形图
plt.bar(city,gdp,alpha = 1,width = 0.4,label = 'GDP')
plt.xlabel('City')
plt.ylabel('GDP')
plt.title('City-GDP')
#显示图例
plt.legend()
#显示图形
plt.show()
- 例2
import matplotlib.pyplot as plt
import matplotlib
label_list = ['2014', '2015', '2016', '2017']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 30, 40, 20]
x = range(len(num_list1))
rects1 = plt.bar(left=x, height=num_list1, width=0.4, alpha=1, color='red', label="department-one")
rects2 = plt.bar(left=[i + 0.4 for i in x], height=num_list2, width=0.4, color='green', label="department-two")
#指定y轴的范围
plt.ylim(0, 50)
plt.ylabel("quetity")
#设置坐标点刻度显示的值
plt.xticks([index + 0.2 for index in x], label_list)
plt.xlabel("year")
plt.title("company")
plt.legend()
#在相应的条形图上显示当前的数值
for rect in rects1:
#获得条形图的高度即数值
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
for rect in rects2:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
#将图片输出到指定目录
plt.savefig('/Users/wcjb/Documents/Machine Learning/Hist-1',dpi = 800)
plt.show()
- 例3
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
price = [39.5, 39.9, 45.4, 38.9, 33.34]
plt.barh(range(5), price, height=0.7, color='steelblue', alpha=0.8)
plt.yticks(range(5), ['one', 'two', 'three', 'four', 'five'])
#指定横坐标的范围
plt.xlim(30,47)
plt.xlabel("price")
plt.title("book-price")
#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标.
for x, y in enumerate(price):
plt.text(y + 0.2, x - 0.1, '%s' % y)
plt.savefig('/Users/wcjb/Documents/Machine Learning/Hist-2',dpi = 800)
plt.show()
- 例4
import matplotlib.pyplot as plt
import matplotlib
label_list = ['2014', '2015', '2016', '2017']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 30, 40, 20]
x = range(len(num_list1))
rects1 = plt.bar(left=x, height=num_list1, width=0.45, alpha=0.8, color='red', label="one")
rects2 = plt.bar(left=x, height=num_list2, width=0.45, color='green', label="two", bottom=num_list1)
plt.ylim(0, 80)
plt.ylabel('quantity')
plt.xticks(x, label_list)
plt.xlabel("year")
plt.title("company")
plt.legend()
plt.savefig('/Users/wcjb/Documents/Machine Learning/Hist-3',dpi = 800)
plt.show()
在matplotlib可视化中如果需要显示图例,要使用legend();要显示图形则需使用show()。
- 绘制直方图
条形图可以让我们很直观看到数据的大小,然而当我们需要去关注数据的分布情况时,直方图可能是一个更好的选择。直方图描述的是一组数据的频次分布,例如把年龄分成“0-5,5-10,……,80-85”17个组,统计一下中国人口年龄的分布情况,这样为我们就可以很直观的看到各个年龄段人数分布的情况。
matplotlib.pyplot.hist(data, bins, normed, facecolor, edgecolor, alpha)
参数 | 用法说明 |
---|---|
data | 必选参数,绘图数据 |
bins | 直方图的长条形数目,可选项,默认为10 |
normed | 是否将得到的直方图向量归一化,可选项,默认为0,代表不归一化,显示频数。normed=1,表示归一化,显示频率。 |
import numpy as np
import matplotlib.pyplot as plt
# 生成1000个服从标准正态分布的随机数据
data = np.random.randn(1000)
plt.figure(1,figsize =(8,4),dpi = 80)
plt.hist(data,bins = 50,normed = 1,alpha = 1,edgecolor = 'black')
plt.xlabel('intervak')
plt.ylabel('rate')
plt.title('Histogram')
plt.legend()
#将图片保存在指定目录
plt.savefig('/Users/wcjb/Documents/Machine Learning/Histgram',dpi = 800)
plt.show()
- 绘制饼图
pie(size, explode, colors, labels, labeldistance, autopct, shadow=False, startangle, pctdistance)
参数 | 用法说明 |
---|---|
explode | 设置各部分突出 |
label | 设置各部分标签 |
labeldistance | 设置标签文本距圆心位置,1.1表示1.1倍半径 |
autopct | 设置圆里面文本 |
shadow | 设置是否有阴影 |
startangle | 起始角度,默认从0开始逆时针转 |
pctdistance | 设置圆内文本距圆心距离 |
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 各部分标签
label_list = ["one", "two", "three"]
# 各部分比例大小
size = [55, 35, 10]
# 各部分颜色
color = ["red", "green", "blue"]
# 突出部分
explode = [0.05, 0, 0]
plt.pie(size, explode=explode, colors=color, labels=label_list, labeldistance=1.1, autopct="%1.1f%%", shadow=False, startangle=90, pctdistance=0.6)
# 设置横轴和纵轴大小相等,这样饼才是圆的,默认输出椭圆
plt.axis("equal")
plt.legend()
plt.savefig('/Users/wcjb/Documents/Machine Learning/pie',dpi = 800)
plt.show()
- 绘制对数坐标图
在matplotlib中有3个函数可以绘制对数坐标图,分别是:semilogx(),semilogy(),loglog(),它们分别表示对X轴,Y轴,XY轴取对数。
import numpy as np
import matplotlib.pyplot as plt
w=np.linspace(0.1,1000,1000)
p=np.abs(1/(1+0.1j*w))
plt.subplot(221)
plt.plot(w,p,lw=2)
plt.xlabel('X')
plt.ylabel('y')
plt.subplot(222)
plt.semilogx(w,p,lw=2)
plt.ylim(0,1.5)
plt.xlabel('log(X)')
plt.ylabel('y')
plt.subplot(223)
plt.semilogy(w,p,lw=2)
plt.ylim(0,1.5)
plt.xlabel('x')
plt.xlabel('log(y)')
plt.subplot(224)
plt.loglog(w,p,lw=2)
plt.ylim(0,1.5)
plt.savefig('/Users/wcjb/Documents/Machine Learning/log',dpi = 800)
plt.show()
subplot(i,j,k):在绘图对象中创建子图,相当于将画布分为个子图,在从左往右,从上到下的第k个子图上绘制当前图形。
- 绘制极坐标图
极坐标系中的点由一个夹角和一段相对于中心位置的距离来表示。要绘制极坐标图只需将plot()函数中的polar属性设为True便可。
import numpy as np
import matplotlib.pyplot as plt
theta=np.arange(0,2*np.pi,0.02)
plt.subplot(121,polar=True)
plt.plot(theta,2*np.ones_like(theta),lw=2)
plt.plot(theta,theta/6,'--',lw=2)
plt.subplot(122,polar=True)
plt.plot(theta,np.cos(5*theta),'--',lw=2)
plt.plot(theta,2*np.cos(4*theta),lw=2)
# 表示绘制半径为0.5 1.0 1.5的三个同心圆,同时将这些半径的值标记在45度位置的那个直径上面。
plt.rgrids(np.arange(0.5,2,0.5),angle=45)
# 表示在theta为0,45,90度的位置上标记上度数。
plt.thetagrids([0,45,90])
plt.savefig('/Users/wcjb/Documents/Machine Learning/1',dpi = 800)
plt.show()
- 绘制散点图
scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, hold=None, data=None, **kwargs)
参数 | 用法说明 |
---|---|
x | 横坐标取值 |
y | 纵坐标取值 |
s | 点的大小 |
c | 设置点的颜色,可以是一个二维数组,其中的行是RGB或RGBA |
maker | 指定绘图点的形状,0表示多边形,1表示是星型,2表示放射型,3表示圆形 |
alpha | 表示透明度 |
import matplotlib.pyplot as plt
import numpy as np
x = np.random.rand(1000)
y = np.random.rand(1000)
size = np.random.rand(1000) * 50
color = np.random.rand(1000)
plt.scatter(x, y, size, color)
#显示颜色渐变条
plt.colorbar()
plt.savefig('/Users/wcjb/Documents/Machine Learning/sample',dpi = 400)
plt.show()
- 绘制等高线
在机器学习中,有时会需要绘制梯度下降算法的图形,可使用等高线的方法来实现contour(x,y,f(x,y)):绘制等高线图,不进行填充
contourf(x,y,f(x,y),cmap=plt.cm.hot) :绘制等高线图并进行填充
import numpy as np
import matplotlib.pyplot as plt
def f(x, y):
return x**2+y**2+x*y
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)
X, Y = np.meshgrid(x, y)
#绘制等高线并进行填充
plt.contourf(X, Y, f(X, Y), 8, alpha=.75, cmap='jet')
#绘制等高线,不进行填充
C = plt.contour(X, Y, f(X, Y), 8, colors='black', linewidth=0.5)
#显示等高线
plt.clabel(C, inline=True, fontsize=12)
plt.show()
- 绘制曲线
plot(x,y,label,color,linewidth)
参数 | 用法说明 |
---|---|
x,y | 相应的横纵坐标数据 |
label | 图例 |
color | 线的颜色 |
linewidth | 指定线的宽度 |
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-10,10,200)
y = np.sin(x**2+2)
plt.plot(x,y,label='$sin(2x^2+2)$',color = 'blue',linewidth = 3)
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.savefig('/Users/wcjb/Documents/Machine Learning/sample',dpi = 400)
plt.show()
- 常用函数补充
函数 | 用法 |
---|---|
grid() | 参数为True时,在图形中显示网格线 |
text(x, y, s[, fontsize, color]) | 在坐标(x,y)显示文本s ,fontsize指定字体大小 |
annotate() | 对图片上某个点进行注释 |
xticks()/yticks() | 设置x,y轴的刻度标签值 |
spines() | 移动坐标轴 |
axis([x1,x2,y1,y2]) | 同时设置x轴和y轴的范围 |
gca() | 返回当前axes(matplotlib.axes.Axes) |
gcf() | 返回当前figure(matplotlib.figure.Figure) |
clf() | 清理当前figure |
cla() | 清理当前axes |
close() | 一副figure直到显式的调用close()时才会释放她所占用的资源; |
防止绘制大量图片时内存占用过高
- 一些有趣的实例
import numpy as np
import matplotlib.pyplot as plt
n = 8
#生成二维数组
X, Y = np.mgrid[-n:n, -n:n]
color = np.random.rand(2*n)+3
#绘制一个二维方向场域
plt.quiver(Y,X,color)
plt.title('A 2-D field of arrows')
plt.colorbar()
plt.savefig('/Users/wcjb/Documents/Machine Learning/arrows')
plt.show()
np.mgrid[start:end:step]:生成二维数组,start:开始坐标,stop:结束坐标(不包括,step:步长,默认为1。
import numpy as np
X,Y=np.mgrid[-4:4,-3:3]
print(X,'\n\n',Y)
quiver(U,V,X,Y,C):U和V是箭头数据,X和Y设置箭头的位置,C设置箭头的颜色。这些参数可以是1-D或2-D阵列或序列。
# 根据实时数据进行图形动态更新
from time import sleep
from threading import Thread
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
#同时创建子图和子图网格,即同时建立一个fig对象和axis对象,subplot()只能创建子图网格
fig,ax = plt.subplots()
#设置图形的显示位置
plt.subplots_adjust(bottom = 0.2)
#实验数据
range_start,range_end,range_step = 0,1,0.005
t = np.arange(range_start,range_end,range_step)
s = np.sin(4*np.pi*t)
l,= plt.plot(t,s,lw = 2)
#自定义类,用于封装两个按钮的单击事件处理函数
class ButtonHandler:
def __init__(self):
self.flag = True
self.range_s,self.range_e,self.range_step = 0,1,0.005
#线程函数,用于更新数据并重新绘制图形
def threadStart(self):
while self.flag:
sleep(0.02)
self.range_s += self.range_step
self.range_e += self.range_step
t = np.arange(self.range_s,self.range_e,self.range_step)
ydata = np.sin(4*np.pi*t)
# 更新数据
l.set_xdata(t-t[0])
l.set_ydata(ydata)
# 重新绘制图形
plt.draw()
def Start(self,event):
self.flag = True
# 创建并启动新进程
t = Thread(target = self.threadStart)
t.start()
def Stop(self,event):
self.flag = False
callback = ButtonHandler()
# 创建按钮并设置单击事件处理函数
axprev = plt.axes([0.81,0.05,0.1,0.075])
bprrev = Button(axprev,'Stop')
bprrev.on_clicked(callback.Stop)
axnext = plt.axes([0.7,0.05,0.1,0.075])
bnext = Button(axnext,'Start')
bnext.on_clicked(callback.Start)
plt.show()