1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > python学习之数据分析(二):Matplotlib库:常用画图技巧 折线图 散点图 柱状图 直方图 饼图

python学习之数据分析(二):Matplotlib库:常用画图技巧 折线图 散点图 柱状图 直方图 饼图

时间:2020-05-30 22:25:08

相关推荐

python学习之数据分析(二):Matplotlib库:常用画图技巧  折线图  散点图 柱状图 直方图  饼图

一、Matplotlib之HelloWorld

1. 什么是Matplotlib:

专门用于开发2D图表(包括3D图表)使用起来及其简单以渐进、交互式方式实现数据可视化

2. matplotlib的效果:

可视化是在整个数据挖掘的关键辅助工具,可以清晰的理解数据,从而调整我们的分析方法。

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

例如下面两个图为数字展示和图形展示:

3. 实现一个简单的matplotlib画图:

import matplotlib.pyplot as pltif __name__ == "__main__":plt.figure(figsize=(20,8)) # 画布大小,可以不写或参数为空,则使用默认大小plt.plot([1,2,3], [4,5,6]) # x轴坐标, y轴plt.show()

4. matplotlib的图像结构:三层结构

4.1 容器层:

容器层主要由Canvas、Figure、Axes组成。

Canvas是位于最底层的系统层,在绘图的过程中充当画板的角色,即放置画布(Figure)的工具。

Figure是Canvas上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。

Axes是应用层的第二层,在绘图的过程中相当于画布上的绘图区的角色。

Figure:指整个图形(可以通过plt.figure()设置画布的大小和分辨率等)Axes(坐标系):数据的绘图区域Axis(坐标轴):坐标系中的一条轴,包含大小限制、刻度和刻度标签

特点为:

一个figure(画布)可以包含多个axes(坐标系/绘图区),但是一个axes只能属于一个figure。一个axes(坐标系/绘图区)可以包含多个axis(坐标轴),包含两个即为2d坐标系,3个即为3d坐标系

4.2 辅助显示层:

辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括

Axes外观(facecolor)边框线(spines)坐标轴(axis)坐标轴名称(axis label)坐标轴刻度(tick)坐标轴刻度标签(tick label)网格线(grid)图例(legend)标题(title)等内容。

该层的设置可使图像显示更加直观更加容易被用户理解,但又不会对图像产生实质的影响

4.3 图像层

图像层指Axes内通过plot、scatter、bar、histogram、pie等函数根据数据绘制出的图像。

4.4 总结:

Canvas(画板)位于最底层,用户一般接触不到Figure(画布)建立在Canvas之上Axes(绘图区)建立在Figure之上坐标轴(axis)、图例(legend)等辅助显示层以及图像层都是建立在Axes之上

二、折线图(plot)与基础绘图功能:

1.折线图绘制与保存图片:

为了更好地理解所有基础绘图功能,我们通过天气温度变化的绘图来融合所有的基础API使用

matplotlib.pyplot模块

matplotlib.pytplot包含了一系列类似于matlab的画图函数。 它的函数作用于当前图形(figure)的当前坐标系(axes)。

import matplotlib.pyplot as plt

2 折线图绘制与显示

展现上海一周的天气,比如从星期一到星期日的天气温度如下

# 1)创建画布(容器层)plt.figure()# 2)绘制折线图(图像层)plt.plot([1, 2, 3, 4, 5, 6 ,7], [17, 17, 18, 15, 11, 11, 13])# 3)显示图像plt.show()

3 设置画布属性与图片保存:

plt.figure(figsize=(), dpi=)figsize:指定图的长宽dpi:图像的清晰度返回fig对象plt.savefig(path)

# 1)创建画布,并设置画布属性plt.figure(figsize=(20, 8), dpi=80)# 2)保存图片到指定路径plt.savefig("test.png")

注意:plt.show()会释放figure资源,如果在显示图像之后保存图片将只能保存空图片。

4. 案例:显示温度变化状况:

需求:画出某城市11点到12点1小时内每分钟的温度变化折线图,温度范围在15度~18度

效果:

4.1 准备数据并画出初始折线图

import randomimport matplotlib.pyplot as plt# 生成温度数据x = range(60)shanghai = [random.uniform(15,18) for _ in x]plt.figure(figsize=(10,4), dpi=80)# 绘制图形plt.plot(x,shanghai)plt.xticks(x_value, [f"11:{i}" for i in x_value])# 显示图像plt.show()

4.2 添加自定义x,y刻度:

plt.xticks(x, **kwargs)

x:要显示的刻度值

plt.yticks(y, **kwargs)

y:要显示的刻度值

# 生成温度数据x = range(60)shanghai = [random.uniform(15,18) for _ in x]plt.figure(figsize=(10,4), dpi=80)# 绘制图形plt.plot(x,shanghai)# 设置辅助显示层plt.yticks(range(0, 41)[::5])x_value = x[::5]plt.xticks(x_value, [f"11:{i}" for i in x_value])# 显示图像plt.show()

4.3 中文显示问题解决

下载中文字体(黑体,看准系统版本)

下载 SimHei 字体(或者其他的支持中文显示的字体也行)

1) 安装字体

windows和mac下:双击安装linux下:拷贝字体到 usr/share/fonts 下:

sudo cp ~/SimHei.ttf /usr/share/fonts/SimHei.ttf

注)Linux如果用ubantu也可以通过双击安装

2) 删除matplotlib缓存文件

Mac系统的解决方案:

删除~/.matplotlib中的缓存文件

cd ~/.matplotlibrm -r *

Linux系统的解决方案

删除~/.cache/matplotlib中的缓存文件

cd ~/.cache/matplotlibrm -r *

3) 修改配置文件matplotlibrc

Mac系统的解决方案:修改配置文件matplotlibrc

vi ~/.matplotlib/matplotlibrc

将文件内容修改为:

font.family : sans-seriffont.sans-serif : SimHeiaxes.unicode_minus : False

Linux系统的解决方案

修改配置文件

sudo find -name matplotlibrc

返回结果:

./.virtualenvs/ai/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc

打开配置文件:

vi ./.virtualenvs/ai/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc

将配置文件中下面3项改为如下所示:

font.family : sans-seriffont.sans-serif : SimHeiaxes.unicode_minus : False

4.3 添加标题, 描述信息显示:

plt.title(str_title, fontsize=20)# 添加标题并设置字体大小plt.xlabel(str_xlabel, color=‘r’,fontsize=16) # 添加X轴标题并设置字体大小plt.ylabel(str_xlabel, color=‘r’,fontsize=16)

4.4 添加网格显示

为了更加清楚地观察图形对应的值

plt.grid(True, linestyle=’–’, alpha=0.5)

常见的颜色及风格字符:

4.5 再添加一个城市的温度变化

设置显示图例:

plt.legend(loc="best")

绘制图形的时候需要设置图形标题label;设置图例显示说明的位置;

# 生成温度数据x = range(60)shanghai = [random.uniform(15,18) for _ in x]beijing = [random.uniform(5,8) for _ in x]plt.figure(figsize=(10,4), dpi=80)# 绘制图形plt.plot(x,shanghai,label="上海")plt.plot(x,beijing, label="北京")# 设置x,y轴的显示plt.yticks(range(0, 41)[::5])x_value = x[::5]plt.xticks(x_value, [f"11点{i}" for i in x_value])# 设置图像标题和描述信息plt.title("温度变化", fontsize=20)# 添加标题并设置字体大小plt.xlabel("时间", color='r',fontsize=16)plt.ylabel("温度", color='r',fontsize=16)# 绘制网格plt.grid(True, linestyle='--', alpha=0.5)# 设置显示图例说明plt.legend(loc=1)# 显示图像plt.show()

4.6 多个坐标系显示-plt.subplots(面向对象的画图方法)

如果我们想要将上海和北京的天气图显示在同一个图的不同坐标系当中,效果如下

可以通过subplots函数实现(旧的版本中有subplot,使用起来不方便),推荐subplots函数

matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw) 创建一个带有多个axes(坐标系/绘图区)的图

Parameters: nrows, ncols : int, optional, default: 1, Number of rows/columns of the subplot grid.**fig_kw : All additional keyword arguments are passed to the figure() call.Returns: fig : 图对象ax : 设置标题等方法不同:set_xticksset_yticksset_xlabelset_ylabel

关于axes子坐标系的更多方法:参考/api/axes_api.html#matplotlib.axes.Axes

注意:plt.函数名()相当于面向过程的画图方法,axes.set_方法名()相当于面向对象的画图方法。

代码实现:

# 生成温度数据x = range(60)shanghai = [random.uniform(15,18) for _ in x]beijing = [random.uniform(5,8) for _ in x]# 1.创建画布fig,axes = plt.subplots(nrows=1,ncols=2,figsize=(20,8),dpi=80)# 2.绘制图形shanghai_plot = axes[0]beijing_plot = axes[1]shanghai_plot.plot(x,shanghai,label="上海")beijing_plot.plot(x,beijing, label="北京")# 3.设置辅助显示shanghai_plot.set_title("上海温度变化", fontsize=20)# 添加标题并设置字体大小beijing_plot.set_title("北京温度变化", fontsize=20)x_value = x[::5]for axe in axes:axe.set_xlabel("时间", color='r',fontsize=16)# 添加描述信息axe.set_ylabel("温度", color='r',fontsize=16)# 添加描述信息# 设置说明axe.set_yticks(range(0, 41)[::5])axe.set_xticks(x_value, [f"11点{i}" for i in x_value])# 设置网格axe.grid(True, linestyle='--', alpha=0.5)# 设置显示图例说明axe.legend(loc=1)

4.7 折线图的应用场景

呈现公司产品(不同区域)每天活跃用户数呈现app每天下载数量呈现产品新功能上线后,用户点击次数随时间的变化拓展:画各种数学函数图像

注意:plt.plot()除了可以画折线图,也可以用于画各种数学函数图像

...import numpy as np# 得到等间隔的数据data = np.linspace(-10,10,10000)# 绘制图形plt.figure(figsize=(20,8), dpi=100)x = datay = np.sin(x)plt.plot(x,y)plt.show()

二、散点图(scatter):

Matplotlib能够绘制折线图、散点图、柱状图、直方图、饼图。

1.常见图形种类及意义

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图

特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)

散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。

特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)

柱状图:排列在工作表的列或行中的数据可以绘制到柱状图中。

特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计/对比)

直方图:由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据范围,纵轴表示分布情况。

特点:绘制连续性的数据展示一组或者多组数据的分布状况(统计)

饼图:用于表示不同分类的占比情况,通过弧度大小来对比各种分类。

特点:分类数据的占比情况(占比)

2 散点图绘制

需求:探究房屋面积和房屋价格的关系

房屋面积数据:

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]

import matplotlib.pyplot as plt# 准备数据# 房屋面积数据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=100)# 创建散点图plt.scatter(x,y)# 添加辅助层# 设置间距plt.xticks(range(int(max(x))+1)[::10])plt.yticks(range(int(max(y))+1)[::20])# 图表标题与plt.title("房价与面积的关系", fontsize=22)plt.xlabel("面积(m²)", fontsize=18,color="r")plt.ylabel("价格(元)",fontsize=18, color='r')# 显示网格plt.grid(True, linestyle="--", alpha=0.5)# 显示图像plt.show()

应用场景

探究不同变量之间的内在关系

三、柱状图(bar)

1.柱状图绘制:

matplotlib.pyplot.bar(x, width, align='center', **kwargs)Parameters: x : sequence of scalars.width : scalar or array-like, optional柱状图的宽度align : {‘center’, ‘edge’}, optional, default: ‘center’Alignment of the bars to the x coordinates:‘center’: Center the base on the x positions.‘edge’: Align the left edges of the bars with the x positions.每个柱状图的位置对齐方式**kwargs :color:选择柱状图的颜色Returns: `.BarContainer`Container with all the bars and optionally errorbars.

需求1-对比每部电影的票房收入

['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴', '降魔传','追捕','七十七天','密战','狂兽','其它'][73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]

代码实现:

import matplotlib.pyplot as plt# 导入数据title = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴', '降魔传','追捕','七十七天','密战','狂兽','其它']box_income = [73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]# 绘制图像plt.figure(figsize=(20,8), dpi=80)plt.bar(title, box_income, width=0.5, color=['b','r','g','y','c','m','y','k','c','g','b'])# 辅助层plt.yticks(range(max(box_income))[::5000])plt.xlabel("电影名称", fontsize=20, color='r')plt.ylabel("票房收入(万元)", fontsize=20, color='r')plt.title("x月电影票房统计", fontsize=26, color='c')plt.grid(True, linestyle='--', alpha=0.5)# 显示图像plt.show()

需求2-如何对比电影票房收入才更能加有说服力?

比较相同天数的票房

有时候为了公平起见,需要对比不同电影首日和首周的票房

1 准备数据

movie_name = ['雷神3:诸神黄昏','正义联盟','寻梦环游记']first_day = [10587.6,10062.5,1275.7]first_weekend=[36224.9,34479.6,11830]数据来源: /?ver=normal

2 绘制

添加首日首周两部分的柱状图x轴中文坐标位置调整

代码实现:

...movie_name = ['雷神3:诸神黄昏','正义联盟','寻梦环游记']first_day = [10587.6,10062.5,1275.7]first_weekend=[36224.9,34479.6,11830]# 绘制图像x = range(len(movie_name))plt.bar(x, first_day, width=0.2, label="首日票房" )plt.bar([i+0.2 for i in x],first_weekend, width=0.2,label="首周票房")# 说明plt.xticks(x,movie_name)# 显示图例plt.legend()# 显示图像plt.show()

柱状图应用场景

适合用在分类数据对比场景上

数量统计用户数量对比分析

四、直方图:

1 直方图介绍

直方图,形状类似柱状图却有着与柱状图完全不同的含义。直方图牵涉统计学的概念,首先要对数据进行分组,然后统计每个分组内数据元的数量。 在坐标系中,横轴标出每个组的端点,纵轴表示频数,每个矩形的高代表对应的频数,称这样的统计图为频数分布直方图。

相关概念:

组数:在统计数据时,我们把数据按照不同的范围分成几个组,分成的组的个数称为组数组距:每一组两个端点的差

2 直方图与柱状图的对比

柱状图是以矩形的长度表示每一组的频数或数量,其宽度(表示类别)则是固定的,利于较小的数据集分析。直方图是以矩形的长度表示每一组的频数或数量,宽度则表示各组的组距,因此其高度与宽度均有意义,利于展示大量数据集的统计结果。由于分组数据具有连续性,直方图的各矩形通常是连续排列,而柱状图则是分开排列

3 直方图绘制

需求:电影时长分布状况

现有250部电影的时长,希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?

数据:

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]

直方图绘制api

matplotlib.pyplot.hist(x, bins=None, normed=None, **kwargs)Parameters: x : (n,) array or sequence of (n,) arraysbins : integer or sequence or ‘auto’, optional组数

绘制: 设置组距设置组数(通常对于数据较少的情况,分为5~12组,数据较多,更换图形显示方式) 通常设置组数会有相应公式:组数 = 极差/组距= (max-min)/bins

代码实现:

import matplotlib.pyplot as plt# 准备数据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]# 画布plt.figure(figsize=(20,8),dpi=100)# 设置组距distance = 2# 计算组数group_num = int((max(time_)-min(time_))//distance)# 绘制plt.hist(time_, bins=group_num)# 显示刻度plt.xticks(range(min(time_), max(time_))[::2])# 添加说明xinxiplt.ylabel("电影数量", fontsize=20)plt.xlabel("电影时长(小时)", fontsize=20)plt.title("250部电影时长分布",fontsize=24)plt.grid(True, linestyle="--", alpha=0.5)# 显示图像plt.show()

4. 直方图的应用场景

例如:用户年龄分布,商品价格分布

用于表示分布情况通过直方图还可以观察和估计哪些数据比较集中,异常或者孤立的数据分布在何处

五、饼图(pie)

1.饼图介绍

饼图广泛得应用在各个领域,用于表示不同分类的占比情况,通过弧度大小来对比各种分类。饼图通过将一个圆饼按照分类的占比划分成多个区块,整个圆饼代表数据的总量,每个区块(圆弧)表示该分类占总体的比例大小,所有区块(圆弧)的加和等于 100%。

2.饼图绘制

需求:显示不同的电影的排片占比

电影排片:

效果:

数据:

movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']place_count = [60605,54546,45819,28243,13270,9945,7679,6799,6101,4621,5]

3.饼图api介绍

注意显示的百分比的位数

plt.pie(x, labels=,autopct=,colors)x:数量,自动算百分比labels:每部分名称autopct:占比显示指定%1.2f%%colors:每部分颜色

代码实现:

import matplotlib.pyplot asplt# 准备数据movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']place_count = [60605,54546,45819,28243,13270,9945,7679,6799,6101,4621,5]# 绘制图像plt.figure(figsize=(20, 8), dpi=100)plt.pie(place_count, labels=movie_name,autopct="%1.2f%%",colors=['b','r','g','y','c','m','y','c','g','y'])# 显示图例plt.legend()# 添加标题plt.title("电影排片占比")# 规定为正圆plt.axis('equal')# 显示图像plt.show()

4.增加阴影和破裂效果

添加explode属性

# 准备数据movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']place_count = [60605,54546,45819,28243,13270,9945,7679,6799,6101,4621,5]explode = (0.1, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0)# 绘制图像plt.figure(figsize=(20, 8), dpi=100)plt.pie(place_count, labels=movie_name,explode=explode,autopct="%1.2f%%",colors=['b','r','g','y','c','m','y','c','g','y'])# 显示图例plt.legend()# 添加标题plt.title("电影排片占比")# 规定为正圆plt.axis('equal')# 显示图像plt.show()

5.饼图应用场景

分类的占比情况(不超过9个分类)

例如:班级男女分布占比,公司销售额占比

六、总结

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。