matplotlib绘制图形

十年热恋 提交于 2020-01-07 02:44:47

为什么使用matplotlib

matplotlib是python中一款功能非常强大的绘图组件,可以根据给定的数据绘制出多种不同的形状,比如直方图、条形图、柱状图、散点图等,就像前端的echart那样,可以将分析后的数据使用形状展示出来,通过图形更加直观的展现出数据内在的规律和趋势

matplotlib通常是数据分析的最后一环,通过python其他的工具对数据进行处理之后,再使用matplotlib对数据绘图

总结来说,matplotlib的作用如下

1.能将数据进行可视化,更直观的呈现
2.使数据更加客观、更具说服力

matplotlib环境安装

matplotlib直接可以使用pip命令即可完成安装,但是个人在安装的时候发现非常慢,因此建议使用豆瓣源的镜像地址安装,执行如下几行命令即可

pip install matplotlib -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install numpy -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install pandas -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
pip install seaborn scipy  -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

大家可只安装matplotlib即可,numpy 、pandas 是后续做数据分析和处理才会使用的

matplotlib绘制常用的几种图形

matplotlib官方网站:https://matplotlib.org/gallery/index.html

1、折线图

我们在中学时代学习过二维坐标系,知道了在平面二维坐标系中要确定一条 直线,只需要确定两个点即可,那么使用matplotlib绘制线条也是如此

import matplotlib.pyplot as plt

name = ['Tom','Dick','Harry','Slim','Jim']
age = [23,26,19,33,21]

plt.plot(name,age)
plt.show()

运行上述代码,呈现出下面的形状
在这里插入图片描述
简单那解释下,使用matplotlib绘制图形的时候,需要确定的要素大概有如下几点

  1. 横坐标X轴和纵坐标Y轴的数据来源,比如上例的name代表X轴,年龄代表Y轴
  2. 图形的标注和说明,上图中我们并没有具体解释X轴和Y轴具体的含义,或者图形的标题等,不懂得意思的话看了可能一脸懵逼
  3. 轴间距,X轴、Y轴上两个数据之间的距离多大才算合理,间距的设定可以影响图形的形状,对整体的走势可能有影响
  4. 图形的颜色、背景,在某些情况下,我们想看看图形中展示出来的点大概是落在什么样的区间内,或者某些点需要重点标注,这些都需要进行设置

这样一来,我们再在上面的基础上添加一些参数,使得图形看起来更丰满一些

import matplotlib.pyplot as plt
#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

name = ['Tom','Dick','Harry','Slim','Jim']
age = [23,26,19,33,21]

#使用数据填充X轴和Y轴
plt.plot(name,age,label="个人折线图")
#设置显示网格,alpha为透明度
plt.grid(alpha=0.6)

#设置X和Y轴的含义备注
plt.xlabel("姓名")
plt.ylabel("年龄")
plt.title("小组姓名年龄折线图")
plt.legend()

#显示图形
plt.show()

运行代码后,展示出来的图形如下:
在这里插入图片描述

在上述代码中,当我们需要在图形中添加一些中文相关的内容的时候,如果直接使用会出现乱码问题,解决的办法,一个是代码中写死的那一段,还有一种办法是使用font_manager引入本地的字体,

font_manager.FontProperties(fname=“本地字体路径”)

其实上述添加的内容,基本上都是参照官网的API进行配置的,更多的参数可以参考官网,或者点击源码进行学习,多绘制一些图形就能掌握里面的用法和各个参数的具体内涵

调整刻度

即设置显示X轴或Y轴上的步长,在很多时候,一开始我们设定显示X轴或Y轴的数据出来的图形并不是非常满意,或者X轴上需要展示拼接出来的字符,就需要调整间隔来趋近完善,matplotlib设置步长调用xticks或yticks的方法,下面来看一个具体的例子

from matplotlib import pyplot as plt, font_manager

#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

#X轴和Y轴的数据量要一致
y = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]
x = range(11,31)

plt.plot(x,y,color="orange",linewidth="3")

#设置X轴展示刻度
x_ticket = ["{}岁".format(i) for i in x]
plt.xticks(x,x_ticket)
plt.yticks(range(0,9))

#设置图形提示
plt.xlabel("年龄")
plt.ylabel("交友数")
plt.title("年龄交朋友占比")

#显示网格
plt.grid(alpha=0.4)

plt.show()

在这里插入图片描述

2、柱状图

柱状图通常用于一组并没有直接关联关系的数据,需要做数据的对比时可以考考虑使用,下面对比一下5部电影的票房数量

from matplotlib import pyplot as plt

#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

x=["战狼2","速度与激情8","功夫瑜伽","西游伏妖篇","摔跤吧!爸爸"]
y=[56.01,26.94,17.53,16.49,15.45]

#绘制直方图
plt.bar(range(len(x)),y,width=0.3,color="green")

#设置X轴的对应字符串关系,rotation设置字体选装角度
plt.xticks(range(len(x)),x,rotation=45)

plt.xlabel("电影名称")
plt.ylabel("票房")
plt.title("电影票房柱状图")

plt.show()

在这里插入图片描述

3、水平柱状图

在某些场景下,还可以通过水平柱状图(水平条形图)来展示,水平的形状从视觉感上来说,对比的效果更佳明显,水平柱状图的语法为:plt.barh(),传入相关的参数即可

from matplotlib import pyplot as plt

#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

x = ["战狼2","速度与激情8","功夫瑜伽","西游伏妖篇","变形金刚5:最后的骑士","摔跤吧!爸爸","加勒比海盗5:死无对证","金刚:骷髅岛","极限特工:终极回归","生化危机6:终章","乘风破浪","神偷奶爸3","智取威虎山","大闹天竺","金刚狼3:殊死一战","蜘蛛侠:英雄归来","悟空传","银河护卫队2","情圣","新木乃伊",]
y=[56.01,26.94,17.53,16.49,15.45,12.96,11.8,11.61,11.28,11.12,10.49,10.3,8.75,7.55,7.32,6.99,6.88,6.86,6.58,6.23]

#绘制水平直方图
plt.barh(range(len(x)),y,height=0.3,color="orange",label="我的票房统计图")

#设置X轴的对应字符串关系
plt.yticks(range(len(x)),x)

#展示具体的数值
for x, y in enumerate(y):
    plt.text(y + 0.2, x - 0.1, '%s' % y)

#设置网格
plt.grid(alpha=0.7)

plt.xlabel("票房单位:亿")
plt.ylabel("电影名称")
plt.title("电影票房统计")

plt.legend()

plt.show()

最终展示的效果如下:
在这里插入图片描述

4、散点图

散点图也称作离散图,通常用于一些大批量看起来无规律的数据中,通过散点图展示数据的分布和聚合情况,matplotlib.pyplot.scatter()函数可用于绘制散点图,该函数的主要参数如下

matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, hold=None, data=None, **kwargs)

x,y组成了散点的坐标;s为散点的面积;c为散点的颜色(默认为蓝色’b’);marker为散点的标记;alpha为散点的透明度(0与1之间的数,0为完全透明,1为完全不透明);linewidths为散点边缘的线宽;如果marker为None,则使用verts的值构建散点标记;edgecolors为散点边缘颜色。
其他参数如cmap为colormap;norm为数据亮度;vmin、vmax和norm配合使用用来归一化亮度数据,这些与数据亮度有关

绘制一个普通的散点图

import matplotlib.pyplot as plt
import numpy as np

# 10个点
N = 10
x = np.random.rand(N)
y = np.random.rand(N)
plt.scatter(x, y)
plt.show()

运行代码,效果如下:
在这里插入图片描述

当然,我们也可以设置scatter中的参数,来控制散点大小,颜色等

import matplotlib.pyplot as plt
import numpy as np

# 10个点
N = 10
x = np.random.rand(N)
y = np.random.rand(N)

# 每个点随机大小
s = (30*np.random.rand(N))**2
# 随机颜色
c = np.random.rand(N)
plt.scatter(x, y, s=s, c=c, alpha=0.5)

plt.show()

这时,可以看到,散点的大小都是随机的
在这里插入图片描述

下面看一个具体的需求,绘制某城市4月份和10月份白天的气温散点图,原始数据如下

t4 = [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]
t10 = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]

X轴代表天,Y轴代表温度,为了不至于X轴显示的数据过于密集,轴距为3

from matplotlib import pyplot as plt

#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

y_4 = [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]
y_10 = [26,26,28,19,21,17,16,19,18,20,20,19,22,23,17,20,21,20,22,15,11,15,5,13,17,10,11,13,12,13,6]

x_4 = range(1,32)
x_10 = range(51,82)

plt.scatter(x_4,y_4,label = "四月份")
plt.scatter(x_10,y_10,label="十月份")

#调整X轴的刻度
_x = list(x_4) + list(x_10)
_x_tick_labels = ["4月{}日".format(i) for i in x_4]
_x_tick_labels += ["10月{}日".format(i-50) for i in x_10]

#设置X轴的间隔为3
plt.xticks(_x[::3],_x_tick_labels[::3],rotation=45)
plt.legend()

#设置图示
plt.xlabel("月份")
plt.ylabel("气温")
plt.title("月份气温变化图")

plt.show()

运行上述代码,效果展示如下:
在这里插入图片描述

5、条形图

个人理解条形图其实可以包含柱状图,但在某些情况下,条形图涵盖的范围似乎更加广一些,比如要统计某种业务指标的连续性数据并对进行对比的时候,就可以考虑使用条形图

下面有一个具体的需求,知道了某个某个地区多个门店的8,9,10三个月份的销售数据,需要用图形展示出来

from matplotlib import pyplot as plt

#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

a = ["西湖区分部","余杭区分部","江干区分部","滨江区分部"]
m_8 = [2358,399,2358,362]
m_9 = [12357,156,2045,168]
m_10 = [15746,312,4497,319]

bar_width=0.2
x_8 = list(range(len(a)))
x_9 = [i + bar_width for i in x_8]
x_10 = [i + 2 * bar_width for i in x_8]

plt.bar(range(len(a)),m_8,width=bar_width,label="8月份")
plt.bar(x_9,m_9,width=bar_width,label="9月份")
plt.bar(x_10,m_10,width=bar_width,label="10月份")

#设置X轴刻度
plt.xticks(x_9,a)

#设置图形标识
plt.xlabel("分部名称")
plt.ylabel("销售业绩")
plt.title("某销售公司8-10月份各区域销售情况")

plt.legend()

plt.show()

在这里插入图片描述

6、直方图

直方图是数值数据分布的精确图形表示,直方图是用来整理计量值的观测数据,分析其分布状态的统计方法,用于对总体的分布特征进行推断。

直方图由竖立在x轴上的多个相邻的矩形组成,这些矩形把x轴拆分为一段段彼此不重叠的线段(线段两个端点所标识的数据范围也叫面元),矩形的面积跟落在其所对应的面元的元素数量成正比。这种可视化方法常被用于样本分布等统计研究。

pyplot用于绘制直方图的函数为hist( ),该函数具有一个其他绘图函数所没有的功能。它除了绘制直方图外,还以元组形式返回直方图的计算结果。事实上,hist( )函数还可以实现直方图的计算。也就是说,它能够接受一系列样本个体和期望的面元数量作为参数,会把样本范围分为多个区间(面元),然后计算每个面元所包含的样本个体的数量,运算结果除了以图形形式表示外,还能以元组形式返回,其参数包括:

(n, bins, patches)

下面通过一个具体的需求看看直方图的绘制和使用,比如有如下一组数据

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]

这组数据代表的是市面上电影的时长,我们需要统计一下,不同时长的电影所在占的范围,

在绘制直方图中,有几点需要注意,也就是绘制直方图中的3个参数(n, bins, patches),下面对其中的主要参数做简要说明

plt.hist(data, bins=40, normed=0, facecolor=“blue”, edgecolor=“black”, alpha=0.7)

data:必选参数,绘图数据
bins:直方图的长条形数目,可选项,默认为10
normed:是否将得到的直方图向量归一化,可选项,默认为0,代表不归一化,显示频数。normed=1,表示归一化,显示频率。
facecolor:长条形的颜色
edgecolor:长条形边框的颜色
alpha:透明度

绘制直方图,组距和分组数是非常重要的两个参数,他们决定直方图整体的显示样式,比如,上述的一组电影时长数据,X轴要分成多少个竖条(组)合适呢?我们可以首先通过len(a)计算一下列表中数据的个数,一开始我们可以设置的稍微粗一点,即间距可设置的大一点,如果展示的效果达不到统计的效果再调小

num_bins的确定,通常可以根据原始数据的最大值和最小值再除以间距确定,最后再微调,代码如下:



#绘制直方图
#直方图一般为原始的数据,拿到后统计区间频率
from matplotlib import pyplot as plt

#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

a=[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]

#计算机组距,也就是频率数之间的间隔
d=3
num_bins=(max(a)-min(a))//d + 1

print(num_bins)

#计算要分的组数,density=True设置Y轴是否以小数(百分数)统计
plt.hist(a,num_bins,density=True,facecolor="orange", edgecolor="black", alpha=0.7)
#设置X轴的刻度
plt.xticks(range(min(a),max(a)+d,d))
plt.grid(alpha=0.3)

plt.show()

在这里插入图片描述

以上通过几个简单的案例展示了一下使用matplotlib绘制常用的几种图形用法,内容比较简单,matplotlib一般并不单独使用,而是集合其他的数据分析工具一起使用才更能体现数据可视化的效果,本篇到此结束,最后感谢观看!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!