Matplotlib数据可视化
mat = matrix 矩阵;二维数组
plot 画图
lib = library 库
一、基础操作和知识
#pyplot模块中包括了一系列在当前图形的当前坐标系画图的函数
import matplotlib.pyplot as plt
%matplotlib inline
#创建画布,开辟一块内存装东西
plt.figure()
#画图,第一个传入的序列是横坐标,第二个序列是纵坐标
plt.plot([1,0,9],[4,5,6])
#显示图像(这里是个折线图)
plt.show()

三层结构
1)容器层
- 画板层 Canvas:
隐式创建,打开就有 - 画布层 Figure:
显式创建,plt.figure(),上面可以有多个绘图区 - 绘图区/坐标系 Axes:
①如未显式创建,默认有一个,显式创建时使用plt.subplots()
②每个绘图区有横纵坐标(两个axis)
③辅助显示层和图像层都在绘图区上
2)辅助显示层
- 使图像更加易懂,方便观察理解(比如网格横线等)
3)图像层
- 每个绘图区可以画不同的图
- 画图是在图像层上画
二、折线图
一周的气温折线图
#创建画布
plt.figure()
#绘制图像
plt.plot([1,2,3,4,5,6,7],[17,17,18,15,11,11,13])
#显示图像
plt.show()

1、设置画布属性和保存图片
plt.figure(figsize=(20,8), dpi=80)
figsize:指定图的长宽
dpi:图像清晰度
plt.save(path)
保存图像(一定要用在show之前,否则保存的是空的,因为show函数会释放图像资源)
2、辅助显示层上的优化功能
e.g.画出某城市11-12点每分钟的温度变化
import random
#准备数据
x = range(60)#生成代表60分钟的列表
#生成一个60个元素的随机的从15到18正态分布的列表作为气温
y_shanghai = [random.uniform(15,18) for i in x]
#三步画图
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y_shanghai)
plt.show()

1)这个时候可以看到Y轴的刻度不太合适,看起来波动很大,X轴也没显示成11点多少,继续优化
plt.xticks(x, **kwargs)
x是要显示的刻度值,传入一个列表
plt.yticks(y, **kwargs)
y是要显示的刻度值,传入一个列表
对上图的修改:
import random
#准备数据
x = range(60)#生成代表60分钟的列表
#生成一个60个元素的随机的从15到18正态分布的列表作为气温
y_shanghai = [random.uniform(15,18) for i in x]
#画图
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y_shanghai)
#坐标优化
#
#创建格式化字符串来作为横坐标标签(用于修饰原来的坐标)
#对坐标和坐标的标签都用切片使步长为5
xLabel = ["11点{}分".format(i) for i in x]
plt.xticks(x[::5], xLabel[::5])
#可用range生成0~40的列表再切片设置步长为5
#也可直接用range设置步长为5作为坐标,效果一致
plt.yticks(range(0,40,5))
plt.show()

2)没有中文,需要增加字体(windows的方法)
①下载安装simhei字体(直接网上搜)
②删除matplotlib缓存文件:
C:\Users\Username.matplotlib下删除
③修改E:\Anaconda\envs\tfgpu\Lib\site-packages\matplotlib\mpl-data\matplotlibrc(我自己是在ananconda里的虚拟环境里做的,如果装在原装python上的话,你就去python的根目录里找),更改几项:
font.family : sans-serit
font.sans-serit : SimHei
axes.unicode_minus : False
3)增加网格显示和文字描述
#网格显示
plt.grid(linestyle="--", alpha=0.5)
#描述信息
plt.xlabel("时间变化")
plt.ylabel("温度变化")
plt.title("上海11点到12点每分钟的温度变化状况")
3、图像层的优化
1)添加一个新的城市,一图两线
#添加北京当日的温度变化情况,温度在1~3°C
#准备北京的数据
#画图
y_beijing = [random.uniform(1,3) for i in x]
plt.plot(x, y_beijing)
现在修改后的代码是:
import random
#准备数据
x = range(60)#生成代表60分钟的列表
#生成60个元素的随机的正态分布的列表作为气温
y_shanghai = [random.uniform(15,18) for i in x]
y_beijing = [random.uniform(1,3) for i in x]
#画图
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y_shanghai)#上海的线
plt.plot(x,y_beijing)#北京的线
#坐标优化
#
#创建格式化字符串来作为横坐标标签(时间)
#用切片方式使步长为5并作为坐标的标签
xLabel = ["11点{}分".format(i) for i in x]
plt.xticks(x[::5], xLabel[::5])
#可用range生成0~40的列表再切片设置步长为5
#也可直接用range设置步长为5作为坐标,效果一致
plt.yticks(range(0,40,5))
#网格显示
plt.grid(linestyle="--", alpha=0.5)
#描述信息
plt.xlabel("时间变化")
plt.ylabel("温度变化")
plt.title("上海和北京11点到12点每分钟的温度变化状况")
plt.show()

2)可以在plot函数里增加参数更改绘制折线的颜色和风格
颜色风格参数可查点击链接
plt.plot(x, y, color='red',linestyle="--")
#绘制红色的虚线

3)也可显示图例(默认右上角)
调整图例位置参见点击链接
#先在plot函数里增加label
plt.plot(x, y_shanghai, color='red',linestyle="--", label="上海")
plt.plot(x, y_beijing, label = "北京")
#再在辅助显示层上显示图例(legend有图例的意思)
plt.legend()

4)多个坐标系显示plt.subplots(面向对象的画图方法)
需求:把北京上海显示到两张图上
默认是一行一列,即一张图
函数会返回一个图像和绘图区列表
#plt.subplots(nrows=1, ncols=1, **flg_kw)
创建一行两列两张图
figure, axes = plt.subplots(nrows=1, ncols=2, **flg_kw)
不能用之前那样的plt.[函数名]来画图了,需要用绘图区的面向过程的画图方法axes.set_方法名()来操作 (参考文档点击链接)
代码修改了一些部分
import random
#准备数据
x = range(60)
y_shanghai = [random.uniform(15,18) for i in x]
y_beijing = [random.uniform(1,3) for i in x]
#创建两个子图
figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=80)
#第一个绘图区画上海,第二个绘图区画北京
axes[0].plot(x,y_shanghai, color='red', linestyle='--', label="shanghai")
axes[1].plot(x,y_beijing, label="beijing")
#两图坐标优化,要加上set_
xLabel = ["11min{}sec".format(i) for i in x]
axes[0].set_xticks(x[::5])#只有两个参数,ticks和minor,不能用来改label
axes[0].set_xticklabels(xLabel[::5])#需要新用这个函数来改label
axes[0].set_yticks(range(0,40,5))
axes[1].set_xticks(x[::5])
axes[1].set_xticklabels(xLabel[::5])
axes[1].set_yticks(range(0,30,5))
#显示两个图的图例
axes[0].legend()
axes[1].legend()
#两个网格显示
axes[0].grid(linestyle="--", alpha=0.5)
axes[1].grid(linestyle="--", alpha=0.5)
#两图描述信息,要加set_
axes[0].set_xlabel("时间变化")
axes[0].set_ylabel("温度变化")
axes[0].set_title("上海11点到12点每分钟的温度变化状况")
axes[1].set_xlabel("时间变化")
axes[1].set_ylabel("温度变化")
axes[1].set_title("北京11点到12点每分钟的温度变化状况")
plt.show()

5)折线图应用场景
- 显示某指标随时间的变化状况
- 可以画数学函数图像
import numpy as np
#准备数据
#准备-10~10间的1000个数
x = np.linspace(-10, 10, 1000)
y = np.sin(x)
#画图
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(x, y)
plt.grid(linestyle='--',alpha=0.5)
plt.show()

三、散点图
- 场景:画出坐标点,判断变量之间是否有关联趋势,展示离群点(分布规律)
- 需求:探求房屋面积和价格间的规律 画图时用plt.scatter(x, y)
#数据
x = [225.98, 247.07, 253.14, 457.85, 241.58, 301.01, 20.67, 288.64,
163.56, 120.06, 207.83, 342.75, 147.9 , 53.06, 224.72, 29.51,
21.61, 483.21, 245.25, 399.25, 343.35]
y = [196.63, 203.88, 210.75, 372.74, 202.41, 247.61, 24.9 , 239.34,
140.32, 104.15, 176.84, 288.23, 128.79, 49.64, 191.74, 33.1 ,
30.74, 400.02, 205.35, 330.64, 283.45]
plt.figure(figsize=(20,8), dpi=80)
#画图
plt.scatter(x, y)
plt.show()

四、柱状图
-
数量统计或者对比数量的时候使用
-
画图用plt.bar(x, y, width, align=‘center’, **kwargs)
-
需求1:对比每部电影的票房收入
#准备数据
movie_name = ['Talk to the moon', 'Let it go', 'Global storm', 'chicken you very beautiful', 'kungfu chick']
tickets = [73853, 57767, 8725, 99999, 42412]
xticks = range(len(movie_name))#横轴坐标的数字形式
#画布
plt.figure(figsize=(20,8), dpi=80)
#绘制柱状图
#width是指占一整块的比例,为1时所有矩形连在一起
#颜色以列表按顺序传入
plt.bar(xticks, tickets, width=0.3, color=['b','r','g','y','c'])
#修改x的刻度为名称
plt.xticks(xticks, movie_name)
#增加标题和网格
plt.title('Movie tickets rank')
plt.grid(linestyle='--', alpha=0.5)
plt.show()

- 需求2:对比相同天数的票房
#准备数据
movie_name = ['Talk to the moon', 'Let it go', 'Global storm', 'chicken you very beautiful', 'kungfu chick']
firstday_tickets = [73853, 57767, 8725, 99999, 42412]
weekend_tickets = [140000, 234441, 55323, 65634, 43532]
xticks = range(len(movie_name))#横轴坐标的数字形式
#画布
plt.figure(figsize=(20,8), dpi=80)
#绘制两个柱状图(第一个和第二个图的第一个参数(横坐标的数字形式)要错开数值)
plt.bar(xticks, firstday_tickets, width=0.3)
plt.bar([xticks[i]+0.3 for i in xticks], weekend_tickets, width=0.3)
#修改x的刻度为名称
plt.xticks(xticks, movie_name)
#增加标题和网格
plt.title('Movie tickets rank')
plt.grid(linestyle='--', alpha=0.5)
plt.show()

五、直方图
- 对数据的分组,然后统计每组内的数据元数量
- 组数:数据按照不同范围分了几个组,分成组的个数是组数
组距:每一组两个端点的差 - 直方图展示的是数据的分布,柱状图比较的是数据的大小
- plt.hist(x, bins=None, density=None, **kwargs)
x是数据的序列,bins是组数,density纵坐标是否显示为频率而不是频数
time = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]
x = time
distance = 2#组距
bins = int((max(time) - min(time)) / distance)
plt.figure(figsize=(20,8), dpi=80)
plt.hist(x, bins)
plt.xticks(range(min(x), max(x), distance) )
plt.grid(linestyle='--',alpha=0.5)
plt.title('the length of movies')
plt.xlabel("length of time")
plt.ylabel("number of movies")
plt.show()

六、饼图
- 观察比例
- 类别太多时不用饼图,用柱状图
- plt.pies(x, labels=, autopct=, colors=)
x是数据的序列,labels是每部分的名称,autopct可使占比显示指定为%1.2f%%,colors颜色
#准备数据
movie_name = ['Talk to the moon', 'Let it go', 'Global storm', 'chicken you very beautiful', 'kungfu chick']
tickets = [73853, 57767, 8725, 99999, 42412]
#画布
plt.figure(figsize=(20,8), dpi=80)
#绘制饼图
plt.pie(tickets, labels=movie_name, colors=['b','r','g','y','c'], autopct="%1.2f%%" )
#axis可以调整饼图的角度
plt.axis('equal')#圆形
#增加标题和网格
plt.title('Movie tickets rank')
#增加图例
plt.legend()
plt.show()

本文详细介绍了使用Matplotlib进行数据可视化的基础知识,包括折线图、散点图、柱状图、直方图和饼图的绘制方法。通过实例展示了如何设置画布属性、优化坐标轴、添加图例及网格,以及如何利用面向对象的方式创建多个坐标系。

2954

被折叠的 条评论
为什么被折叠?



