4 matplotlib数据可视化基础
- 安装----- 在cmd中把路径调整到python的安装目录(D:可以跳转磁盘区,cd python可以跳转到python的文件夹),然后输入python -m pip install matplotlib即可安装最新版本的matplotlib。
- 测试----- cmd跳转到python文件夹,输入import matplotlib 无错误即安装成功。
参考内容:
官方教程:matplotlib.Tutorials
Matplotlib教程(非常详细)
动图参考博客-Matplotlib 画动态图: animation模块的使用
4.1 matplotlib画布和子图属性
4.1.1 区分画布和子图(figure and axes)
官方给出的示例:
画布(figure):一般用fig表达,一个画布就是一个matplotlib显示的绘图窗口,画布上可以有多个子图(axes)
子图(axes):一般用ax表达(ax = plt.gca()
),子图作用在指定的画布上, figure.add_subplot
(行,列,索引位置)的方式添加子图。注意由:fig,ax = plt.subplots(m,n)
创建出来的fig是唯一的而ax为二维列表,通过ax[i,j]
依次可以指定子图内容和属性。
二者关系如图所示:
import matplotlib.pyplot as plt
import numpy as np
fig_a = plt.figure() # 创建画布fig_a
fig_b,ax_b = plt.subplots() # 创建画布fig_b,同时包含一个子图ax_b
plt.show() # 显示所有的画布
例如,为上诉的fig_a添加子图,如下所示:
import matplotlib.pyplot as plt
import numpy as np
fig_a = plt.figure() # 创建画布fig_a
fig_b,ax_b = plt.subplots() # 创建画布fig_b,同时包含一个子图ax_b
ax_a = fig_a.add_subplot(1,2,1) # 在画布fig_a里添加一个子图
plt.show() # 显示所有的画布
4.1.2 画布和子图常用属性
1)共用坐标轴:关键字sharex和sharey可以设置画布/子图共用XY轴,如下所示:
import matplotlib.pyplot as plt
import numpy as np
fig_a = plt.figure()
ax_a1 = fig_a.add_subplot(1,2,1)
# 子图2共用子图1的坐标轴
ax_a2 = fig_a.add_subplot(1,2,2,sharex = ax_a1,sharey = ax_a1)
# 画布全部共用坐标轴
fig_b,ax_b = plt.subplots(2,2,sharex = True,sharey = True)
plt.show()
2)设置画布的标题:fig.suptitle()
,其中画布的其他属性可以在figure打开之后的按钮中进行设置。
3)plt函数对画布和子图属性修改习惯:单个画布显示单个图形时候,plt就只作用在这子图上,而多个子图时,子图属性采用plt.xxx进行设置,需要注意plt函数对图像的修改是有先后顺序的(即子图都用plt.title()设置子图名,然而对于子图的子图名需要在其后面调用该函数,和MATLAB类似操作习惯是一样的),而在for循环里使用plt最后只作用一次。
import matplotlib.pyplot as plt
import numpy as np
plt.rc('font',family='SimHei') # 放在后面则中文显示失败,plt函数对图像的改变是有先后顺序的
fig,ax = plt.subplots()
fig.suptitle('我是画布的标题', fontsize = 20)
ax1 = fig.add_subplot(1,2,1)
plt.title("我是第1个子图") # 作用给第1个子图
ax2 = fig.add_subplot(1,2,2)
plt.title("我是第2个子图") # 作用给第2个子图
plt.show()
在for循环使用plt修改子图属性:
import matplotlib.pyplot as plt
import numpy as np
plt.rc('font',family='SimHei') # 放在后面则中文显示失败,plt函数对图像的改变是有先后顺序的
fig,ax = plt.subplots(2,2,sharex=True,sharey=True)
fig.suptitle('我是画布的标题', fontsize = 20)
for i in range(2):
for j in range(2):
# ax[i,j].plot(i,j)
plt.title(str(i) + ' & ' + str(j),fontsize = 10)
plt.show()
4)plt设置基本属性:
5)子图ax(plt.gca())设置基本属性:
例子:创建一个画布,上有两个子图,子图1绘制x和x平方图形,右图绘制sinx图形,并设置属性,主要在于注意绘图的一般思路
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
# 1、中文设置
plt.rcParams['font.family'] = ['SimHei'] # 用于显示中文
plt.rcParams['axes.unicode_minus'] = False # 用于解决保存图像是负号‘-’显示为方框的问题
# 2、创建画布
fig = plt.figure() # 创建画布
# 3、绘制子图
# 左边y=x和y=x*x图像在一张子图上
ax1 = fig.add_subplot(1,2,1) # 创建子图1
x1 = [1,2,3,4,5]
y1 = [1,2,3,4,5]
y2 = [1,4,9,16,25]
ax1.plot(x1,y1,'r')
ax1.plot(x1,y2,'b') # 两个图像绘制在一个子图上
# 右边绘制 y = sinx图像
ax2 = fig.add_subplot(1,2,2) # 创建子图2
x2 = np.arange(-np.pi,np.pi,0.01)
y2 = np.sin(x2)
ax2.plot(x2,y2,'b')
# 4、依次设置子图属性
ax1.set_title("子图1,y=x和y=x*x图像") # 创建标题
ax2.set_title("子图1,y=sinx图像")
ax1.set_xlabel("x") # 设置坐标轴标签
ax1.set_ylabel("y=x and y=x*x")
ax2.set_xlabel("x")
ax2.set_ylabel("y=sinx")
ax1.set_xlim([0,6]) # 设置坐标轴范围,坐标轴范围决定显示图的尺寸
ax1.set_ylim([0,26])
ax2.set_xlim([-4,4])
ax2.set_ylim([-1,1])
ax1.set_xticks(np.arange(6)) # 设置刻度,刻度和范围不一样
ax2.set_xticks(np.linspace(-np.pi,np.pi,4))
plt.show()
6)pyplot的动态rc参数:rc参数包括设置绘图过程中线条颜色、线条粗细、线条节点形状等等,不同的绘图函数有不同的rc重载形式,上面的plt.rcParams['font.family'] = ['SimHei']
也属于rc参数的一种,rc一般在绘图时候再函数体内指定如下面代码:plt.plot([1,2,3],[1,2,1],'bs',[1,2,3],[1,2,1],'r')
则绘制了折线图并且打点为蓝色小方块。
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
plt.plot([1,2,3],[1,2,1],'bs',[1,2,3],[1,2,1],'r')
plt.show()
4.2 绘制基本图形的命令
4.2.1 折线图
折线图基础命令----- plt.plot(X坐标数组,Y坐标数组,rc属性=……)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
plt.show()
4.2.2 散点图
散点图基础命令----- plt.scatter(X坐标数组,Y坐标数组,rc属性=…….)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
# s设置点的大小
plt.scatter([1,2], [4,9], c = ['b','r'], s = [50,100])
plt.show()
4.2.3 柱状图
柱状图基本命令----- plt.bar(X, Y, rc=…)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
plt.bar(['a','b','c'], [10,20,30])
plt.show()
4.2.4 直方图
绘制直方图基本命令----- plt.hist(序列, X值范围, rc参数=…)
,例如随机统计某班上所有同学成绩直方图, X划分为0-10分,10-20分,20-30分…90-100分10个阶段,Y轴表示成绩在分段的统计个数(hist会自发统计序列各个分段的个数),序列为所有学生成绩
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
scores = np.random.randint(0,100,10)
plt.hist(scores,[0,10,20,30,40,50,60,70,80,90,100])
plt.show()
4.2.5 饼状图
绘制饼状图基本命令----- plt.pie(序列,rc参数=…)
,pie函数会自发统计序列的占比,形成饼状图。
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
plt.pie([1,3,1,5])
plt.show()
4.2.6 文本文字
绘制文本文字基本命令----- plt.text(X坐标位置, Y坐标位置, 文本内容, 其他rc参数=…)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
plt.text(1,1,"hello")
plt.axis([0,2,0,2])
plt.show()
4.3 绘制其他图像命令
4.3.1 绘制几何形状
导入包import matplotlib.patches as pc
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpathes
fig,ax = plt.subplots()
xy1 = np.array([0.2,0.2])
xy2 = np.array([0.2,0.8])
xy3 = np.array([0.8,0.2])
xy4 = np.array([0.8,0.8])
#圆形
circle = mpathes.Circle(xy1,0.05)
ax.add_patch(circle)
#长方形
rect = mpathes.Rectangle(xy2,0.2,0.1,color='r')
ax.add_patch(rect)
#多边形
polygon = mpathes.RegularPolygon(xy3,5,0.1,color='g')
ax.add_patch(polygon)
#椭圆形
ellipse = mpathes.Ellipse(xy4,0.4,0.2,color='y')
ax.add_patch(ellipse)
plt.show()
4.3.2 绘制热力图
绘制热力图方法一:ax.imshow(数据,色域,范围min,范围max)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
# 色阶 一共八个内容对应不同颜色
cmap = colors.ListedColormap(
['none', 'white', 'black', 'red', 'yellow', 'magenta', 'green', 'cyan', 'blue'])
# 绘图函数
fig, ax = plt.subplots()
filed = [[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[4, 1, 2, 1, 5],
[1, 1, 2, 1, 1]]
# 绘制热力图
# 其中vmin和vmax对应栅格地图数值的颜色与cmap一一对应
colorbar = ax.imshow(filed, cmap=cmap, vmin=0, vmax=8)
fig.colorbar(colorbar, ax=ax, extend='both')#注释即可关闭色条
plt.show()
方式二采用seaborn的函数heatmap---- seaborn.heatmap(数据,色域,…)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
import seaborn as sns
# 色阶 一共八个内容对应不同颜色
cmap = colors.ListedColormap(
['none', 'white', 'black', 'red', 'yellow', 'magenta', 'green', 'cyan', 'blue'])
# 绘图函数
fig, ax = plt.subplots()
filed = [[1, 1, 1, 1, 1],
[1, 1, 2, 1, 1],
[4, 1, 2, 1, 5],
[1, 1, 2, 1, 1]]
# 绘制热力图
# 其中vmin和vmax对应栅格地图数值的颜色与cmap一一对应
sns.heatmap(filed, cmap = cmap,vmin = 0,vmax = 8, linewidths = 1.5, linecolor= 'black', ax = ax, cbar = False)
plt.show()
4.3.2 绘制动图
方法一:采用for循环联合plt.pause()进行绘制动态效果
import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib import animation
fig, ax = plt.subplots()
x = [1]
y = [2]
ax.axis([0,10,0,30])
for i in range(200):
plt.scatter(x,y,s=10,c='k')
plt.pause(0.01)
x.append(random.randint(0,10))
y.append(random.randint(0,30))
plt.show()
方法二:通过animation.FuncAnimation绘制动图
首先导入包:from matplotlib import animation
关键函数----- animation.FuncAnimation(fig,func,frames,init_func,interval,blit)
其中参数的含义:
- fig:绘制动图的画布名称
- func:自定义动画函数,有一个形参,存放frames传来的值
- frames:动画长度,一次循环包含的帧数,在函数运行时,其值会传递给函数func,因此func有一个形参
- init_func:自定义开始帧,即传入刚定义的函数init,初始化函数
- interval:更新频率,以ms计
- bli:选择更新所有点,还是仅更新产生变化的点,默认为True
默认函数执行顺序
例子:在折线图上实现点依次跳跃的动图,**以frames为一个序列时**的操作方法。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
fig, ax = plt.subplots()
x = [1,2,3,4,5,6,7,8]
y = [2,1,2,1,2,1,2,1]
# 绘制动图的图像,但是此时内部数据是空的
dynamic_ax, = ax.plot([],[],'ro')
'''
初始化函数,在动图函数最先执行的操作
返回值可以使用某个图像作为背景板
'''
def init():
ax.set_xlim(0, 9)
ax.set_ylim(0, 3)
return ax.plot(x, y,'b')
'''
更新操作,在动画执行时候,会将frames循环的内容作为参数传入
'''
def update_frame(frames):
dynamic_ax.set_data(x[frames], y[frames])
return dynamic_ax,
ani = animation.FuncAnimation(fig, update_frame, frames = np.arange(8), interval = 100, init_func = init)
ani.save('test.gif', writer='pillow', fps = 500)
plt.show()
以:frames为一个函数操作时候,利用yeild迭代器操作
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
fig, ax = plt.subplots()
x = [1,2,3,4,5,6,7,8]
y = [2,1,2,1,2,1,2,1]
# 绘制动图的图像,但是此时内部数据是空的
dynamic_ax, = ax.plot([],[],'ro')
n = 0
'''
初始化函数,在动图函数最先执行的操作
返回值可以使用某个图像作为背景板
'''
def init():
ax.set_xlim(0, 9)
ax.set_ylim(0, 3)
return ax.plot(x, y,'b')
def add_frame():
for frames in range(8):
yield frames
'''
更新操作,在动画执行时候,会将frames循环的内容作为参数传入
'''
def update_frame(frames):
dynamic_ax.set_data(x[frames], y[frames])
return dynamic_ax,
ani = animation.FuncAnimation(fig, update_frame, frames = add_frame, interval = 100, init_func = init)
ani.save('test.gif', writer='pillow', fps = 500)
plt.show()