Python机器学习及分析工具:Matplotlib篇


  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()
Hist-0

  • 例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()
Hist-1

  • 例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()
Hist-2

  • 例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()
Hist-3

在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()

pie

  • 绘制对数坐标图
      在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()
log

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()
arrows

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()
数据动态更新

你可能感兴趣的:(Python机器学习及分析工具:Matplotlib篇)