IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 【宝藏级】全网最全的Matplotlib详细教程-数据分析必备手册(4.5万字总结) -> 正文阅读

[人工智能]【宝藏级】全网最全的Matplotlib详细教程-数据分析必备手册(4.5万字总结)

【宝藏级】全网最全的Matplotlib详细教程(4.5万字总结)

1. 数据分析中常用图

折线图:

折线图用于显示数据在一个连续的时间间隔或者时间跨度上的变化,它的特点是反映事物随时间或有序类别而变化的趋势。示例图如下:
在这里插入图片描述

折线图应用场景:

  1. 折线图适合X轴是一个连续递增或递减的,对于没有规律的,则不适合使用折线图,建议使用柱状图。
  2. 如果折线图条数过多,则不应该都绘制在一个图上。

柱状图:

典型的柱状图(又名条形图),使用垂直或水平的柱子显示类别之间的数值比较。其中一个轴表示需要对比的分类,另一个轴代表相应的数值。

柱状图有别于直方图,柱状图无法显示数据在一个区间内的连续变化趋势。柱状图描述的是分类数据,回答的是每一个分类中“有多少?”这个问题。 示例图如下:
在这里插入图片描述

柱状图应用场景:

  1. 适用于分类数据对比。
  2. 垂直条形图最多不超过12个分类(也就是12个柱形),横向条形图最多不超过30个分类。如果垂直条形图的分类名太长,那么建议换成横向条形图。

在这里插入图片描述
在这里插入图片描述

  1. 柱状图不适合表示趋势,如果想要表示趋势,应该使用折线图。

直方图:

直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的条纹表示数据分布的情况。一般用横轴表示数据类型,纵轴表示分布情况。

直方图是数值数据分布的精确图形表示。为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。这些值通常被指定为连续的,不重叠的变量间隔。间隔必须相邻,并且通常是(但不是必须的)相等的大小。

在这里插入图片描述

直方图的应用场景:

  1. 显示各组数据数量分布的情况。
  2. 用于观察异常或孤立数据。
  3. 抽取的样本数量过小,将会产生较大误差,可信度低,也就失去了统计的意义。因此,样本数不应少于50个。

散点图:

散点图也叫 X-Y 图,它将所有的数据以点的形式展现在直角坐标系上,以显示变量之间的相互影响程度,点的位置由变量的数值决定。

通过观察散点图上数据点的分布情况,我们可以推断出变量间的相关性。如果变量之间不存在相互关系,那么在散点图上就会表现为随机分布的离散的点,如果存在某种相关性,那么大部分的数据点就会相对密集并以某种趋势呈现。数据的相关关系主要分为:正相关(两个变量值同时增长)、负相关(一个变量值增加另一个变量值下降)、不相关、线性相关、指数相关等,表现在散点图上的大致分布如下图所示。那些离点集群较远的点我们称为离群点或者异常点。

在这里插入图片描述

示例图如下:
在这里插入图片描述

散点图的应用场景:

  1. 观察数据集的分布情况。
  2. 通过分析规律,根据样本数据特征计算出回归方程。

饼状图:

饼状图通常用来描述量、频率和百分比之间的关系。在饼图中,每个扇区的弧长大小为其所表示的数量的比例。
在这里插入图片描述

饼状图的应用场景:

  1. 展示多个分类的占比情况,分类数量建议不超过9个。
  2. 对于一些占比值非常接近的,不建议使用饼状图,可以使用柱状图。

箱线图:

箱线图(Box-plot)又称为盒须图、盒式图或箱型图,是一种用作显示一组数据分散情况资料的统计图。因形状如箱子而得名。在各种领域也经常被使用,它主要用于反映原始数据分布的特征,还可以进行多组数据分布特征的比较。箱线图的绘制方法是:先找出一组数据的上限值、下限值、中位数(Q2)和下四分位数(Q1)以及上四分位数(Q3);然后,连接两个四分位数画出箱子;再将最大值和最小值与箱子相连接,中位数在箱子中间。
在这里插入图片描述
在这里插入图片描述

四分位数(Quartile)也称四分位点,是指在统计学中把所有数值由小到大排列并分成四等份,处于三个分割点位置的数值。多应用于统计学中的箱线图绘制。它是一组数据排序后处于25%和75%位置上的值。四分位数是通过3个点将全部数据等分为4部分,其中每部分包含25%的数据。很显然,中间的四分位数就是中位数,因此通常所说的四分位数是指处在25%位置上的数值(称为下四分位数)和处在75%位置上的数值(称为上四分位数)。与中位数的计算方法类似,根据未分组数据计算四分位数时,首先对数据进行排序,然后确定四分位数所在的位置,该位置上的数值就是四分位数。与中位数不同的是,四分位数位置的确定方法有几种,每种方法得到的结果会有一定差异,但差异不会很大。

上限的计算规则是:
IQR=Q3-Q1
上限=Q3+1.5IQR
下限=Q1-1.5IQR

箱线图的应用场景:

  1. 直观明了地识别数据中的异常值。
  2. 利用箱线图判断数据的偏态。
  3. 利用箱线图比较几批数据的形状。
  4. 箱线图适合比较多组数据,如果知识要看一组数据的分布情况,建议使用直方图。

更多参考:

https://antvis.github.io/vis/doc/chart/classify/compare.html

2. Matplotlib库

Matplotlib是一个Python2D绘图库,通过Matplotlib,开发者可以仅需要几行代码,便可以生成折线图,直方图,条形图,饼状图,散点图等。

安装:

如果是用Anaconda,可以通过conda install matplotlib或者通过pip install matplotlib进行安装。

基本使用:

首先先看以下例子:

import matplotlib.pyplot as plt
import numpy as np
plt.plot(range(10),[np.random.randint(0,10) for x in range(10)])

那么就会出现以下图:
在这里插入图片描述

其中plot是一个画图的函数,他的参数为plot([x],y,[fmt],data=None,**kwargs)。其中fmt可以传一个字符串,用来给这个图做一些样式修改的。默认的绘制样式是b-,也就是蓝色实体线条。比如我想将原来的图的线条改成点状,那么可以通过以下代码实现:

import matplotlib.pyplot as plt
plt.plot(range(10),[np.random.randint(0,10) for x in range(10)],":")

其中使用:代表点线,是matplotlib的一个缩写。这些缩写还有以下的:

字符类型字符类型
‘-’实线‘–’虚线
‘-.’虚点线‘:’点线
‘.’‘,’像素点
‘o’圆点‘v’下三角点
‘^’上三角点‘<’左三角点
‘>’右三角点‘1’下三叉点
‘2’上三叉点‘3’左三叉点
‘4’右三叉点‘s’正方点
‘p’五角点‘*’星形点
‘h’六边形点1‘H’六边形点2
‘+’加号点‘x’乘号点
‘D’实心菱形点‘d’瘦菱形点
‘_’横线点

除了设置线条的形状外,我们还可以设置点的颜色。示例代码如下:

plt.plot([1,2,3,4,5],[1,2,3,4,5],'r') #将颜色线条设置成红色
plt.plot([1,2,3,4,5],[1,2,3,4,5],color='red') #将颜色设置成红色
plt.plot([1,2,3,4,5],[1,2,3,4,5],color='#000000') #将颜色设置成纯黑色
plt.plot([1,2,3,4,5],[1,2,3,4,5],color=(0,0,0,0)) #将颜色设置成纯黑色

给线条设置颜色总体来说有三种方式,第一种是使用颜色名称(rred的缩写)的形式,第二种是使用十六进制的方式,第三种是使用RGBRGBA的方式。如果使用的是颜色名称,那么可以和线的形状写在同一个字符串中。比如使用红色的五角点,那么可以使用如下的方式实现:

plt.plot([1,2,3,4,5],[1,2,3,4,5],'rp') #将颜色线条设置成红色

其中可以表示颜色的缩写字符有如下:

字符颜色
‘b’蓝色,blue
‘g’绿色,green
‘r’红色,red
‘c’青色,cyan
‘m’品红,magenta
‘y’黄色,yellow
‘k’黑色,black
‘w’白色,white

设置图的信息:

现在我们添加图后,没有指定x轴代表什么,y轴代表什么,以及这个图的标题是什么。因此以下我们通过一些属性来设置一下。

设置线条样式:

  1. 使用plot方法:plot方法就是用来绘制线条的,因此可以在绘制的时候就把线条相关的样式通过参数传进去。示例代码如下:

     plt.plot(x,y,linewidth=2)
    
  2. 通过Line2D对象来设置:plot方法会返回一个装有Line2D对象的列表,比如lines=plt.plot(x1,y1,x2,y2)因为绘制了两根线条,因此lines中会有两个2D对象。而如果plot只绘制一根线条,那么lines中就只有一个Line2D对象。拿到这个Line2D对象后就可以通过set_属性名设置线条的样式了:

     lines = plt.plot(x,y)
     line = lines[0]
     line.set_aa(False) #关掉反锯齿
     line.set_alpha(0.5) #设置0.5的透明度
    
  3. 使用plt.setp来设置:setp的好处是一次性可以设置多根线条的样式。示例代码如下:

     lines = plt.plot(x,y)
     plt.setp(lines,linewidth=10,alpha=0.5)
    
  4. 更多Line2D属性:
    在这里插入图片描述

设置轴和标题:

  1. 设置轴名称:可以通过plt.xlabelplt.ylabel来设置x轴和y轴的的名称。示例代码如下:

     plt.plot(x,y,linewidth=10,color='red')
     plt.xlabel("x轴")
     plt.ylabel("y轴")
    

    默认情况下是显示不了中文的。需要设置字体。可以通过以下代码来实现:

# 加载字体
font = font_manager.FontProperties(fname="C:\Windows\Fonts\msyh.ttc")
plt.plot(x,y,linewidth=10,color='red')
plt.xlabel("x轴",fontproperties=font)
plt.ylabel("y轴",fontproperties=font)

加载字体的时候,可以到C:\Windows\Fonts中找你喜欢的并且可以显示中文的字体。找到字体后,还需要找到字体的真实名称。方法是右键->属性->安全->对象名称:
在这里插入图片描述

  1. 设置标题:可以通过plt.title方法来实现。示例代码如下:
font = font_manager.FontProperties(fname="C:\Windows\Fonts\msyh.ttc")
plt.title("sin函数",fontproperties=font)
  1. 设置x轴和y轴的刻度:之前我们画的图,x轴和y轴的刻度都是matplotlib自动生成的。如果想要在生成图的时候手动的指定,那么可以通过plt.xticksplt.yticks来实现:

     plt.xticks(range(0,20,2)) #在x轴上的刻度是0,2,4,6...20
    

    以上会把那个刻度显示在x轴上。如果想要显示字符串类型,那么可以再构造一个数组,这个数组的长度必须和x轴刻度的长度保持一致。然后传给xticks的第二个参数。示例代码如下:

_x = range(0,20,2)
_xticks = ["%d坐标"%i for i in _x]
plt.xticks(_x,_xticks,fontproperties=font) #在x轴上的刻度是0坐标,2坐标...20坐标

在这里插入图片描述

同样y轴的刻度设置也是一样的。示例代码如下:

_y = np.arange(-1,1,0.25)
_yticks = ["%.2f点"%i for i in _y]
plt.yticks(_y,_yticks,fontproperties=font)

效果图如下:
在这里插入图片描述

复仇者联盟电影票房案例:

avenger = [17974.4,50918.4,30033.0,40329.1,52330.2,19833.3,11902.0,24322.6,47521.8,32262.0,22841.9,12938.7,4835.1,3118.1,2570.9,2267.9,1902.8,2548.9,5046.6,3600.8]
plt.figure(figsize=(15,5))
plt.plot(avenger,marker="o")
font.set_size(10)
plt.xticks(range(20),["第%d天"%x for x in range(1,21)],fontproperties=font)
plt.xlabel("天数",fontproperties=font)
plt.ylabel("票房数(万)",fontproperties=font)
plt.grid()

在这里插入图片描述

设置marker:

有时候,我们想要在一些关键点上重点标记出来。那么我们可以通过设置marker来实现。示例代码如下:

x = np.linspace(0,20)y = np.sin(x)plt.plot(x,y,marker="o")

在这里插入图片描述

我们设置了markero,这样就是会在(x,y)的坐标点上显示出来,并且显示的是圆点。其中o跟之前的线条样式的简写是一样的。另外,还可以通过markerfacecolor属性和markersize来指定标记点的颜色和大小。示例代码如下:

# 以下设置标记点的颜色为黑色,尺寸为10
plt.plot(x,y,marker="o",markerfacecolor='k',markersize=10)

设置注释文本:

有时候需要在图形中的某个点标记或者注释一下。那么我们可以使用plt.annotate(text,xy,xytext,arrowprops={})来实现,其中text是注释的文本,xy是需要注释的点的坐标,xytext是注释文本的坐标,arrowprops是箭头的样式属性。示例代码如下:

ax = plt.subplot(111)

x = np.arange(0.0, 5.0, 0.01)
y = np.cos(2*np.pi*t)
line, = plt.plot(x, y,linewidth=2)

plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black',shrink=0.05),
)

plt.ylim(-2, 2)
plt.show()

设置图形样式:

如果想要调整图片的大小和像素,可以通过plt.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)来实现。
其中num是图的编号,figsize的单位是英寸,dpi是每英寸的像素点,facecolor是图片背景颜色,edgecolor是边框颜色,frameon代表是否绘制画板。
示例代码如下:

plt.figure(figsize=(20,8),dpi=80)
# 其他的绘制图形的代码

我们也可以使用grid方法,来显示图片的网格:

plt.plot(x,y,color="r")
plt.grid()

在这里插入图片描述

保存图片:

可以调用plt.savefig(path)来保存当前的图片。示例代码如下:

plt.savefig("./abc.png")

绘制多个图:

绘制多个图有两种形式,第一种形式是在一张图中绘制多跟线条,第二种形式是绘制多个子图形。以下分别进行讲解。

绘制多根折线:

绘制多根线条,只要准备好坐标,重新使用plt.plot绘制即可。示例代码如下:

from matplotlib import font_managerx = np.linspace(0,20)y = np.sin(x)z = np.cos(x)font = font_manager.FontProperties(fname="C:\Windows\Fonts\msyh.ttc")plt.xlabel("x轴",fontproperties=font)plt.ylabel("y轴",fontproperties=font)_x = range(0,20,2)_xticks = ["%s点"%i for i in _x]plt.xticks(range(0,20,2),_xticks,fontproperties=font,rotation=45)_y = list(np.range(-1,1,0.25))_yticks = ["%.2f点"%i for i in _y]plt.yticks(_y,_yticks,fontproperties=font)plt.plot(x,y)plt.plot(x,z)

示例图如下:
在这里插入图片描述

绘制多个子图:

绘制子图的时候,我们可以使用plt.subplotplt.subplots来实现。示例代码如下:

plt.subplot(221)
plt.plot(np.arange(10),c='r')
plt.subplot(222)
plt.plot(np.sin(np.arange(10)),c='b')
plt.subplot(223)
plt.plot(np.cos(np.arange(10)),c='y')
plt.subplot(224)
plt.plot(np.tan(np.arange(10)),c='g')

效果图如下:
在这里插入图片描述

其中subplot中的211212分别代表的意思是,第一个数表示这个大图中总共有2行,第二个数表示总共有1列,然后第三个数表示当前绘制第几个图。

也可以使用fig,axs=plt.subplots(rows,cols,*args,**kwargs)来绘制多个图形,返回值是一个元组,其中的fig参数是figure对象,axsaxes对象的array。示例代码如下:

figure,axes = plt.subplots(2,2)
axes[0,0].plot(np.sin(np.arange(10)),c='r')
axes[0,1].plot(np.cos(np.arange(10)),c='b')
axes[1,0].plot(np.tan(np.arange(10)),c='y')
axes[1,1].plot(np.arange(10),c='g')

效果图跟之前使用plt.subplot一样。另外使用subplotsubplots都可以传递sharex/sharey参数,这两个参数表示是否需要共享X轴和Y轴。示例代码如下:

figure,axes = plt.subplots(2,2,sharex=True,sharey=True)
axes[0,0].plot(np.sin(np.arange(10)),c='r')
axes[0,1].plot(np.cos(np.arange(10)),c='b')
axes[1,0].plot(np.tan(np.arange(10)),c='y')
axes[1,1].plot(np.arange(10),c='g')

在这里插入图片描述

风格设置:

matplotlib图片默认内置了几种风格。我们可以通过plt.style.available来查看内置的所有风格:

['bmh',
'classic',
'dark_background',
'fast',
'fivethirtyeight',
'ggplot',
'grayscale',
'seaborn-bright',
'seaborn-colorblind',
'seaborn-dark-palette',
'seaborn-dark',
'seaborn-darkgrid',
'seaborn-deep',
'seaborn-muted',
'seaborn-notebook',
'seaborn-paper',
'seaborn-pastel',
'seaborn-poster',
'seaborn-talk',
'seaborn-ticks',
'seaborn-white',
'seaborn-whitegrid',
'seaborn',
'Solarize_Light2',
'tableau-colorblind10',
'_classic_test']

在绘制的,可以使用plt.style.use方法来使用不同的风格。示例代码如下:

plt.style.use("dark_background")

官方文档介绍:

  1. plt.plot使用详解:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html#matplotlib.pyplot.plot
  2. matplotlib.pyplot使用详解:https://matplotlib.org/api/pyplot_summary.html
  3. matplotlib内置的样式:https://tonysyu.github.io/raw_content/matplotlib-style-gallery/gallery.html

3. 条形图

条形图的绘制方式跟折线图非常的类似,只不过是换成了plt.bar方法。plt.bar方法有以下常用参数:

  1. x:一个数组或者列表,代表需要绘制的条形图的x轴的坐标点。
  2. height:一个数组或者列表,代表需要绘制的条形图y轴的坐标点。
  3. width:每一个条形图的宽度,默认是0.8的宽度。
  4. bottomy轴的基线,默认是0,也就是距离底部为0.
  5. align:对齐方式,默认是center,也就是跟指定的x坐标居中对齐,还有为edge,靠边对齐,具体靠右边还是靠左边,看width的正负。
  6. color:条形图的颜色。

返回值为BarContainer,是一个存储了条形图的容器,而条形图实际上的类型是matplotlib.patches.Rectangle对象。

更多参考:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.bar.html#matplotlib.pyplot.bar

条形图的绘制:

比如现在有2019年贺岁片票房的数据(数据来源:https://piaofang.maoyan.com/dashboard):

#票房单位亿元
movies = {
    "流浪地球":40.78,
    "飞驰人生":15.77,
    "疯狂的外星人":20.83,
    "新喜剧之王":6.10,
    "廉政风云":1.10,
    "神探蒲松龄":1.49,
    "小猪佩奇过大年":1.22,
    "熊出没·原始时代":6.71
}

用条形图绘制每部电影及其票房的代码如下:

movies = {
    "流浪地球":40.78,
    "飞驰人生":15.77,
    "疯狂的外星人":20.83,
    "新喜剧之王":6.10,
    "廉政风云":1.10,
    "神探蒲松龄":1.49,
    "小猪佩奇过大年":1.22,
    "熊出没·原始时代":6.71
}
plt.bar(np.arange(len(movies)),list(movies.keys()))
plt.xticks(np.arange(len(movies)),list(movies.keys()),fontproperties=font)
plt.grid()

效果图如下:
在这里插入图片描述

其中xticksyticks的用法跟之前的折线图一样。这里新出现的方法是barbar常用的有3个参数,分别是x(x轴的坐标点),y(y轴的坐标点)以及width(条形的宽度)。

横向条形图:

横向条形图需要使用plt.barh这个方法跟bar非常的类似,只不过把方向进行旋转。参数跟bar类似,但也有区别。如下:

  1. y:数组或列表,代表需要绘制的条形图在y轴上的坐标点。
  2. width:数组或列表,代表需要绘制的条形图在x轴上的值(也就是长度)。
  3. height:条形图的高度,默认是0.8。
  4. left:条形图的基线,也就是距离y轴的距离。
  5. 其他参数跟bar一样。

返回值也是BarContainer容器对象。

还是以以上数据为例,将电影名和票房反转一下。示例代码如下:

movies = {
    "流浪地球":40.78,
    "飞驰人生":15.77,
    "疯狂的外星人":20.83,
    "新喜剧之王":6.10,
    "廉政风云":1.10,
    "神探蒲松龄":1.49,
    "小猪佩奇过大年":1.22,
    "熊出没·原始时代":6.71
}
plt.barh(np.arange(len(movies)),list(movies.values()))
plt.yticks(np.arange(len(movies)),list(movies.keys()),fontproperties=font)
plt.grid()

效果图如下:
在这里插入图片描述

分组条形图:

现在有一组数据,是2019年春节贺岁片前五天的电影票房记录。
示例代码如下:

movies = {
    "流浪地球":[2.01,4.59,7.99,11.83,16],
    "飞驰人生":[3.19,5.08,6.73,8.10,9.35],
    "疯狂的外星人":[4.07,6.92,9.30,11.29,13.03],
    "新喜剧之王":[2.72,3.79,4.45,4.83,5.11],
    "廉政风云":[0.56,0.74,0.83,0.88,0.92],
    "神探蒲松龄":[0.66,0.95,1.10,1.17,1.23],
    "小猪佩奇过大年":[0.58,0.81,0.94,1.01,1.07],
    "熊出没·原始时代":[1.13,1.96,2.73,3.42,4.05]
}
plt.figure(figsize=(20,8))
width = 0.75
bin_width = width/5
movie_pd = pd.DataFrame(movies)
ind = np.arange(0,len(movies))

# 第一种方案
# first_day = movie_pd.iloc[0]
# plt.bar(ind-bin_width*2,first_day,width=bin_width,label='第一天')

# second_day = movie_pd.iloc[1]
# plt.bar(ind-bin_width,second_day,width=bin_width,label='第二天')

# third_day = movie_pd.iloc[2]
# plt.bar(ind,third_day,width=bin_width,label='第三天')

# four_day = movie_pd.iloc[3]
# plt.bar(ind+bin_width,four_day,width=bin_width,label='第四天')

# five_day = movie_pd.iloc[4]
# plt.bar(ind+bin_width*2,five_day,width=bin_width,label='第五天')

# 第二种方案
for index in movie_pd.index:
    day_tickets = movie_pd.iloc[index]
    xs = ind-(bin_width*(2-index))
    plt.bar(xs,day_tickets,width=bin_width,label="第%d天"%(index+1))
    for ticket,x in zip(day_tickets,xs):
        plt.annotate(ticket,xy=(x,ticket),xytext=(x-0.1,ticket+0.1))

# 设置图例
plt.legend(prop=font)
plt.ylabel("单位:亿",fontproperties=font)
plt.title("春节前5天电影票房记录",fontproperties=font)
# 设置x轴的坐标
plt.xticks(ind,movie_pd.columns,fontproperties=font)
plt.xlim
plt.grid(True)
plt.show()

示例图如下:
在这里插入图片描述

堆叠条形图:

堆叠条形图,是将一组相关的条形图堆叠在一起进行比较的条形图。比如以下案例:

menMeans = (20, 35, 30, 35, 27)
womenMeans = (25, 32, 34, 20, 25)
groupNames = ('G1','G2','G3','G4','G5')
xs = np.arange(len(menMeans))
plt.bar(xs,menMeans)
plt.bar(xs,womenMeans,bottom=menMeans)
plt.xticks(xs,groupNames)
plt.show()

效果图如下:
在这里插入图片描述

在绘制女性得分的条形图的时候,因为要堆叠在男性得分的条形图上,所以使用到了一个bottom参数,就是距离x轴的距离。通过对贴条形图,我们就可以清楚的知道,哪一个队伍的综合排名是最高的,并且在每个队伍中男女的得分情况。

条形图应用场景:

  1. 数量统计。
  2. 频率统计。

4. 直方图

直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的条纹表示数据分布的情况。一般用横轴表示数据类型,纵轴表示分布情况。

直方图是数值数据分布的精确图形表示。为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。这些值通常被指定为连续的,不重叠的变量间隔。间隔必须相邻,并且通常是(但不是必须的)相等的大小。

绘制直方图:

直方图的绘制方法,使用的是plt.hist方法来实现,这个方法的参数以及返回值如下:

参数:

  1. x:数组或者可以循环的序列。直方图将会从这组数据中进行分组。
  2. bins:数字或者序列(数组/列表等)。如果是数字,代表的是要分成多少组。如果是序列,那么就会按照序列中指定的值进行分组。比如[1,2,3,4],那么分组的时候会按照三个区间分成3组,分别是[1,2)/[2,3)/[3,4]
  3. range:元组或者None,如果为元组,那么指定x划分区间的最大值和最小值。如果bins是一个序列,那么range没有有没有设置没有任何影响。
  4. density:默认是False,如果等于True,那么将会使用频率分布直方图。每个条形表示的不是个数,而是频率/组距(落在各组样本数据的个数称为频数,频数除以样本总个数为频率)。
  5. cumulative:如果这个和density都等于True,那么返回值的第一个参数会不断的累加,最终等于1
  6. 其他参数:请参考:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.hist.html

返回值:

  1. n:数组。每个区间内值出现的个数,如果density=True,那么这个将返回的是频率/组距
  2. bins:数组。区间的值。
  3. patches:数组。每根条的对象,类型是matplotlib.patches.Rectangle

案例:

比如有一组电影票房时长,想要看下这组票房时长的数据,那么可以通过以下代码来实现:

durations = [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]
plt.figure(figsize=(15,5))
nums,bins,patches = plt.hist(durations,bins=20,edgecolor='k')
plt.xticks(bins,bins)
for num,bin in zip(nums,bins):
    plt.annotate(num,xy=(bin,num),xytext=(bin+1.5,num+0.5))
plt.show()

效果图如下:
在这里插入图片描述

另外,也可以通过density=True,来实现频率分布直方图。示例代码如下:

nums,bins,patches = plt.hist(durations,bins=20,edgecolor='k',density=True)
plt.xticks(bins,bins)
for num,bin in zip(nums,bins):
    plt.annotate("%.4f"%num,xy=(bin,num),xytext=(bin+0.2,num+0.0005))

在这里插入图片描述

而如果想要让nums的总和为1,那么就需要设置cumulative=True参数,示例代码如下:

nums,bins,patches = plt.hist(durations,bins=20,edgecolor='k',density=True,cumulative=True)
plt.xticks(bins,bins)
for num,bin in zip(nums,bins):
    plt.annotate("%.4f"%num,xy=(bin,num),xytext=(bin+0.2,num+0.0005))

直方图的应用场景:

  1. 显示各组数据数量分布的情况。
  2. 用于观察异常或孤立数据。
  3. 抽取的样本数量过小,将会产生较大误差,可信度低,也就失去了统计的意义。因此,样本数不应少于50个。

5. 散点图

散点图也叫 X-Y 图,它将所有的数据以点的形式展现在直角坐标系上,以显示变量之间的相互影响程度,点的位置由变量的数值决定。

通过观察散点图上数据点的分布情况,我们可以推断出变量间的相关性。如果变量之间不存在相互关系,那么在散点图上就会表现为随机分布的离散的点,如果存在某种相关性,那么大部分的数据点就会相对密集并以某种趋势呈现。

数据的相关关系主要分为:正相关(两个变量值同时增长)、负相关(一个变量值增加另一个变量值下降)、不相关、线性相关、指数相关等,表现在散点图上的大致分布如下图所示。那些离点集群较远的点我们称为离群点或者异常点。
在这里插入图片描述

示例图如下:
在这里插入图片描述

绘制散点图:

散点图的绘制,使用的是plt.scatter方法,这个方法有以下参数:

  1. x,y:分别是x轴和y轴的数据集。两者的数据长度必须一致。
  2. s:点的尺寸。如果是一个具体的数字,那么散点图的所有点都是一样大小,如果是一个序列,那么这个序列的长度应该和x轴数据量一致,序列中的每个元素代表每个点的尺寸。
  3. c:点的颜色。可以为具体的颜色,也可以为一个序列或者是一个cmap对象。
  4. marker:标记点,默认是圆点,也可以换成其他的。
  5. 其他参数:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter

比如有一组运动员身高和体重以及年龄的数据,那么可以通过以下代码来绘制散点图:

male_athletes = athletes[athletes['Sex'] == 'M']
female_athletes = athletes[athletes['Sex'] == 'F']
male_mean_height = male_athletes['Height'].mean()
female_mean_height = female_athletes['Height'].mean()
male_mean_weight = male_athletes['Weight'].mean()
female_mean_weight = female_athletes['Weight'].mean()

plt.figure(figsize=(10,5))
plt.scatter(male_athletes['Height'],male_athletes['Weight'],s=male_athletes['Age'],marker='^',color='g',label='男性',alpha=0.5)
plt.scatter(female_athletes['Height'],female_athletes['Weight'],color='r',alpha=0.5,s=female_athletes['Age'],label='女性')
plt.axvline(male_mean_height,color="g",linewidth=1)
plt.axhline(male_mean_weight,color="g",linewidth=1)
plt.axvline(female_mean_height,color="r",linewidth=1)
plt.axhline(female_mean_weight,color="r",linewidth=1)
plt.xticks(np.arange(140,220,5))
plt.yticks(np.arange(30,150,10))
plt.legend(prop=font)
plt.xlabel("身高(cm)",fontproperties=font)
plt.ylabel("体重(kg)",fontproperties=font)
plt.title("运动员身高和体重散点图",fontproperties=font)
plt.grid()
plt.show()

效果图如下:
在这里插入图片描述

绘制回归曲线:

有一组数据后,我们可以对这组数据进行回归分析,回归分析可以帮助我们了解这组数据的大体走向

回归分析按照涉及的变量的多少,分为一元回归和多元回归分析;按照自变量的多少,可分为简单回归分析和多重回归分析;按照自变量和因变量之间的关系类型,可分为线性回归分析和非线性回归分析。如果在回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且自变量之间存在线性相关,则称为多重线性回归分析。

自变量数量是否线性回归类型
1个一元线性回归
多个多元线性回归
1个一元非线性回归
多个多元非线性回归

通过以上运动员散点图的分析,我们总体上可以看出来是满足线性回归的,因此可以在图上绘制一个线性回归的线条。想要绘制线性回归的线条,需要先按照之前的数据计算出线性方程,假如x是自变量,y是因变量,那么线性回归的方程可以用以下几个来表示:

y = 截距+斜率*x+误差

只要把这个方程计算出来了,那么后续我们就可以根据x的值,大概的估计出y的取值范围,也就是预测。如果我们针对以上运动员的身高和体重的关系,只要有身高,那么就可以大概的估计出体重的值。

回归方程的绘制我们需要借助scikit-learn库,这个库是专门做机器学习用的,我们需要使用里面的线性回归类sklearn.liear_regression.LinearRegression。示例代码如下:

from sklearn.linear_model import LinearRegression
male_athletes = athletes[athletes['Sex'] == 'M'].dropna()
female_athletes = athletes[athletes['Sex'] == 'F'].dropna()
xtrain = male_athletes['Height']
ytrain = male_athletes['Weight']
# 生成线性回归对象
model = LinearRegression()
# 喂训练数据进去,但是需要把因变量转换成1列多行的数据/reshape(xtrain.shape(0), 1)
model.fit(xtrain[:,np.newaxis],ytrain)
# 打印斜率
print(model.coef_)
# 打印截距
print(model.intercept_)
line_xticks = xtrain
# 根据回归方程计算出的y轴坐标
line_yticks = model.predict(xtrain[:,np.newaxis])  # predict_male_weight
plt.plot(male_heights, line_yticks)
# male_heights.values.reshape(male_heights.shape[0],1)

效果图如下:
在这里插入图片描述

6. 饼图

饼图是一个划分为几个扇形的圆形统计图表,用于描述量、频率或百分比之间的相对关系的。
matplotlib中,可以通过plt.pie来实现,其中的参数如下:

  1. x:饼图的比例序列。
  2. labels:饼图上每个分块的名称文字。
  3. explode:设置某几个分块是否要分离饼图。
  4. autopct:设置比例文字的展示方式。比如保留几个小数等。
  5. shadow:是否显示阴影。
  6. textprops:文本的属性(颜色,大小等)。
  7. 其他参数:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.pie.html#matplotlib.pyplot.pie

返回值:

  1. patches:饼图上每个分块的对象。
  2. texts:分块的名字文本对象。
  3. autotexts:分块的比例文字对象。

假如现在我们有一组数据,用来记录各个操作系统的市场份额的。那么用饼状图表示如下:

oses = {
'windows7':60.86,
'windows10': 18.46,
'windows8': 3.61,
'windows xp': 10.3,
'mac os': 6.78,
'其他': 1.12
}
names = oses.keys()
percents = oses.values()
patches,texts,autotexts = plt.pie(percents,labels=names,autopct="%.2f%%",explode=(0,0.05,0,0,0,0))
for text in texts+autotexts:
    plt.setp(text,fontproperties=font)
    text.set_fontsize(10)
for text in autotexts:
    text.set_color("white")

效果图如下:

在这里插入图片描述

7. 箱线图

箱线图(Box-plot)又称为盒须图、盒式图或箱型图,是一种用作显示一组数据分散情况资料的统计图。因形状如箱子而得名。在各种领域也经常被使用,它主要用于反映原始数据分布的特征,还可以进行多组数据分布特征的比较

箱线图的绘制方法是:先找出一组数据的上限值、下限值、中位数(Q2)和下四分位数(Q1)以及上四分位数(Q3);然后,连接两个四分位数画出箱子;再将最大值和最小值与箱子相连接,中位数在箱子中间。
在这里插入图片描述
在这里插入图片描述

中位数:把数据按照从小到大的顺序排序,然后最中间的那个值为中位数,如果数据的个数为偶数,那么就是最中间的两个数的平均数为中位数。
上下四分位数:同样把数据排好序后,把数据等分为4份。出现在25%位置的叫做下四分位数,出现在75%位置上的数叫做上四分位数。但是四分位数位置的确定方法不是固定的,有几种算法,每种方法得到的结果会有一定差异,但差异不会很大。

上下限的计算规则是:
IQR=Q3-Q1
上限=Q3+1.5IQR
下限=Q1-1.5IQR

使用matplotlib绘制箱线图:

matplotlib中有plt.boxplot来绘制箱线图,这个方法的相关参数如下:

  1. x:需要绘制的箱线图的数据。
  2. notch:是否展示置信区间,默认是False。如果设置为True,那么就会在盒子上展示一个缺口。
  3. sym:代表异常点的符号表示,默认是小圆点。
  4. vert:是否是垂直的,默认是True,如果设置为False那么将水平方向展示。
  5. whis:上下限的系数,默认是1.5,也就是上限是Q3+1.5IQR,可以改成其他的。也可以为一个序列,如果是序列,那么序列中的两个值分别代表的就是下限和上限的值,而不是再需要通过IQR来计算。
  6. positions:设置每个盒子的位置。
  7. widths:设置每个盒子的宽度。
  8. labels:每个盒子的label
  9. meanlineshowmeans:如果这两个都为True,那么将会绘制平均值的的线条。

示例代码如下:

data = np.random.rand(100)*100
# 添加两个异常值
data = np.append(data,np.array([-100,100]))
plt.boxplot(data,meanline=True,showmeans=True)

效果图如下:
在这里插入图片描述

如果有多组数据绘制箱型图,才能更好的提现出箱型图的优势。

假如我们想要获取奥林匹克运动会上不同国家运动员的身高情况,那么可以把每个国家的运动员身高数据绘制成一个箱线图,然后进行对比。示例代码如下:

athletes = pd.read_csv("athlete_events.csv")
# (中国CHN,日本JPN,韩国KOR),(埃塞俄比亚ETH,肯尼亚KEN,尼日利亚NIG),(美国USA,加拿大CAN,巴西BRA),(英国GBR,法国FRA,意大利ITA)
countries = {
    'CHN':'中国',
    'JPN':"日本",
    'KOR':'韩国',
    'USA':"美国",
    'CAN':"加拿大",
    'BRA':"巴西",
    'GBR':"英国",
    'FRA':"法国",
    'ITA':"意大利",
    'ETH':"埃塞俄比亚",
    'KEN':"肯尼亚",
    'NIG':"尼日利亚",
}
dfs = []
for code in countries.keys():
    df = athletes[(athletes['NOC'] == code)&(athletes['Age']>18)]['Height'].dropna()
    dfs.append(df)
font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=14)
plt.figure(figsize=(20,5))
plt.boxplot(dfs,showmeans=True,meanline=True,labels=countries.values())
plt.xticks(range(1,13),countries.values(),fontproperties=font)
plt.ylabel("身高(cm)",fontproperties=font)
plt.title("奥林匹克运动员身高箱线图",fontproperties=font)

效果图如下:
在这里插入图片描述

箱线图的应用场景:

  1. 直观明了地识别数据中的异常值。
  2. 利用箱线图判断数据的偏态。
  3. 利用箱线图比较几批数据的形状。
  4. 箱线图适合比较多组数据,如果知识要看一组数据的分布情况,建议使用直方图。

8. 雷达图

雷达图(Radar Chart)又被叫做蜘蛛网图,适用于显示三个或更多的维度的变量的强弱情况。比如英雄联盟中某个影响的属性(法术伤害,物理防御等),或者是某个企业在哪些业务方面的投入等,都可以用雷达图方便的表示。

使用plt.polar绘制雷达图:

matplotlib.pyplot中,可以通过plt.polar来绘制雷达图,这个方法的参数跟plt.plot非常的类似,只不过是x轴的坐标点应该为弧度(2*PI=360°)。示例代码如下:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib import font_manager
font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=12)

properties = ['输出','KDA','发育','团战','生存']
values = [40,91,44,90,95,40]
theta = np.linspace(0,np.pi*2,6)
plt.polar(theta,values)
plt.xticks(theta,properties,fontproperties=font)
plt.fill(theta,values)

效果图如下:
在这里插入图片描述

其中有几点需要注意:

  1. 因为polar并不会完成线条的闭合绘制,所以我们在绘制的时候需要在theta中和values中在最后多重复添加第0个位置的值,然后在绘制的时候就可以和第1个点进行闭合了。
  2. polar只是绘制线条,所以如果想要把里面进行颜色填充,那么需要调用fill函数来实现。
  3. polar默认的圆圈的坐标是角度,如果我们想要改成文字显示,那么可以通过xticks来设置。

使用子图绘制雷达图:

在多子图中,绘图对象不再是pyplot而是Axes,而Axes及其子类绘制雷达图则是通过将直角坐标转换成极坐标,然后再绘制折线图。示例代码如下:

  1. 使用plt.subplot绘制的子图:

     properties = ['输出','KDA','发育','团战','生存']
     values = [40,91,44,90,95,40]
     theta = np.linspace(0,np.pi*2,6)
     # 生成一个子图,并且指定子图的类型为polar
     axes = plt.subplot(111,projection="polar")
     axes.plot(theta,values)
     axes.fill(theta,values)
    

    在这里插入图片描述

  2. 使用plt.subplots绘制的子图:

     properties = ['输出','KDA','发育','团战','生存']
     values = [40,91,44,90,95,40]
     theta = np.linspace(0,np.pi*2,6)
     figure,axes = plt.subplots(1,1,subplot_kw={"projection":"polar"})
     axes.plot(theta,values)
    

在这里插入图片描述

  1. 使用fig.add_subplot绘制的子图:

     properties = ['输出','KDA','发育','团战','生存']
     values = [40,91,44,90,95,40]
     theta = np.linspace(0,np.pi*2,6)
     fig = plt.figure(figsize=(10,10))
     axes = fig.add_subplot(111,polar=True)
     axes.plot(theta,values)
    

在这里插入图片描述
总结:

雷达图:用来清晰的表示多个维度的值的强弱关系。
绘制雷达图:
    因为雷达图绘制的时候,不会自动的封闭,所以要在数据的最后多添加一个起始点的坐标。
    plt.polar绘制。
    plt.subplot(111,projection="polar")。
    figure,axes = plt.subplots(1,1,subplot_kw={"projection":"polar"})
    axes = fig.add_subplot(111,polar=True)

9. matplotlib绘图分析

在这里插入图片描述

解释:

  1. Figure:图形绘制的画板,他就相当于一个黑板,所有的图都是绘制在Figure上面。
  2. Axes:每个图都是Axes对象。一个Figure上可以有多个Axes对象。
  3. Axisx轴、y轴的对象。
  4. Tickx轴和y轴上的刻度对象。每一个刻度都是一个Tick对象。
  5. TickLabel:每个刻度上都要显示文字,这个文字的显示就是在TickLabel上。
  6. AxisLabelx轴和y轴的名称的文字显示。
  7. Legend:图例对象。
  8. TitleAxes图的标题对象。
  9. Line2D:绘制在Axes上的线条对象,比如折线图等。
  10. Reactangle:绘制在Axes上的矩形对象,比如条形图等。
  11. Marker:标记点,比如绘制散点图上的每个点就是这个对象。
  12. Artist:只要是绘制在Figure上的元素(包括Figure),都是Artist的子类。

一、Figure容器:

Figure容器是最顶层的容器,他几乎包含了这个图的所有对象。通过add_subplotadd_axes方法可以添加Axes对象,这两个方法添加的都是Axes及其子类的对象。添加完成后是存储在figure.axes中。示例代码如下:

In [156]: fig = plt.figure()
In [157]: ax1 = fig.add_subplot(211)
In [158]: ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
In [159]: ax1
Out[159]: <matplotlib.axes.Subplot instance at 0xd54b26c>
In [160]: print(fig.axes)
[<matplotlib.axes.Subplot instance at 0xd54b26c>, <matplotlib.axes.Axes instance at 0xd3f0b2c>]

1.1. 添加Axes对象:

Figure只是一个黑板,如果想要绘图,需要先添加Axes。添加Axes可以通过add_axesadd_subplot来实现。示例代码如下:

# 创建一个figure对象
fig = plt.figure()
# 添加一个Axes
ax1 = fig.add_subplot(211)
# 添加一个Axes,其中参数是left,bottom,width,height
ax2 = fig.add_axes([0.1,0.1,0.8,0.3])

1.2. 操作当前Axes对象:

可以通过figure.gca以及figure.sca来设置和获取当前的axes对象。示例代码如下:

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_axes([0,0,1,0.3])
print(fig.gca())
print(fig.sca(ax1))

>> Axes(0,0;1x0.3)
>> AxesSubplot(0.125,0.536818;0.775x0.343182)

1.3. 删除Axes对象:

Figure上的所有Axes对象都是保存在fig.axes中,但是如果想要删除某个Axes对象,那么必须通过delaxes来实现:

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_axes([0,0,1,0.3])
fig.delaxes(ax1)
print(fig.axes)

1.4. 获取所有的axes:

for ax in fig.axes:
    ax.grid(True) # 设置打开网格

1.5. Figure的属性有如下:

在这里插入图片描述

Figure类定义介绍:https://matplotlib.org/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure

二、Axes容器:

Axes容器是用来创建具体的图形的。比如画曲线,柱状图,都是画在上面。所以之前我们学的使用plt.xx绘制各种图形(比如条形图,直方图,散点图等)都是对Axes的封装。比如plt.plot对应的是axes.plot,比如plt.hist对应的是axes.hist。针对图的所有操作,都可以在Axes上找到对应的API。另外后面要讲到的Axis容器,是轴的对象,也是绑定在Axes上面。

Axes的类定义介绍:https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes

2.1. 设置x和y轴的最大值和最小值:

设置完刻度后,我们还可以设置x轴和y轴的最大值和最小值。可以通过set_xlim/set_ylim来实现:

fig = plt.figure()  
axes = fig.add_subplot(111)  
axes.plot(np.random.randn(10))

# 设置x轴的最大值和最小值
axes.set_xlim(-2,12)

# 设置y轴的最大值和最小值
axes.set_ylim(-3,3)

2.2. 添加文本:

之前添加文本我们用的是annotate,但是如果不是需要做注释,其实还有另外一种更加简单的方式,那就是使用text方法:

data = np.random.randn(10)
fig = plt.figure()
axes = fig.add_subplot(111)
axes.plot(data)
# 添加文本,比annotate更加方便
axes.text(0,0,"hello")

2.3. 绘制双Y轴:

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.bar(np.arange(0,10,2),np.random.rand(5))
ax1.set_yticks(np.arange(0,1,0.25))
ax2 = ax1.twinx() #克隆一个共享x轴的axes对象
ax2.plot(np.random.randn(10),c="b")
plt.show()

效果图如下:
在这里插入图片描述

三、Axis容器:

Axis代表的是x轴或者y轴的对象。包含Tick(刻度)对象,TickLabel刻度文本对象,以及AxisLabel坐标轴文本对象。axis对象有一些方法可以操作刻度和文本等。

3.1. 设置x轴和y轴label的位置:

fig = plt.figure()
axes = fig.add_subplot(111)
axes.plot(np.random.randn(10))
axes.set_xlabel("x coordate")
# 设置x轴label的位置为(0.-0.1)
axes.xaxis.set_label_coords(0,-0.1)

3.2. 设置刻度上的刻度格式:

import matplotlib.ticker as ticker
fig = plt.figure()
axes = fig.add_subplot(111)
axes.plot(np.random.randn(10))
axes.set_xlabel("x coordate")
# 创建格式化对象
formatter = ticker.FormatStrFormatter('%.2f')
# 设置格式化对象
axes.yaxis.set_major_formatter(formatter)

3.3. 设置轴的属性:

fig = plt.figure()

ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
ax1.set_facecolor('lightslategray')

# 设置刻度上文本的属性
for label in ax1.xaxis.get_ticklabels():
    # label是一个Label对象
    label.set_color('red')
    label.set_rotation(45)
    label.set_fontsize(16)

# 设置刻度上线条的属性
for line in ax1.yaxis.get_ticklines():
    # line是一个Line2D对象
    line.set_color('green')
    line.set_markersize(25)
    line.set_markeredgewidth(3)

plt.show()

在这里插入图片描述

四、Tick容器:

Tick是用来做刻度的,包括刻度和网格对象。其中可操作的属性如下:
在这里插入图片描述

示例代码如下:

import matplotlib.ticker as ticker

# Fixing random state for reproducibility
np.random.seed(19680801)

fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))

formatter = ticker.FormatStrFormatter('$%.2f')
ax.yaxis.set_major_formatter(formatter)

for tick in ax.yaxis.get_major_ticks():
    tick.label1On = False
    tick.label2On = True
    tick.label2.set_color('green')

plt.show()

在这里插入图片描述

更多请参考:
https://matplotlib.org/api/axis_api.html#matplotlib.axis.Axis

参考:

https://matplotlib.org/tutorials/intermediate/artists.html#sphx-glr-tutorials-intermediate-artists-py

10. 多图布局

解决元素重叠的问题:

在一个Figure上面,可能存在多个Axes对象,如果Figure比较小,那么有可能会造成一些图形元素重叠,这时候我们就可以通过fig.tight_layout或者是fig.subplots_adjust方法来帮我们调整。假如现在没有经过调整,那么以下代码的效果图如下:

import matplotlib.pyplot as plt
import numpy as np

def example_plot(ax, fontsize=12):
    ax.plot([1, 2])
    ax.set_xlabel('x-label', fontsize=fontsize)
    ax.set_ylabel('y-label', fontsize=fontsize)
    ax.set_title('Title', fontsize=fontsize)

fig,axes = plt.subplots(2,2)
fig.set_facecolor("y")
example_plot(axes[0,0])
example_plot(axes[0,1])
example_plot(axes[1,0])
example_plot(axes[1,1])

效果图如下:
在这里插入图片描述

为了避免多个图重叠,可以使用plt.tight_layout来实现:

# 之前的代码...
plt.tight_layout()

效果图如下:
在这里插入图片描述

其中tight_layout还有两个参数可以使用,分别是w_padh_pad,这两个参数分别表示的意思是在水平方向的图之间的间距,以及在垂直方向这些图的间距。

另外也可以通过fig.subplots_adjust(left=None,bottom=None,right=None,top=None,wspace=None,hspace=None)来实现,效果如下:

# 之前的代码...
fig.subplots_adjust(0,0,1,1,hspace=0.5,wspace=0.5)

效果图如下:
在这里插入图片描述

自定义布局方式:

如果布局不是固定的几宫格的方式,而是某个图占据了多行或者多列,那么就需要采用一些手段来实现。如果不是很复杂,那么直接可以通过subplot等方法来实现。示例代码如下:

ax1 = plt.subplot(221)
ax2 = plt.subplot(223)
ax3 = plt.subplot(122)

效果图如下:
在这里插入图片描述

但是如果实现的布局比较复杂,那么就需要采用GridSpec对象来实现。示例代码如下:

fig = plt.figure()
# 创建3行3列的GridSpec对象
gs = fig.add_gridspec(3,3)
ax1 = fig.add_subplot(gs[0,0:3])
ax1.set_title("[0,0:3]")
ax2 = fig.add_subplot(gs[1,0:2])
ax2.set_title("[1,0:2]")
ax3 = fig.add_subplot(gs[1:3,2])
ax3.set_title("[1:3,2]")
ax4 = fig.add_subplot(gs[2,0])
ax4.set_title("[2,0]")
ax5 = fig.add_subplot(gs[2,1])
ax5.set_title("[2,1]")
plt.tight_layout()

效果图如下:
在这里插入图片描述

也可以设置宽高比例。示例代码如下:

# 设置宽度比例为1:2:1
widths = (1,2,1)
# 设置高度比例为2:2:1
heights = (2,2,1)
fig = plt.figure()
# 创建GridSpec对象的时候指定宽高的比
gs = fig.add_gridspec(3,3,width_ratios=widths,height_ratios=heights)
for row in range(0,3):
    for col in range(0,3):
        fig.add_subplot(gs[row,col])
plt.tight_layout()

效果图如下:
在这里插入图片描述

手动设置位置:

通过fig.add_axes的方式添加Axes对象,可以直接指定位置。也可以在添加完成后,通过axes.set_position的方式设置位置。示例代码如下:

# add_axes的方式
fig = plt.figure()
fig.add_subplot(111)
fig.add_axes([0.2,0.2,0.4,0.4])

# 设置position的方式
fig,axes = plt.subplots(1,2)
axes[1].set_position([0.2,0.2,0.4,0.4])

散点图和直方图合并实战:

fig = plt.figure(figsize=(8,8))
widths = (2,0.5)
heights = (0.5,2)
gs = fig.add_gridspec(2,2,width_ratios=widths,height_ratios=heights)
# 顶部的直方图
ax1 = fig.add_subplot(gs[0,0])
ax1.hist(male_athletes['Height'],bins=20)
for tick in ax1.xaxis.get_major_ticks():
    tick.label1On = False

# 中间的散点图
ax2 = fig.add_subplot(gs[1,0])
ax2.scatter('Height','Weight',data=male_athletes)

# 右边的直方图
ax3 = fig.add_subplot(gs[1,1])
ax3.hist(male_athletes['Weight'],bins=20,orientation='horizontal')
for tick in ax3.yaxis.get_major_ticks():
    tick.label1On = False
fig.tight_layout(h_pad=0,w_pad=0)

效果图如下:
在这里插入图片描述

11. matplotlib配置

修改默认的配置:

修改默认的配置可以通过matplotlib.rcParams来设置,比如修改字体,修改线条大小和宽度等。示例代码如下:

import matplotlib.pyplot as plt
# 设置字体为仿宋
plt.rcParams['font.sans-serif'] = ['FangSong']
# 设置字体大小为20
plt.rcParams['font.size'] = 20
# 设置线条宽度
plt.rcParams['lines.linewidth'] = 2
# 设置线条颜色
plt.rcParams['axes.prop_cycle'] = plt.cycler('color', ['r', 'y'])

其中rcParams中可以设置的属性为如下:

Windows上如果想要显示中文,那么可以通过设置font.sans-serif来设置,示例代码如下:

plt.rcParams['font.sans-serif'] = ['FangSong']

这个属性可以设置以下字体都可以显示中文:

字体名英文名称
黑体SimHei
仿宋FangSong
楷体KaiTi
宋体SimSun
隶书LiSu
幼圆YouYuan
华文细黑STXihei
华文楷体STKaiti
华文宋体STSong
华文中宋STZhongsong
华文仿宋STFangsong
方正舒体FZShuTi
方正姚体FZYaoti
华文彩云STCaiyun
华文琥珀STHupo
华文隶书STLiti
华文行楷STXingkai
华文新魏STXinwei

MacLinux支持的字体可能会不同,如果不行,可以使用matplotlib.font_manager来指定具体的字体。

自定义配置文件:

有时候我们可能需要设置一大堆参数,并且这个配置在后面很多项目中可能都会用到,那么这时候我们就可以把这些配置信息放到文件中(可配置项见下),文件的命名规则为[名称].mplstyle,然后把这个文件放到matplotlib.get_configdir()/stylelib的目录中,在写代码的时候根据名称加载这个配置文件,示例代码如下:

plt.style.use("名称")

可配置项:

更多可配置项请参考:https://raw.githubusercontent.com/matplotlib/matplotlib/master/matplotlibrc.template

12. matplotlib作业

一、折线图作业要求:

  1. 以下是长沙某一个月的天气数据,按照时间的顺序绘制成折线图,其中数据highest是最高温度,lowest是最低温度。最高温度线条用红色,最低温度线条用蓝色。
  2. 具体的坐标点,用圆点marker表示。
  3. 把x轴的时间刻度按照1-31标记出来,并且标记x轴和y轴的标题。
  4. 图的标题是“长沙5月份气温走势”。

数据:

highest = [26,21,26,26,22,20,17,19,22,28,30,28,24,28,25,26,25,26,25,23,24,30,32,31,30,27,26,27,29,25,25]
lowest =  [17,13,17,18,18,17,14,15,16,18,19,20,18,18,20,20,20,20,20,16,17,19,21,24,24,23,20,18,19,18,19]

效果图参考:
在这里插入图片描述

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib import font_manager

highest = [26,21,26,26,22,20,17,19,22,28,30,28,24,28,25,26,25,26,25,23,24,30,32,31,30,27,26,27,29,25,25]
lowest =  [17,13,17,18,18,17,14,15,16,18,19,20,18,18,20,20,20,20,20,16,17,19,21,24,24,23,20,18,19,18,19]
plt.figure(figsize=(15,5))
# 设置字体
font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=12)
# 绘制最高温度折线
plt.plot(highest,color='r',marker='o')
# 绘制最低温度折线
plt.plot(lowest,color='b',marker='o')
# 设置x轴的坐标和标题
plt.xticks(range(31),range(1,32),fontproperties=font)
plt.xlabel("日期(天)",fontproperties=font)
# 设置y轴的坐标和文本
plt.yticks(range(10,40,5),range(10,40,5))
plt.ylabel("温度(℃)",fontproperties=font)
# 设置标题
plt.title("长沙5月份气温走势",fontproperties=font)
# 添加最高温度注释文字
for x in range(0,31):
    temp = highest[x]
    plt.annotate(temp,xy=(x,temp),xytext=(x-0.2,temp+0.5))
# 添加最低温度注释文字
for x in range(0,31):
    temp = lowest[x]
    plt.annotate(temp,xy=(x,temp),xytext=(x-0.2,temp+0.5))
# 绘制网格
plt.grid()
plt.show()

二、条形图作业要求:

  1. 以下数据是三类学校(普通本科、中等职业教育、普通高中)在2014-2018(包含2018)的报名人数,用DataFrame构建。
  2. 把年份当做x轴,报名人数当做y轴的值。
  3. 绘制分组条形图,同一个年份的放在一个组。
  4. 图例横向排列(提示:用legend的ncol参数,ncol表示的是把图例分成多少列显示)。
  5. 把报名人数在图上绘制出来。

数据:

data = {
    "普通本科":[721,738,749,761,791],
    "中等职业教育": [620,601,593,582,557],
    "普通高中": [797,797,803,800,793]
}
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib import font_manager

data = {
    "普通本科":[721,738,749,761,791],
    "中等职业教育": [620,601,593,582,557],
    "普通高中": [797,797,803,800,793]
}
df = pd.DataFrame(data=data)
df

在这里插入图片描述

font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=12)
# 设置图的大小
plt.figure(figsize=(15,5))
bar_width = 0.2
# x轴的刻度
xticks = np.arange(2014,2019)
# 循环列,按照年份绘制条形图
for index,column in enumerate(df.columns):
    values = df[column]
    c_xticks = xticks+bar_width*(index-1)
    plt.bar(c_xticks,values,width=bar_width,label=column)
    for x,y in zip(c_xticks,values):
        plt.annotate(y,xy=(x,y),xytext=(x-0.05,y+10))

# 设置Y轴顶部的最大值
plt.ylim(top=1000)
# 设置Y轴的标题显示,默认是垂直显示,使用rotation=horizontal变成横向显示,并且通过y修改在y轴的位置
plt.ylabel("万人",fontproperties=font,rotation="horizontal")
# 通过set_label_coords才能灵活设置ylabel的位置。以下代码可选实现(不懂删掉没有任何关系)
plt.gca().yaxis.set_label_coords(-0.02,1.02)
# 设置图例,ncol表示要把图例显示成几列,loc表示在Axes中的哪个位置
plt.legend(prop=font,ncol=3,loc='upper right')
# 设置标题
plt.title("2014-2018普通本科、中等职业教育、普通高中招生人数",fontproperties=font)
plt.show()

在这里插入图片描述

三、直方图作业要求:

  1. 用pandas从scores.csv读取出来,形成一个DataFrame对象。
  2. 绘制化学成绩的直方图(chem列)。
  3. 标记x轴的坐标。
  4. 标记每个条形上的具体数值。

数据:
matplotlib代码->作业参考文件夹的scores.csv文件中。

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib import font_manager

scores_df = pd.read_csv("scores.csv")

font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=14)
plt.figure(figsize=(15,5))
nums,bins,_ = plt.hist(scores_df['chem'],bins=20,edgecolor="k")
for num,bin in zip(nums,bins):
    plt.annotate("%d"%num,xy=(bin,num),xytext=(bin+0.8,num+1))
plt.xticks(bins,['%.2f'%x for x in bins])
plt.title("某班化学成绩直方图",fontproperties=font)
plt.show()

在这里插入图片描述

四、散点图作业要求:

  1. 把guazi_bj(北京)、guazi_gz(广州)、guazi_sh(上海)、guazi_sz(深圳)二手车的数据归类在一个DataFrame中。
  2. 新增车辆使用年份(use_year)与保值率(hedge_rate)两个字段。其中使用年份的计算是把当前的时间减去购买的时间,然后再转换成年;保值率的计算是将二手车的价格/新车的价格。
  3. 把二手车使用年份与保值率(二手车价/新车价格)绘制成散点图,观察他们的分布情况。
  4. 把二手车的行驶距离与保值率(二手车价/新车价格)绘制成散点图,观察他们的分布情况。

在这里插入图片描述
在这里插入图片描述

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from datetime import datetime

guazi_bj = pd.read_csv("guazi_bj.csv")
guazi_gz = pd.read_csv("guazi_gz.csv")
guazi_sh = pd.read_csv("guazi_sh.csv")
guazi_sz = pd.read_csv("guazi_sz.csv")

# 数据预处理
guazi = pd.concat([guazi_bj,guazi_gz,guazi_sh,guazi_sz],axis=0)
def get_use_year(value):
    if isinstance(value,str):
        datetime_value = datetime.strptime(value,"%Y-%m")
        now = datetime.now()
        yeardelay = (now - datetime_value).total_seconds()/60/60/24/30/12
        return yeardelay
    return np.NAN
guazi['use_year'] = guazi['buy_time'].apply(get_use_year)
guazi['hedge_rate'] = guazi['es_price'] / guazi['new_price']
guazi[['use_year','km','hedge_rate']].head()

在这里插入图片描述

plt.figure(figsize=(15,5))
plt.scatter(guazi['km'],guazi['hedge_rate'],s=guazi['km'])

在这里插入图片描述

plt.figure(figsize=(15,5))
plt.scatter(guazi['use_year'],guazi['hedge_rate'],s=guazi['km'])
plt.xlabel("use year")
plt.ylabel("hedge rate")

在这里插入图片描述

guazi[(guazi['hedge_rate'] > 0.9) & (guazi['use_year'] > 3)][['new_price','es_price','use_year','km']].head()

在这里插入图片描述

guazi[(guazi['hedge_rate'] > 0.9) & (guazi['use_year'] > 6)][['new_price','es_price','use_year','use_year']].head()

在这里插入图片描述
观察结果:

  1. 通过以上分析,我们可以看到汽车的保值率是随着使用年份和行驶公里数的增加呈现线性下降的。
  2. 有一部分数据引起我们的注意,就是保值率大于0.9,并且使用年份和行驶公里数都比较大的数据,我们可以看出这类数据基本上可以算是异常数据了,因此以后在分析的时候就可以处理掉这部分数据了。

五、饼图作业要求:

  1. 把以下数据绘制成饼图。
  2. 把Chrome浏览器的模块分割开0.05。
  3. 设置阴影。
  4. 把百分数的颜色设置成白色,把浏览器的名字颜色设置成黑色。
  5. 把Edge和Safari浏览器的比例文字字体大小调成10,其他的12。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib import font_manager

browsers = {
    "Chrome": 0.6098,
    "Internet Explorer": 0.1218,
    "FireFox": 0.1147,
    "Edge": 0.0415,
    "Safari": 0.0372,
    "其他浏览器": 0.075
}
font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=12)
patches,texts,autotexts = plt.pie(browsers.values(),explode=(0.05,0,0,0,0,0),labels=browsers.keys(),textprops={"fontproperties":font},autopct="%.2f%%",shadow=True)
for index,autotext in enumerate(autotexts):
    autotext.set_color("w")
    if index == 3 or index == 4:
        autotext.set_size(10)
plt.show()

在这里插入图片描述

六、箱线图作业:

  1. 读取scores.csv文件。
  2. 把所有科目的成绩都在一张图上绘制箱线图。
  3. 观察这个图,你能发现什么信息。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib import font_manager

scores = pd.read_csv("scores.csv").drop(["num","class"],axis=1)
scores.head()

在这里插入图片描述

plt.figure(figsize=(15,5))
font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=12)
plt.boxplot([scores[column] for column in scores.columns])
plt.xticks(range(1,11),scores.columns)
plt.title("某班成绩分布情况",fontproperties=font)
plt.xticks(range(1,11),["语文","数学","英语","物理","化学","政治","生物","历史","地理","体育"],fontproperties=font)
plt.xlabel("科目",fontproperties=font)
plt.ylabel("成绩",fontproperties=font)
plt.show()

在这里插入图片描述
结论:

  1. 语文成绩盒子比较小,说明其中50%的同学分数相差都不大,但是有许多下限的异常值,说明考得不好的也估计占了20%左右,并且在上限有一个异常值,这个人考得特别好,关注下这个人,分析下他平时的上课表现。
  2. 整体来说数学和英语的成绩是比较偏好的,但是也存在很多偏科的学生。
  3. 还是数学和英语成绩,数学有75%以上的学生都是在80分以上,英语有75%以上的学生在70分以上,但是剩下的25%的学生的成绩就差别很大了,直接从几分70几分,还有大部分的异常值,说明数学这两个学科有部分人是偏科很厉害的。
  4. PE课(体育课)成绩比较最集中,但是也不高,都是在60的边缘。出现这个问题,有可能是学生平时锻炼得少了,需要关注。
  5. chem(化学)没有出现异常值,并且盒子的高度也不高,整体的分数也都不高,说明这个学科大家考得都不好,要么是试卷太难,要么就是真的没太多人学好了。

七、雷达图作业:

  1. 读取scores.csv文件成DataFrame对象。
  2. 计算每个科目的平均成绩。
  3. 将每个科目的平均成绩绘制成雷达图。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib import font_manager
font = font_manager.FontProperties(fname=r"C:\\Windows\\Fonts\\msyh.ttc",size=12)

scores = pd.read_csv("scores.csv").drop(['num','class'],axis=1)
scores.head()

在这里插入图片描述

theta = np.linspace(0,2*np.pi,11)
means = np.append(scores.mean().values,scores['chn'].mean())
plt.polar(theta,means)
plt.xticks(theta,['语文','数学','英语','物理','化学','政治','生物','历史','地理','体育'],fontproperties=font)
plt.fill(theta,means)
plt.show()

在这里插入图片描述


加油!

感谢!

努力!

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-19 11:52:51  更:2021-10-19 11:53:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 8:44:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码