Python数据挖掘基础(一):Matplotlib

1. 绘制折线图

折线图将值标注成点,并通过直线将这些按照某种顺序连接起来形成的图。场景:数据在一个有序的因变量上的变化,它的特点是反应事物随类别而变化的趋势,可以清晰展现数据的增减趋势、增减的速率、增减的规律、峰值等特征。优点:

  1. 能很好的展现沿某个维度的变化趋势
  2. 能比较多组数据在同一个维度上的趋势
  3. 适合展现较大数据集

需求1: 画出厦门及北京两个城市11点到12点1小时内每分钟的温度变化折线图。厦门温度范围在15度~18度 北京温度范围在1度~3度。示例代码如下:

import matplotlib.pyplot as plt
import random

# 1.创建一个新图 简单理解为一个画板
# figsize可选:指定图的宽高 dpi: 图的分辨率 返回一个fig对象
plt.figure(figsize=(20, 8), dpi=80)

# 2.构造x,y坐标的数据
x = range(60)  # x坐标: 模拟0-60分钟
# random.uniform用于生成一个指定范围内的随机符点数
y_xiamen = [random.uniform(15,18) for i in range(60)]  # 厦门温度
y_beijing = [random.uniform(1,3) for i in range(60)]  # 北京温度

# 3.画折线图
plt.plot(x, y_xiamen, label="厦门")  # 厦门温度显示
# color: 颜色 linestyle: 线型
plt.plot(x, y_beijing, label="北京", color="r", linestyle="--")  # 北京温度显示

# 4.美化折线图
# 构造中文列表的字符串
x_ch = ["11点{}分".format(i) for i in x]
y_ticks = range(40)

# 4.1 添加刻度: 修改x,y坐标的刻度
plt.xticks(x[::5], x_ch[::5])  # x: 要显示的刻度值
plt.yticks(y_ticks[::5])
# plt.yticks(y_ticks[::5])

# 4.2 增加标题 x轴/y轴描述信息
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("一些城市中午11点0分到12点之间的温度变化图示")

# 4.3 添加图例: 默认值为最佳loc="best" 也可以省略 可以根据实际情况自行设置
# loc除了设置为best之外 还有可以设置为 upper/lower/center left/right/center 并且可以使用数字代替 
# plt.legend(loc="center left")
plt.legend(loc=2) # 2代表左上 写数字并不直观
plt.legend(loc="best")  # 0,"best" 代表右上

plt.savefig("weather.png")  # 保存图形到本地
# 5.显示图形
plt.show()

上述代码执行结果如下:
在这里插入图片描述
颜色color设置如下表:
在这里插入图片描述
线型linestyle设置如下表:
在这里插入图片描述
需求2:将厦门和北京的天气图显示在同一个图的不同坐标系当中,示例代码如下:

import matplotlib.pyplot as plt
import random

# 两个城市的温度 在多个坐标系中显示
# 1.创建新图 一个白白的画板
# nrows:1行 ncols:2列 就是一行两个不同的坐标系 可以简写为1,2
# fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(20, 8))
fig, ax = plt.subplots(1, 2, figsize=(20, 8))
# 2.准备数据
x = range(60)  # 0-59分
y_xiamen = [random.uniform(15, 18) for i in range(60)]  # 准备厦门温度
y_beijing = [random.uniform(1, 3) for i in range(60)]  # 准备北京温度

# 3.显示
ax[0].plot(x, y_xiamen, label="厦门")  # 厦门显示
ax[1].plot(x, y_beijing, label="北京", ls="--", color="r")  # 北京显示 ls: linestyle缩写

# 4.美化坐标系
x_ch = ["11点{}分".format(i) for i in x]  # 中文刻度
y_ticks = range(40)  # y轴刻度
# 4.1 设置刻度值
ax[0].set_xticks(x[::5], x_ch[::5])
ax[0].set_yticks(y_ticks[::5])
ax[1].set_xticks(x[::5], x_ch[::5])
ax[1].set_yticks(y_ticks[::5])
# 4.2 设置label
ax[0].set_xlabel("时间")
ax[0].set_ylabel("温度")  # 给第一个图设置label
ax[1].set_xlabel("时间")
ax[1].set_ylabel("温度")  # 给第二个图设置label
# 4.3 分别给每个图设置title
ax[0].set_title("中午11点0分到12点之间的温度变化图示")
ax[1].set_title("中午11点0分到12点之间的温度变化图示")
# 4.4 分别给每个图设置图例
ax[0].legend(loc="best")
ax[1].legend(loc="best")  # 注意: 当在多个ax里面画图的时候 刻度 标签 必须在相应的坐标系里面指定

# 5.显示图形
plt.show()

上述代码执行结果如下:
在这里插入图片描述

2. 绘制柱状图

柱状图是一种以长方形的长度来表达数据的统计报告图,由一系列高度不等的纵向条纹表示数据分布的情况。适合用于展示二维数据集,展示数据的分布情况,其中一个轴表示需要对比的分类维度,另一个轴代表相应的数值,比如:(月份,商品销量) 或者在一个维度上,对多个同质可比的指标的比较,比如:月份,苹果销量,桃子产量。

需求1:画出每部电影的票房收入对比。电影数据如下图所示:
在这里插入图片描述
示例代码如下:

# 需求:电影票房数据的对比(柱状图)
# 1.创建一个新图 即画板
plt.figure(figsize=(20, 8), dpi=80)

# 2.准备数据
movie_name_list = ["宠爱", "叶问4: 完结篇", "误杀", "我为你牺牲", 
                   "变身特工", "美丽人生","天使陷落", "紫罗兰永恒花园 外传:永远与自动手记人偶"]
x = range(len(movie_name_list))
y = [51033, 41834, 37528, 10606, 10341, 5982, 5506, 4850]

# 3.画出柱状图
# 注意: 填入的x坐标必须全是数字
plt.bar(x, y, width=0.5, color=['b','r','g','y','c','m','y','k'])

# 4.修改刻度,以及电影名字显示
plt.xticks(x, movie_name_list)

# 5.显示
plt.show()

上述代码执行结果如下:
在这里插入图片描述
有时候为了公平起见,我们需要对比不同电影首日和首周的票房,数据如下:

movie_name_list = ["雷神3:诸神黄昏","正义联盟","寻梦环游记"]  # 电影名字
first_day = [10587.6,10062.5,1275.7]  # 票房数据
first_weekend=[36224.9,34479.6,11830]

示例代码如下:

# 不同电影的首日、首周的票房对比
# 1.创建新图
plt.figure(figsize=(20, 8), dpi=80)

# 2.准备数据
movie_name_list = ["雷神3:诸神黄昏","正义联盟","寻梦环游记"]  # 电影名字
first_day = [10587.6,10062.5,1275.7]  # 票房数据
first_weekend=[36224.9,34479.6,11830]
x = range(len(movie_name_list))

# 3.画柱状图
plt.bar(x, first_day, width=0.2, label="首日票房")
plt.bar([i+0.2 for i in x], first_weekend, width=0.2, label="首周票房")

# 4.美化
# 替换刻度值
plt.xticks([i+0.1 for i in x], movie_name_list)
plt.legend(loc="best")  # 添加图例

# 5.显示
plt.show()

上述代码执行结果如下:
在这里插入图片描述

3. 绘制直方图

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

需求1:现有250部电影的时长, 希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量/出现的频率)等信息。示例代码如下:

import matplotlib.pyplot as plt

# 电影时长分布直方图
# 1.创建新图
plt.figure(figsize=(20, 8), dpi=80)

# 2.准备数据
bins = 2  # 组距
time_list = [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]
group = int((max(time_list)-min(time_list))/2)

# 3.绘制直方图
plt.hist(time_list, group)

# 4.美化
# 指定刻度的范围,以及步长
plt.xticks(range(min(time_list), max(time_list))[::2])
plt.xlabel("电影时长大小")
plt.ylabel("电影的数据量")  # 设置label
plt.grid(True, linestyle="--", alpha=0.5)  # 添加网格

# 5.显示图形
plt.show()

上述代码执行结果如下:
在这里插入图片描述

4. 绘制饼图

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

需求1:基本饼图演示以及一些其他功能。示例代码如下:

import matplotlib.pyplot as plt

# 基本饼图演示以及一些其他功能
# 1.创建新图
plt.figure(figsize=(20, 8))

# 2.构造数据
labels = ["Frogs", "Hogs", "Dogs", "Logs"]  # 分类
sizes = [15, 30, 45, 10]  # 占比
explode = (0, 0.1, 0, 0)

# 3.画图
# labels: 每部分的名称
# autopct: 占比显示指定
# explode: 偏移
# shadow: 阴影
# startangle: 不为None 则将饼形图的起点 从x轴逆时针旋转角度
plt.pie(sizes, labels=labels, autopct="%1.1f%%", explode=explode, shadow=True, startangle=90)
plt.axis("equal")  # 等宽高比可确保将饼图绘制为圆

# 4.显示
plt.show()

上述代码执行结果如下:
在这里插入图片描述
更多画图功能请参考:画图实例

5. 解决中文乱码问题

5.1 windows版

在创建新图之后,添加以下两行代码即可:

plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号

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

5.2 Mac版

  1. 下载相关的中文字体simhei文件: 下载地址
  2. 通过以下代码查找matplotlib的数据存放位置:
    import matplotlib
    matplotlib.matplotlib_fname()
    
    运行结果如图所示:
    在这里插入图片描述
  3. 使用终端打开上述目录,并将下载的字体文件simhei.ttf复制到上述目录的fonts/ttf/目录中,如下图所示:
    在这里插入图片描述
    在这里插入图片描述
  4. 在上述目录中用sublime(或其他记事本工具或vi/vim) 打开matplotlibrc,找到#font.sans-serif开头的这一行,去掉#,并加上SimHei,如下:
    在这里插入图片描述
  5. #axes.unicode_minus : True 去掉注释并改为False,如果不修改,会导致坐标轴的负号显示不出来,如下:
    在这里插入图片描述
  6. 在终端执行rm -rf ~/.matplotlib/,然后重启jupyter或者在jupyter里面重启服务都可,如下:
    在这里插入图片描述
原创文章 43 获赞 749 访问量 4万+

猜你喜欢

转载自blog.csdn.net/xw1680/article/details/105922423