文章目录
前言
今天笔者正式接触到了Matplotlib,如何快速上手Matplotlib其实不多难,网上也有海量的资源可供我们去认真学习;在这里笔者就简单介绍一下Matplotlib(建议最好使用jupyter notebook)😊
一、Matplotlib是什么?
简单的说Matplotlib是一个画二维图表的一个python模块,也可以理解成它是低配版的matlab。在我们处理数据的时候,图表往往更能直观的反应数据的信息,笔者也是刚上手Matplotlib,在这里介绍几个常用的二维图表帮助大家快速上手Matplotlib。
二、Matplotlib
1.引入
一个简单例子:
import matplotlib.pyplot as plt # 整个matplotlib画图都要添加这个模块
plt.figure() # 画图在画布上画、这一步就是创建画布
plt.plot([1, 2, 3], [2, 4, 6])
# 开始画图,两个参数(都是列表)第一个是x轴,第二个是y轴
plt.show() # 呈现图
2.认识Matplotlib
上手其实不多难,就是直接调用API即可。
我们用画图工具的时候,首先呢要先创建一个画布;之后都是基于该画布上绘图。
(1).基本步骤:
1、导入Matplotlib模块;
2、准备数据;
3、创建画布;
......这里可以设置一些属性......
4、绘制图像;
5、显示图像
将上面的例子规格化:
# 1、导入Matplotlib模块
import matplotlib.pyplot as plt
# 2、准备数据
x = [1, 2, 3]
y = [2, 4, 6]
# 3、创建画布
plt.figure()
# 4、绘制图像
plt.plot(x, y)
# 5、显示图像
plt.show()
(2).Matplotlib三层结构
1、容器层
画板层(canvas)
画布层(figure):plt.figure()
绘图区/坐标系(可以创建多个绘图区)(axis) plt.subplots()
2、辅助显示层
可以设置:外观、边框、坐标轴、刻度、刻度标签、网格线、图例、标题等等…
3、图像层
能够呈现:折线图(plot)、散点图(scatter)、直方图(bar)、柱状图(histogram)、饼图(pie)等等。
canvas 位于最底层,用户一般接触不到;
figure 建立在canvas之上;
axes建立在figure之上;
坐标轴、图例等辅助显示层以及图像层都是建立在axes之上。
单看定义其实很笼统。我们直接实操。
3.Matplotlib常用的一些图表
(1).折线图
在上述的那个例子其实就是一个简单的折线图;
折线图关键字:plot;
plot就是将x,y 这些坐标点用线段连接起来
这里我们举一个小例子
1):朴素版折线图
只是单纯将数据以折线图的形式呈现出来。
# 绘制简单折线图
# 展示甲城市一周的天气温度(周一到周日)
import matplotlib.pyplot as plt
# 1)、准备数据
x = [1, 2, 3, 4, 5, 6, 7]
y = [20, 30, 35, 18, 25, 31, 40]
# 2)、创建画布(容器层)
plt.figure()
# 3)、绘制图像
plt.plot(x, y)
# 4)、显示图像
plt.show()
2):添加属性的折线图
①:设置画布属性与图片保存
画布属性:
figsize:画布大小(长,宽);
dpi:图像的清晰度。
eg.plt.figure(figsize=(20, 8), dpi=80) 这样长20,宽(高)8;透明度80%
图片保存:
调用savefig(path)
参数就是路径
# 上述的例子,展示城市一周的天起变化
import matplotlib.pyplot as plt
# 准备数据
x = [1, 2, 3, 4, 5, 6, 7]
y = [20, 30, 35, 18, 25, 31, 40]
# 创建画布(容器层) 设置画布属性
plt.figure(figsize=(20, 8), dpi=80) # figsize:画布大小; dpi:图像的清晰度;自己拟定
# 绘制图像
plt.plot(x, y)
# 保存图像
plt.savefig('../OneDrive/test.png') # 参数就是路径;可以去该路径下检查是否存在该文件
# 显示图像
plt.show()
ps: 保存图像必须在显示图像show之前保存,否则图片为空白;这是因为我们调用show,会释放画图的所有资源。
换一个例子;需求:画出城市11点到12点1小时内每分钟的温度变化折线图,温度范围在18度-35度
1、朴素版
# 城市11点到12点1小时内每分钟的温度变化折线图,温度范围在18度-25度
import matplotlib.pyplot as plt
import random
# 1、准备数据x, y
x = range(60)
y = [random.uniform(18, 25) for i in x] # 列表生成式
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制图像
plt.plot(x, y)
# 4、显示图像
plt.show()
我们可以看到绘制出来的图像非常的不好看😫
2、现在我们开始来针对这个例子进行完善
②:完善折线图(辅助显示层)
1、添加自定义x,y的刻度;
plt.xticks(x, **kwargs)
plt.yticks(y, **kwarge)
第一个参数是要显示的刻度值;
第二个参数就是一个列表。
2、添加网格;
为了更加清楚地观察图形对应的值 plt.grid(True, linstyle='--', alpha=0.5)
第一个参数:是否添加显示网格;
第二个参数:线条风格;
第三个参数:透明度。
3、添加描述信息;
可以添加x轴、y轴描述信息
plt.xlabel();
plt.ylabel()
可以添加标题
plt.title()
4、在这里一定要注意:如果字符串参数里面存在中文或负号,不处理的话,会显示乱码,并且还会有警告。
这里我们用这两句语句:
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
import matplotlib.pyplot as plt
import random
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据x, y
x = range(60)
y = [random.uniform(18, 25) for i in x] # 列表生成式
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制图像
plt.plot(x, y)
# 修改x、y的刻度
# 准备x的刻度说明
x_label = ["11点{}分".format(i) for i in x] # 列表生成式,针对x刻度的说明
plt.xticks(x[::5], x_label[::5]) # x刻度和x刻度说明,设置前后相差5步
plt.yticks(range(0, 40, 5)) # y刻度,设置前后相差5步
# 添加网格显示
plt.grid(True, linestyle="--", alpha=0.5) # 第一个参数代表是否添加网格,第二个参数表示线条风格, 第三个参数代表透明度
# 添加描述信息
plt.xlabel("时间变化") # x轴描述信息
plt.ylabel("温度变化") # y轴描述信息
plt.title("某城市11点到12点每分钟温度的变化") # 标题描述信息
# 4、显示图像
plt.show()
这样的话就有内味了🤭
③:完善折线图(图像层)
a:添加多条折线
在一个坐标系上,添加多个折线图
其实就是多次调用polt即可
针对上一个例子进行修改
# 再添加一个城市的温度变化
import matplotlib.pyplot as plt
import random
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据x, y
x = range(60)
y1 = [random.uniform(15, 18) for i in x]
y2 = [random.uniform(1, 3) for i in x] # 多添加一条数据
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制图像
plt.plot(x, y1, color="r", linestyle="--")
plt.plot(x, y2, color="b", linestyle="-") # 绘制图像时多调用一次plot,为了区别新添加的这个折线设置为实线,颜色设为blue
# 修改x、y的刻度
# 准备x的刻度说明
x_label = ["11点{}分".format(i) for i in x]
plt.xticks(x[::5], x_label[::5])
plt.yticks(range(0, 40, 5))
# 添加网格显示
plt.grid(True, linestyle="--", alpha=0.5)
# 添加描述信息
plt.xlabel("时间变化")
plt.ylabel("温度变化")
plt.title("城市11点到12点每分钟温度的变化")
# 4、显示图像
plt.show()
这样另外一条折线就成功的呈现出来了。
但是似乎还是有些不足,我们平常见到的多个折线的时候,一般都会有说明的(即图例)
b:添加图例
import matplotlib.pyplot as plt
import random
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据x, y
x = range(60)
y1 = [random.uniform(15, 18) for i in x]
y2 = [random.uniform(1, 3) for i in x]
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制图像
plt.plot(x, y1, color="r", linestyle="--", label="甲") label就是标签,对折线的说明
plt.plot(x, y2, color="b", linestyle="-", label="乙")
# 要在辅助显示层显示图例
# plt.legend() # 不设置loc参数,默认应该是在右上方
# 可以设置图例的位置
plt.legend(loc="lower left") # loc属性就是位置属性可以设置图例在图像的位置
# 修改x、y的刻度
# 准备x的刻度说明
x_label = ["11点{}分".format(i) for i in x]
plt.xticks(x[::5], x_label[::5])
plt.yticks(range(0, 40, 5))
# 添加网格显示
plt.grid(True, linestyle="--", alpha=0.5)
# 添加描述信息
plt.xlabel("时间变化")
plt.ylabel("温度变化")
plt.title("城市11点到12点每分钟温度的变化")
# 4、显示图像
plt.show()
c:添加多个绘图区(面向对象)
要用到面向对象
多个坐标系显示:plt.subplots(面向对象的画图方法)
plt.pyplot.subplots(nrows, ncols, **flag_kw) 创建一个带有多个axes(坐标系、绘图区)
第一个参数:几行;
第二个参数:几列;
后面可以设置其他的属性
之前介绍都是面向过程的plot绘图方法,其实大差不差;就是和面向对象使用的一些方法不太一样。
比如创建画布就和面向过程的不一样:
面向过程:plt.figure(figsize=(20, 8), dpi=80);
面向对象:figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=80);
在这里面向对象返回了两个实例化对象:一个是画布(figure);一个绘图区对象(axes)。
还有就是调用的一些方法不一样:
面向过程:plt.函数名();
面向对象:axes.set_方法名()。
其中绘图区对象可以理解成对象数组。
下面我们来看一个例子:
# 创建一个一行两列
# 用面向对象其实和面向过程就是方法不一样
# plt.函数名()相当于面向过程的画图方法,
# axes.set_方法名()相当于面向对象的画图方法
import matplotlib.pyplot as plt
import random
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据x, y
x = range(60)
y1 = [random.uniform(15, 18) for i in x]
y2 = [random.uniform(1, 3) for i in x]
# 2、创建画布
# plt.figure(figsize=(20, 8), dpi=80)
figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=80)
# 返回两个实例对象一个是figure,一个是绘图区
# 3、绘制图像
axes[0].plot(x, y1, color="r", linestyle="--", label="甲")
axes[1].plot(x, y2, color="b", linestyle="-", label="乙")
# 要在辅助显示层显示图例
# plt.legend()
# 可以设置图例的位置
# plt.legend(loc="lower left")
axes[0].legend()
axes[1].legend()
# 修改x、y的刻度
# 准备x的刻度说明
x_label = ["11点{}分".format(i) for i in x]
axes[0].set_xticks(x[::5])
axes[0].set_xticklabels(x_label[::5])
axes[0].set_yticks(range(0, 40, 5))
axes[1].set_xticks(x[::5])
axes[1].set_xticklabels(x_label[::5])
axes[1].set_yticks(range(0, 40, 5))
# 添加网格显示
axes[0].grid(True, linestyle="--", alpha=0.5)
axes[1].grid(True, linestyle="--", alpha=0.5)
# 添加描述信息
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点每分钟温度的变化")
# 4、显示图像
plt.show()
这样我们就可以创建两个绘图区(坐标系);当然要是想再创建,添加实例化绘图区对象数据。
3):折线图小结
折线图应用的场景,相信大家比我要熟悉太多了;其实就是根据(某事物、某指标随时间的变化状况。
当然大家是否注意到折线图还有画各种数学函数的图像的功能。就像第一个例子那样,其实相当于一个一次函数;不仅线性函数可以画,非线性也可以。
试想:当一个区间有足够密集的点,然后根据折线图将这些点一个一个连接起来,其实就可以呈现出平滑的数学曲线。
1、举个简单的例子:画出y = 2 * x ^ 2(抛物线)的函数图像
这里需要用到numpy模块(是一个为Python提供的高性能向量、矩阵和高维数据结构的科学计算包)
这个笔者后续会继续学习的。
# 画一个抛物线y = 2 * x ^ 2的图像
import numpy as np
import matplotlib.pyplot as plt
# 1、准备数据
x = np.linspace(-10, 10, 1000) # 模块内的一个方法:生成-10-10之间的1000个数[闭区间]
y = 2 * x ** 2
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=100)
# 3、绘制函数图像
plt.plot(x, y)
# 4、添加网格显示
plt.grid()
# 5、显示图像
plt.show()
2、我们再来试一下正弦函数
# 画一个正弦函数的图像
import numpy as np
import matplotlib.pyplot as plt
# 1、准备数据
x = np.linspace(-10, 10, 1000)
y = np.sin(x)
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=100)
# 3、绘制函数图像
plt.plot(x, y)
# 4、添加网格显示
plt.grid()
# 5、显示图像
plt.show()
(2).散点图(scatter)
用两组数据构成多个坐标点,考察坐标点的分布;
判断两变量之间是否存在目中关联或总结坐标点的分布模式。
关键字:scatter
特点:判断变量之间是否存在数量关联趋势(分布规律)
# 这里笔者是随机造的数据,散点图可能呈现的看不出来关系,读者可以用数据再测试一下
import random
import matplotlib.pyplot as plt
# 1、准备数据
x = []
y = []
for i in range(1, 16, 1):
x.append(random.randint(30, 100))
for i in range(1, 16, 1):
y.append(random.randint(30, 100))
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制图像
plt.scatter(x, y)
# 4、显示图像
plt.show()
(3).柱状图(bar)
排列在工作表的列或行中的数据可以绘制柱状图中
关键字:bar
特点:绘制连离散的数据,能够一眼看到各个数据的大小,比较数据之间的差别(统计/对比)
1).整体对比
即所有数据整体呈现再整个图上
1、举个例子:对比下面几个电影票房收入
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# 1、准备数据
movie_name = ['熊出没', '喜羊羊与灰太狼之虎虎生威', '复仇者联盟', '无限列车', '黄金城', '沉默的十五分钟', '狂热行动', '直接裂开', '唐人街探案', '喜羊羊与灰太狼之牛气冲天']
tickets = [73574697, 57746678, 228279054, 115949969, 146114183, 87611625, 86111318, 7669116, 67166164, 522215112]
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制柱状图
x_ticks = range(len(movie_name))
plt.bar(x_ticks, tickets, color=['b', 'r', 'g', 'y', 'c', 'm', 'y', 'k', 'c', 'g', 'b'])
# 4、修改x刻度
plt.xticks(x_ticks, movie_name) # 加进名字
# 5、修改标题:
plt.title("电影票房收入对比")
# 6、添加网格
plt.grid(linestyle="--", alpha=0.5)
# 5、显示图像
plt.show()
2).局部对比
就是可以将同时间段的柱状图放在一起对比
其实就是绘制多个bar
2、对比电影首映和一周后的票房收入
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据
movie_name = ['熊出没', '喜羊羊与灰太狼之虎虎生威', '复仇者联盟']
first_day = [105817.6, 100162.5, 12175.7]
first_weekend = [362124.9, 344719.6, 118130]
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制柱状图
plt.bar(range(3), first_day, width=0.2, label="首日票房")
plt.bar([0.2, 1.2, 2.2], first_weekend, width=0.2, label="一周后票房")
# 4、修改刻度
plt.xticks([0.1, 1.1, 2.1], movie_name)
# 5、显示图例
plt.legend()
# 6、显示图像
plt.show()
(4).直方图(histogram)
横轴表示的是一个范围
关键字:hist
特点:绘制连续性的数据,展示一组或多组数据的分布状况(统计)
直方图的宽度可不一;
高度表示频数;
组数:按照范围分成不同的组;
组距:每一组两个端点差;
举个例子:模拟电影的时长分布状况
import random
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据
movie_time = []
for i in range(1, 251, 1):
movie_time.append(random.randint(120, 240))
time = movie_time
# 2、求组数(极大值 - 极小值) / 组距
distance = 5 # 组距设置
group_num = int((max(time) - min(time)) / distance)
# 求组数记得强制类型转换(组数不允许出现浮点数)
# 3、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 4、绘制直方图
plt.hist(time, bins=group_num, density=True)
# 使用density可以将频数显示不来
# 5、修改x轴刻度
plt.xticks(range(min(time), 245, distance))
# 6、添加网格
plt.grid(linestyle="--", alpha=0.5)
# 7、添加x,y轴描述信息
plt.xlabel("电影时长大小", color="k")
plt.ylabel("电影的数据量", color="k")
# 、显示图像
plt.show()
(5).饼图(pie)
用于表示不用分类的占比情况,通过弧度的大小来对比各种分类;
关键字:pie
plt.pie(x, labels=, autopct=, colors)
x:数量;
labels:每部分名称;
autopct:占比显示指定%1.21%%
colors:每部分颜色
特点:分类数据的占比情况(占比)
举个例子:显示一个大学生每月花费占比情况
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 1、准备数据
name = ['生活必需品', '衣服', '学习', '饭', '给女朋友', '氪游戏', '奢侈品']
data_money = [100, 500, 100, 800, 1000, 200, 800]
data_money = sorted(data_money) # 可以排序
# 2、创建画布
plt.figure(figsize=(20, 8), dpi=80)
# 3、绘制饼图
plt.pie(data_money, labels=name, colors=['b', 'y', 'g', 'k', 'c', 'm', 'r'], autopct="%1.2f%%")
# 4、显示图例
plt.legend()
# 5、调整饼图的比例
plt.axis('equal') # 保证长宽一样
# 6、显示图像
plt.show()
三、总结
以上就是我简单上手Matplotlib学到的东西,用的时间也比较短;总结的不多,可能还有错误;其实Matplotlib还有很多东西,笔者后续也会继续学习起来。大家一起加油!😊