matplotlib学习笔记

数据分析-可视化工具matplotlib

一、数据分析的流程

提出问题:明确想干什么;

②准备数据:将数据取出,进行预处理,以获得我们需要的数据;

③分析数据:使用工具、模型对数据进行分析;

④获得结论;

⑤结论可视化:将结论以图的形式展现,使分析结果清晰明了、易懂;

二、对比常用统计图

(1)折线图

以折线(线条)的上升下降来表示统计数量的增减变化的统计图,特点是:能够显示数据的变化趋势,反映事物随某个变量(如时间)的变化情况。简单的折线图如下:(源自matplotlib官网)

图一、折线图示例

(2)直方图

直方图又称质量分布图,是表示资料变化情况的重要工具。直方图由一系列高度不同的纵向条纹或者线段表示数据的分布情况,一般用横轴表示数据范围,用纵轴表示分布情况。例如用直方图表示某学校各个年龄段各有多少人。绘制直方图需要确定组数和组距,即将数据分为多少组,相邻两组之间的间隔是多少,比如绘制(年龄-人数)的直方图时,设置组距为5,即每一组的范围分别为(05岁)、(610岁)....组数=(max(x)-min(x))/组距。组距的选择十分重要,通常情况下,应该尽量选择合适的组距使组数为整数。

直方图也分为频数直方图和频率直方图,即纵轴分别表示该组的数量和频率。

特点:绘制连续性的数据,展示一组或者多组数据的分布情况。直方图示例如下:(来自matplotlib官网)

图二、直方图示例

(3)条形图

条形图是用来显示各个不同的事物对于某一个共同属性的比较情况,例如已知2019年各个城市的GDP,那么用条形图可以很直观的展示各个城市的GDP情况以及他们的对比关系。

特点:绘制离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。条形图示例如下:(来自matplotlib官网)

图三、条形图示例

(4)散点图

散点图表示在回归分析中,数据点在直角坐标系的分布情况。绘制散点图时,用两组数据构成多个坐标点,考察坐标点的分布,判断两个变量之间是否存在某种关联或者总结坐标点的分布模式、分布情况。

特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)散点图示例如下:(来自matplotlib官网)

图四、散点图示例

三、matplotlib绘制常用统计图

(1)绘制折线图

案例一:

假设一天中每个两个小时的气温分别是:15,13,14.5,17,20,25,26,26,26,27,22,18,15;使matplotlib画出该图形。代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

# 数据在x轴的位置,是一个可迭代对象

x =range(2, 26, 2)

y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

plt.plot(x, y)

plt.show()

运行之后结果如下图:

图五、折线图案例一结果

在上图中,我们通过对函数plt.plot()传入两个列表参数x, y,便可以绘制折线图,然后调用函数plt.show()将绘制结果显示出来。但是通过观察上图,发现还存在一下问题:

①图片大小不够

②图片没有描述信息

③x,y轴的刻度显示不明确(刻度间距不合适)

④线条样式可能不合适

针对上述问题,修改代码如下所示:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

# 设置图片大小,以及dpi

plt.figure(figsize=(10, 8), dpi=80)

# 设置字体显示为指定的文件(windows路径为:)适用于各种操作系统

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 数据在x轴的位置,是一个可迭代对象

x =range(2, 26, 2)

y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

plt.plot(x, y)

# 设置x轴的刻度 可以传一个range(),也可以传一个列表, 列表元素为坐标轴各点的值

plt.xticks(x)

# plt.xticks(range(2, 25))

# 设置y轴的刻度

plt.yticks(range(min(y), max(y)+1))

# 设置x,y轴的标签以及图片标题

plt.xlabel("时间", fontproperties=my_font)

plt.ylabel("温度(℃)", fontproperties=my_font)

plt.title("一天中气温变化情况(每隔两小时)", fontproperties=my_font)

# 保存图片在绘制之后

# 可以保存为.svg这种矢量图格式,放大之后不会有锯齿

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

plt.show()

运行结果如下:

图六、折线图案例一改良结果

案例二:

如果列表a表示十点到十一点两个小时之间每一分钟气温的变化,绘图表示。

代码如下:


from matplotlib import pyplot as plt

from matplotlib import font_manager

import random

# 设置图片大小,以及dpi

plt.figure(figsize=(10, 8), dpi=80)

# 设置字体显示为指定的文件(windows路径为:)适用于各种操作系统my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

x = range(0, 120)

y = [random.randint(25, 30)for i in range(120)]

plt.plot(x, y)

# 调整x轴的刻度_x = list(x)  # 只有列表才能取步长,所以进行强制转换_xtick_labels = ["10点{}分".format(i)for i in range(60)]

_xtick_labels += ["11点{}分".format(i)for i in range(60)]

plt.xticks(_x[::5], _xtick_labels[::5], rotation=45, fontproperties=my_font)  # 取步长为5,旋转270度,rotation表示旋转的度数# 添加描述信息plt.xlabel("时间", fontproperties=my_font)

plt.ylabel("温度 单位(℃)", fontproperties=my_font)

plt.title("10点到12点每分钟的气温变化情况", fontproperties=my_font)

plt.show()

结果如下图:

图七、折线图案例二结果

案例三:

假设大家在30岁的时候,根据自己的实际情况统计出来了11岁到30岁每年交的男女朋友的数量如列表[1,0,1,1,3,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1] ,以及某位朋友的上述情况列表[0,2,3,5,2,1, 1,0,3,4,6,3,1,1,0,2,1,1,3,2]。请绘制出该数据的折线图,以便分析每年交男女朋友的数量走势。

代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

# 设置字体

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 设置图的大小

plt.figure(figsize=(14, 7), dpi=80)

x =range(11, 31)

y = [1, 0, 1, 1, 3, 4, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1]

y1 = [0, 2, 3, 5, 2, 1, 1, 0, 3, 4, 6, 3, 1, 1, 0, 2, 1, 1, 3, 2]

plt.plot(x, y, label="自己", color="orange", linestyle=":")

plt.plot(x, y1, label="同桌", color="cyan", linestyle="--")

# 设置x轴显示信息

x_labels = ["{}岁".format(i)for i in range(11, 31)]

_x =list(x)

plt.xticks(_x, x_labels, fontproperties=my_font)

plt.yticks(range(min(y), max(y)+2))

# 绘制网格

plt.grid(alpha=0.5)# alpha 表示透明度

# 添加描述信息

plt.xlabel("年龄(岁)", fontproperties=my_font)

plt.ylabel("男(女)朋友数量(个)", fontproperties=my_font)

plt.title("11岁到30岁每年所处对象的数量走势图", fontproperties=my_font)

# 添加图例

# 调用此方法之后,程序会结合plt.plot()方法中的label参数显示出图例

# 此方法接收字体的参数为prop

plt.legend(prop=my_font)

plt.show()

结果如下:

图八、折线图案例三结果

plt.plot()方法的参数:

@ label: 用来在plt.legend()方法调用时设置图例

@ color: 设置线条颜色

@ linestyle: 设置线条风格

@ linewidth: 设置线条粗细

matplotlib折线图总结:

·绘制折线图(plt.plot()方法)

·设置图片大小和分辨率(plt.figure()方法)

·实现图片保存(plt.savefig()方法)

·设置xy轴的刻度和字符串(plt.xticks())

·解决刻度稀疏或者密集的问题(plt.xticks()方法)

·设置标题、xy轴的label(title,xlabel,ylabel)

·设置字体(font_manager类,结合fontproperties参数)

·添加图例(plt.plot(label=”xx”),plt.legend()方法)

(2)绘制散点图

案例:

假设你通过爬虫获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b)那么此时如何寻找出气温随时间变化的某种规律?

代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 设置图片大小,设置分辨率

plt.figure(figsize=(14, 9), dpi=80)

y_3 = [11, 17, 16, 11, 12, 11, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18

    ,21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22, 22, 23, 21]

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_3 =range(1, 32)

x_10 =range(40, 71)

# 绘制

plt.scatter(x_3, y_3, label="三月")

plt.scatter(x_10, y_10, label="十月")

# 调整x轴刻度

_x =list(x_3) +list(x_10)

_xticks_labels = ["3月{}日".format(i)for i in x_3]

_xticks_labels += ["10月{}日".format(i)for i in x_10]

plt.xticks(_x[::3], _xticks_labels[::3], fontproperties=my_font, rotation=45, fontsize=12)

# 设置附加信息

plt.xlabel("时间", fontproperties=my_font, fontsize=14)

plt.ylabel("温度(℃)", fontproperties=my_font, fontsize=14)

plt.title("三月与十月的最高气温趋势图", fontproperties=my_font, fontsize=14)

# 添加图例

plt.legend(prop=my_font)

plt.show()

结果如下:

图九、散点图案例结果

(3)绘制条形图

案例一:

假设你获取到了2017年内地电影票房前20的电影列表a和电影票房数据列表b,那么如何更加直观的展示该数据?

代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

a = ["战狼2", "速度与激情8", "功夫瑜伽", "西游伏妖篇", "变形金刚", "最后的骑士",

    "摔跤吧爸爸", "加勒比海盗5:死无对证", "金刚:骷髅岛", "极限特工:终极回归",

    "生化危机6:终章", "乘风破浪", "神偷奶爸3", "智取威虎山", "大闹天竺", "金刚狼3:殊死一战",

    "蜘蛛侠:英雄归来", "悟空传", "银河护卫队", "情圣"]

b = [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.32]

plt.figure(figsize=(15, 10), dpi=80)

# 竖着的条形图# plt.bar(range(len(a)), b)

# plt.xticks(range(len(a)), a, fontproperties=my_font, rotation=90)

# 横着的条形图# 某些情况下横着的条形图比竖着的好看plt.barh(range(len(a)), b, height=0.3)

# 设置附加信息plt.xlabel("票房 单位(亿)", fontproperties=my_font)

# y轴刻度信息plt.yticks(range(len(a)), a, fontproperties=my_font)

plt.grid(alpha=0.3)

plt.show()

结果如下:

图十、条形图案例一结果

案例二:

假设你知道了列表a中电影分别在2017-09-14(b_14),2017-09-15(b_15),2017-09-16三天的票房,为了展示列表中电影本身的票房以及同其他电影数据的对比情况,应该如何更加直观的呈现该数据?

代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

plt.figure(figsize=(14, 9), dpi=80)

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

a = ["星球崛起3", "敦刻尔克", "蜘蛛侠", "战狼2"]

b_16 = [15746, 312, 4497, 319]

b_15 = [12357, 156, 2045, 168]

b_14 = [2358, 399, 2358, 362]

x_14 =list(range(len(a)))

x_15 = [i +0.3 for i in x_14]

x_16 = [i +0.3*2 for i in x_14]

print(len(x_14))

plt.bar(x_14, b_14, width=0.3, label="2017-09-14")

plt.bar(x_15, b_15, width=0.3, label="2017-09-15")

plt.bar(x_16, b_16, width=0.3, label="2017-09-16")

# 设置x轴的刻度

plt.xticks(list(x_15), a, fontproperties=my_font, fontsize=12)

# 设置图例

plt.legend()

plt.show()

注意:为了使条形图不重叠,应当使每个条形的位置向右偏移一定距离,并且满足:

条形宽度*条形数量<1,比如上述代码中的x_14,x_15,x_16的设置。

结果如下:

图十一、条形图案例二结果

(4)绘制直方图

直方图的应用场景:

·用户的年龄状态

·一段时间内用户点击次数的分布状态

·用户活跃时间的分布状态

案例一:

频数分布直方图,假设你获取了250部电影的时长列表a,希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟的电影的数量,出现的频率)等信息,你应该如何呈现这些数据?(ps: 由于数据量比较大,因此使用随机数模拟上述数据)

代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

import random

# 设置组距为5,设置组距的时候应该注意尽量使(max(a)-min(a))能够整除组距

dis =5

a = [random.randint(80, 150)for i in range(251)]

# 组数

num_bin = (max(a)-min(a))//dis

plt.hist(a, num_bin)# 参数normed=1表示画出的图形是频率分布直方图

# 设置x轴的刻度

plt.xticks(range(min(a), max(a)+dis, dis))

plt.grid()

plt.show()

注:在组数为正整数的情况下,图形能正确绘制,当实际组数为小数时(即(max(a)-min(a))/dis为小数),获得的图形会有一定的偏移(如图十四,组数实际为小数)。解决方法为调整组距,使组数为正整数。

结果为:

图十二、直方图案例一结果
图十三、直方图案例一异常情况

案例二:

在美国 2004的人口普查发现有124million的人在离家较远的地方工作。根据他们从家里到上班地点所需要的时间,通过抽样统计列出了下表的数据,这些数据能够绘制成直方图吗?

interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90] (表示各个区间)

width = [5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60] (表示区间宽度)

quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 47] (各区间频数)

分析:由于数据以及被统计好了,因此不能直接使用直方图画图函数plt.hist(),该函数会在使用时分析一遍各个区间的频数。(但是理论上如果用随机数来模拟原始数据,应该可以用直方图画图函数来绘制出图形)。由于数据已经统计好,因此直接使用条形图,使条形图的线条宽度占满x轴的一个区间,即图形直观上是直方图。

代码如下:


from matplotlibimport pyplotas plt

from matplotlibimport font_manager

import random

my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\simsun.ttc")

# 只需要设置条形图的宽度为1即可

plt.figure(figsize=(12, 8), dpi=80)

interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90]

width = [5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60]

quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 47]

plt.bar(range(12), quantity, width=1)

_x = [i -0.5 for iin range(13)]

_xlabels = interval + [150]

plt.xticks(_x, _xlabels)

plt.ylabel("人数", fontproperties=my_font, fontsize=12)

plt.xlabel("时间", fontproperties=my_font, fontsize=12)

plt.grid()

plt.show()

图十四、直方图案例二结果

四、总结

matplotlib使用流程:

·明确问题

·选择图形的呈现形式

·准备数据

·绘图和图形完善

matplotlib更多图形样式:

百度echart(前端应用,使用js)。

plotly:可视化工具,兼容matplotlib和pandas。(需要付费)

<本文档记录个人学习matplotlib绘图工具过程的总结!若有不当之处欢迎指正! >

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352