大家好呀,今天我们学习数据分析课程的第九节课——用来做数据可视化的 Matplotlib。
内容目录如下:
- 什么是 Matplotlib
- 为什么要学习 Matplotlib
- 常见图形种类及意义
- Matplotlib 画图的简单实现
- 对 Matplotlib 图像结构的认识
- 折线图
(1)折线图的绘制
(2)折线的颜色和形状设置
(3)折点样式
(4)设置的图片的大小和保存
(5)绘制x轴和y轴的刻度
(6)设置显示中文
(7)一图多线
(8)拓展一(一图多个坐标系子图)
(9)拓展二(设置坐标轴范围)
(10)拓展三(改变坐标轴的默认显示方式) - 散点图
- 条形图
- 直方图
- 饼状图
课前准备:安装 Matplotlib
pip install -U matplotlib -i https://pypi.douban.com/simple
一、什么是 Matplotlib?
Matplotlib官网
Matplotlib 是一个 Python 2D 绘图库,它可以让你仅用几行代码就可以生成直方图、折线图、条形图、饼状图、散点图等一些数据统计图形,还可以自定义设置图表元素的多种样式和属性。
二、为什么要学习 Matplotlib?
可视化是整个数据分析过程中的关键一步,它可以让我们更清晰地理解数据,从而调整我们的分析方法,也能让数据更加直观,更具有说服力。
三、常见图形种类及意义
1、折线图
折线图:以折线的上升或下降来表示统计数量的增减变化的统计图。
特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)
2、散点图
散点图: 用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。
特点:判断变量之间是否存在数量关联趋势,展示离群点。(分布规律)
3、柱状图(条形图)
柱状图: 又叫条形图,是一种以长方形的长度为变量的统计图表,一般用来表示数量型变量。
特点: 绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计/对比)
4、直方图
直方图:由一系列高度不等的纵向条纹或线段表示数据分布的情况。一般用横轴表示数据范围, 纵轴表示分布情况。
特点:绘制连续性的数据展示一组或者多组数据的分布状况。(统计)。
5、饼图
饼图:用于表示不同分类的占比情况,通过弧度大小来对比各种分类。
特点:分类数据的占比情况。(占比)
四、Matplotlib 画图的简单实现
# 导入模块
import matplotlib.pyplot as plt
# 在 jupyter 中执行的时候显示图片
%matplotlib inline
# 传入x和y, 通过plot画图
plt.plot([1, 0, 9], [4, 5, 6])
# 在执行程序的时候展示图形
plt.show()
五、对 Matplotlib 图像结构的认识
通常情况下,我们可以将一张 Matplotlib 图像分成三层结构:
- 第一层是底层的容器层,主要包括 Canvas、Figure、Axes;
- 第二层是辅助显示层,主要包括 axis、spines、grid、legend、title等;
- 第三层为图像层,即通过 plot、scatter 等方法绘制的图像。
六、折线图
1、折线图的绘制
from matplotlib import pyplot as plt
x = range(1,8) # x轴的位置
y = [17, 17, 18, 15, 11, 11, 13]
# 传入x和y, 通过plot画折线图
plt.plot(x,y)
plt.show()
2、折线的颜色和形状设置
from matplotlib import pyplot as plt
x = range(1,8)
# x轴的位置
y = [17, 17, 18, 15, 11, 11, 13]
# 传入x和y, 通过plot画折线图
plt.plot(x, y, color='red',alpha=0.5,linestyle='--',linewidth=3) plt.show()
'''基础属性设置
color='red' : 折线的颜色
alpha=0.5: 折线的透明度(0-1)
linestyle='--' : 折线的样式
linewidth=3: 折线的宽度
'''
'''线的样式
- 实线(solid)
-- 短线(dashed)
-. 短点相间线(dashdot)
: 虚点线(dotted) '''
3、折点样式
from matplotlib import pyplot as plt
x = range(1,8) # x轴的位置
y = [17, 17, 18, 15, 11, 11, 13]
# 传入x和y, 通过plot画折线图
plt.plot(x, y, marker='o',color='red',markersize='20',markeredgecolor='g',markeredgewidth = 5)
plt.show()
折点形状选择:
character | description |
---|---|
'-' | solid line style |
'--' | dashed line style |
'-.' | dash-dot line style |
':' | dotted line style |
'.' | point marker |
',' | pixel marker |
'o' | circle marker |
'v' | triangle_down marker |
'^' | triangle_up marker |
'<' | triangle_left marker |
'>' | triangle_right marker |
'1' | tri_down marker |
'2' | tri_up marker |
'3' | tri_left marker |
'4' | tri_right marker |
's' | square marker |
'p' | pentagon marker |
'*' | star marker |
'h' | hexagon1 marker |
'H' | hexagon2 marker |
'+' | plus marker |
'x' | x marker |
'D' | diamond marker |
'd' | thin_diamond marker |
'|' | vline marker |
'_' | hline marker |
4、设置的图片的大小和保存
from matplotlib import pyplot as plt
import random
x = range(2,26,2) # x轴的位置
y = [random.randint(15, 30) for i in x]
# 设置图片的大小
'''
figsize:指定figure的宽和高,单位为英寸;
dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80
1英寸等于2.5cm,A4纸是 21*30cm的纸张
'''
# 根据画布对象
plt.figure(figsize=(20,8),dpi=80) plt.plot(x,y)
# 传入x和y, 通过plot画图#
plt.show()
# 保存(注意: 要放在绘制的下面,并且plt.show()会释放figure资源,如果在显示图像之后保存图片将只能保存空图片 。) plt.savefig('./t1.png')
# 图片的格式也可以保存为svg这种矢量图格式,这种矢量图放在网页中放大后不会有锯齿
# plt.savefig('./t1.svg')
5、绘制 x 轴和 y 轴的刻度
from matplotlib import pyplot as plt x = range(2,26,2) # x轴的位置
y = [random.randint(15, 30) for i in x] plt.figure(figsize=(20,8),dpi=80)
# 设置x轴的刻度
# plt.xticks(x)
# plt.xticks(range(1,25)) # 设置y轴的刻度
# plt.yticks(y)
# plt.yticks(range(min(y),max(y)+1))
# 构造x轴刻度标签
x_ticks_label = ["{}:00".format(i) for i in x]
#rotation = 45 让字旋转45度
plt.xticks(x,x_ticks_label,rotation = 45)
# 设置y轴的刻度标签
y_ticks_label = ["{}℃".format(i) for i in range(min(y),max(y)+1)] plt.yticks(range(min(y),max(y)+1),y_ticks_label)
plt.plot(x,y)
plt.show()
6、设置显示中文
# matplotlib只显示英文,无法显示中文,需要修改matplotlib的默认字体# 通过matplotlib下的font_manager可以解决
# 两个小时内的每分钟跳动变化
from matplotlib import pyplot as plt
import matplotlib
import random
x = range(0,120)
y = [random.randint(10,30) for i in range(120)]
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y)
# 加坐标轴信息
'''另外一种写法
查看Linux、Mac下支持的字体
终端执行: fc-list
查看支持的中文(冒号前面有空格) fc-list :lang=zh
查看Windows下的字体:“C:\Windows\Fonts\”
可以自己下载字体文件(xxx.ttf),然后双击安装即可
# my_font = font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=18) # plt.ylabel("天气",fontproperties=my_font)
'''
#rotation将字体旋转45度
plt.xlabel('时间',rotation=45)
from matplotlib import font_manager my_font =
font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=18) plt.ylabel("次数",fontproperties=my_font)
# 设置标题
plt.title('每分钟跳动次数',fontproperties=my_font,color='red')
plt.show()
7、一图多线
# 假设大家在30岁的时候,根据自己的实际情况,统计出来你和你同事各自从11岁到30岁每年交的男/女朋友的数量如列表y1和y2,请在一个图中绘制出该数据的折线图,从而分析每年交朋友的数量走势。
y1 = [1,0,1,1,2,4,3,4,4,5,6,5,4,3,3,1,1,1,1,1]
y2 = [1,0,3,1,2,2,3,4,3,2,1,2,1,1,1,1,1,1,1,1]
x = range(11,31)
# 设置图形
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y1,color='red',label='自己')
plt.plot(x,y2,color='blue',label='同事')
# 设置x轴刻度
xtick_labels = ['{}岁'.format(i) for i in x]
my_font =
font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=18)
plt.xticks(x,xtick_labels,fontproperties=my_font,rotation=45)
# 绘制网格(网格也是可以设置线的样式)
#alpha=0.4 设置透明度
plt.grid(alpha=0.4)
# 添加图例(注意:只有在这里需要添加prop参数是显示中文,其他的都用fontproperties)
# 设置位置loc : upper left、 lower left、 center left、 upper center plt.legend(prop=my_font,loc='upper right')
#展示
plt.show()
8、拓展一(一图多个坐标系子图)
import matplotlib.pyplot as plt
import numpy as np
# add_subplot方法 给figure新增子图
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(1, 100)
#新建figure对象fig=plt.figure(figsize=(20,10),dpi=80)
#新建子图1
ax1=fig.add_subplot(2,2,1)
ax1.plot(x, x)
#新建子图2
ax2=fig.add_subplot(2,2,2)
ax2.plot(x, x ** 2)
ax2.grid(color='r', linestyle='--', linewidth=1,alpha=0.3)
#新建子图3
ax3=fig.add_subplot(2,2,3)
ax3.plot(x, np.log(x))
plt.show()
![结果](https://upload-images.jianshu.io/upload_images/8919282-b9fe618be5a0900b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 9、拓展二(设置坐标轴范围)
import matplotlib.pyplot as plt
import numpy as np
x= np.arange(-10,11,1)
y = x**2
plt.plot(x,y)
可以调x轴的左右两边
plt.xlim([-5,5])
只调一边
plt.xlim(xmin=-4)
plt.xlim(xmax=4)
plt.ylim(ymin=0)
plt.xlim(xmin=0)
plt.show()
![结果](https://upload-images.jianshu.io/upload_images/8919282-5dcdfc8972b90a00.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 10、拓展三(改变坐标轴的默认显示方式)
import matplotlib.pyplot as plt
import numpy as np
y = range(0,14,2)
x轴的位置
x = [-3,-2,-1,0,1,2,3]
plt.figure(figsize=(20,8),dpi=80)
获得当前图表的图像
ax = plt.gca()
设置图型的包围线
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('blue')
ax.spines['left'].set_color('red')
设置底边的移动范围,移动到y轴的0位置,'data':移动轴的位置到交叉轴的指定坐标
ax.spines['bottom'].set_position(('data', 0))
ax.spines['left'].set_position(('data', 1))
plt.plot(x,y)
plt.show()
![结果](https://upload-images.jianshu.io/upload_images/8919282-e082fc710bf34a27.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 七、绘制散点图
'''题干
3月份每天最高气温a =
[11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]
'''
from matplotlib
import pyplot as plt
from matplotlib import font_manager
import numpy as np
y = [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23]
x = range(1,32)
设置图形大小
plt.figure(figsize=(20,8),dpi=80)
使用scatter绘制散点图
size = np.random.randint(0, 100, 31)
设置大小
plt.scatter(x,y,label= '3月份',alpha=0.5,s=size,c='red')
调整x轴的刻度
my_font = font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=10)
_xticks_labels = ['3 月 {} 日 '.format(i) for i in x] plt.xticks(x[::3],_xticks_labels[::3],fontproperties=my_font,rotation=45)
_yticks_labels = ['{}°C'.format(i) for i in range(min(y),max(y)+1)] plt.yticks(range(min(y),max(y)+1),_yticks_labels)
plt.xlabel('日期',fontproperties=my_font)
plt.ylabel('温度',fontproperties=my_font)
图例plt.legend(prop=my_font)
plt.show()
![结果](https://upload-images.jianshu.io/upload_images/8919282-44e1f6e1ac65f59d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 八、绘制条形图**
'''http://58921.com/alltime
假设你获取到了2019年内地电影票房前20的电影(列表a)和电影票房数据(列表b),请展示该数据:
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b = ['38.13','19.85','14.89','11.36','6.47','5.93']
'''
from matplotlib import pyplot as plt
from matplotlib import font_manager
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b = ['38.13','19.85','14.89','11.36','6.47','5.93']
b =[38.13,19.85,14.89,11.36,6.47,5.93]
my_font = font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=10)
plt.figure(figsize=(20,8),dpi=80)
绘制条形图
rects = plt.bar(a,[float(i) for i in b],width=0.3,color= ['r','g','b','r','g','b'])
plt.xticks(range(len(a)),a,fontproperties=my_font)
plt.yticks(range(0,41,5),range(0,41,5))
在条形图上加标注(水平居中)
for rect in rects:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height+0.3, str(height),ha="center")
plt.show()
![结果](https://upload-images.jianshu.io/upload_images/8919282-805f1d7b31accd3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**横向条形图**
横向柱状图
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font =
font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=10)
a = ['流浪地球','疯狂的外星人','飞驰人生','大黄蜂','熊出没·原始时代','新喜剧之王']
b = [38.13,19.85,14.89,11.36,6.47,5.93]
plt.figure(figsize=(20,8),dpi=80)
绘制条形图的方法
'''
height=0.3 条形的宽度
'''
# 绘制横向的条形图
# plt.bar(y,x,width = 0.4)
rects = plt.barh(range(len(a)),b,height=0.5,color='r') plt.yticks(range(len(a)),a,fontproperties=my_font,rotation=45)
# 在条形图上加标注(水平居中)
for rect in rects:
# print(rect.get_x())
width = rect.get_width()
plt.text(width, rect.get_y()+0.5/2, str(width),va="center")
plt.show()
并列和罗列条形图
import matplotlib.pyplot as plt
import numpy as np
index = np.arange(4)
BJ = [50,55,53,60]
Sh = [44,66,55,41]
# 并列
plt.bar(index,BJ,width=0.3) plt.bar(index+0.3,Sh,width=0.3,color='green')
plt.xticks(index+0.3/2,index)
# 罗列
# plt.bar(index,Sh,bottom=BJ,width=0.3,color='green')
plt.show()
九、直方图
这部分由于原始数据太多,不好呈现,所以放张图给大家,大家可以自己找一些数据放在本地练习一下。
十、饼状图
import matplotlib.pyplot as plt
import matplotlib
from matplotlib import font_manager
my_font =
font_manager.FontProperties(fname='/System/Library/Fonts/PingFang.ttc',size=10)
label_list = ["第一部分", "第二部分", "第三部分"]
# 各部分标签
size = [55, 35, 10]
# 各部分大小
color = ["red", "green", "blue"]
# 各部分颜色
explode = [0, 0.05, 0]
# 各部分突出值
"""
绘制饼图
x : (每一块)的比例,如果sum(x)>1,会将多出的部分进行均分; explode: (每一块)离开中心距离
labels: (每一块)饼图外侧显示的说明文字;
labeldistance:设置标签文本距圆心位置,1.1表示1.1倍半径autopct:控制饼图内百分比设置
shadow:设置是否有阴影
startangle:起始绘制角度,默认图是从x轴正方向逆时针画起,如设定=90则从y轴正方向画起;
pctdistance:类似于labeldistance,指定autopct的位置刻度,默认值为0.6;
返回值:
patches : matplotlib.patches.Wedge列表(扇形实例)
l_text:label matplotlib.text.Text列表(标签实例)
p_text:label matplotlib.text.Text列表(百分比标签实例)
"""
plt.figure(figsize=(20, 8), dpi=100)
patches, l_text, p_text = plt.pie(size, explode=explode, colors=color, labels=label_list, labeldistance=1.1, autopct="%1.1f%%", shadow=False, startangle=90, pctdistance=0.6)
for t in l_text:
print(dir(t))
t.set_fontproperties(my_font)
for t in p_text:
t.set_size(18)
for i in patches:
i.set_color('pink')
break
plt.show()
pie 函数参数详解,英文原版请参见:matplotlib官网pie函数