为什么要学习matplotlib

  1. 能将数据进行可视化,更直观的呈现
  2. 使数据更加客观、更具说服力
  3. matplotlib:最流行的Python底层绘图库,主要做数据可视化图表,名字取材MATLAB,模仿MATLAB构建

matplotlib基本要点

每个红色的点是坐标,把5个点的坐标连接成一条线,组成了一个折线图。

示例:
假设一天中每隔两个小时(range(2, 25, 2))的气温(C)分别是[15, 13, 14.5, 17, 20, 25, 26, 26, 27, 22, 18, 15]

from matplotlib import pyplot as plt  # 导入pyplot

x = range(2, 26, 2)  
# 数据在x轴的位置,是一个可迭代对象
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]
# 数据在y轴的位置,是一个可迭代对象
# x轴和y轴的数据一起组成了所有要绘制出的坐标
# 分别是(2, 15), (4, 13), (6, 14.5), (8, 17)......

plt.plot(x, y)  # 传入x和y,通过plot绘制出折线图
plt.show()  # 在执行程序的时候展示图形

WE CAN DO MORE

但是目前存在以下几个问题:

  1. 设置图片大小(想要一个高清无码大图)
  2. 保存到本地
  3. 描述信息,比如x轴和y轴表示什么,这个图表示什么
  4. 调整x或者y的刻度的间距
  5. 线条的样式(比如颜色,透明度等)
  6. 标记出特殊的点(比如告诉别人最高点和最低点在哪里)
  7. 给图片添加一个水印(防伪,防止盗用)

设置图片大小

improt matplotlib.pyplot as plt

fig = plt.figure(figsize=(20, 8), dpi=80)
# figure图形图标的意思,在这里指的就是我们画的图
# 通过实例化一个figure并且传递参数,能够在后台自动使用该figure实例
# 在图像模糊的时候可以传入dpi参数,让图片更加清晰

x = range(2, 26, 2) 
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

plt.plot(x, y)
plt.savefig("./sig_size.png")  # 保存图片 可以保存svg这种矢量图格式,放大不会有锯齿

plt.show()

调整x或者y轴上的刻度

import matplotlib.pylot as plt

fig = plt.figure(figsize(10, 5))

x = range(2, 26, 2) 
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

plt.plot(x, y)
plt.xticks(x)  # 设置x的刻度
# plt.xticks(x[::2])
# 当刻度太密集的时候使用列表的步长(间隔取值)来解决,matplotlib自动帮我们对应plt.show()

设置中文显示

为什么无法显示中文:
matplotlib默认不支持中文字符,因为默认的英文字体无法显示汉字

查看linux/mac下面支持的字符:
fc-list -> 查看支持的字体
fc-list: lang-zh -> 查看支持的中文(冒号前面有空格)

如何修该matplotlib的默认字体?
通过matplotlib.rc可以修改,具体方法参见源码(windown/linux)
通过matplotlib下的font manager可以解决(window/linux/mac)

示例代码1:

from matplotlib import pyplot as plt
import matplotlib
import random


font = {
    'family': 'MicroSoft YaHei',
    'weight': 'bold',
    'size': 10,
}

matplotlib.rc("font", **font)
fig = plt.figure(figsize=(10, 5))

x = range(0, 120)
y = [random.randint(20, 35) for i in range(0, 120)]
 
# 取步长,数字与字符串一一对应,数据长度一眼

x_lable = ["10点{0:>02}分".format(i) for i in range(0, 60)]
x_lable = x_lable + ["11点{0:>02}分".format(i) for i in range(0, 60)]

plt.plot(x, y)
plt.xticks(x[::5], x_lable[::5], rotation=45)  # ratation旋转角度

plt.show()

示例代码2:

from matplotlib import pyplot as plt
from matplotlib import font_manager
# import matplotlib
import random


my_font = font_manager.FontProperties(fname="C:\\Windows\\Fonts\\s8514sys.fon")


fig = plt.figure(figsize=(10, 5))

x = range(0, 120)
y = [random.randint(20, 35) for i in range(0, 120)]

x_lable = ["10点{0:>02}分".format(i) for i in range(0, 60)]
x_lable = x_lable + ["11点{0:>02}分".format(i) for i in range(0, 60)]
# 取步长,数字与字符串一一对应,数据长度一眼

plt.plot(x, y)
plt.xticks(x[::5], x_lable[::5], rotation=45, font_properties=my_font)

plt.show()

给图像添加描述信息

from matplotlib import pyplot as plt 
import random


font = {
    'family': 'MicroSoft YaHei',
    'weight': 'bold',
    'size': 10,
}

matplotlib.rc("font", **font)
fig = plt.figure(figsize=(10, 5))

x = range(0, 120)
y = [random.randint(20, 35) for i in range(0, 120)]
 
# 取步长,数字与字符串一一对应,数据长度一眼

x_lable = ["10点{0:>02}分".format(i) for i in range(0, 60)]
x_lable = x_lable + ["11点{0:>02}分".format(i) for i in range(0, 60)]

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = ['SimHei']  # 用来正常显示负号
plt.plot(x, y)
plt.xticks(x[::5], x_lable[::5], rotation=45)  # ratation旋转角度

plt.xlabel("时间")
plt.ylabel("温度(度)")
plt.title("10到12点每分钟的时间变化请求")

plt.show()

自定义绘制图形的风格

plt.grid(alpha=0.4)  # 绘制网格

plt.legend(prop=my_font, loc="upper left")  # 添加图例
plt.plot(
    x, # x
    y, # y
    ->在绘制的时候指定即可
    color='r'  # 线条颜色
    linestyle='--',  # 线条风格
    linewidth=5,  # 线条粗细
    
    alpha=0.5,  # 透明度
)
颜色字符 风格字符
r红色 -实线
g绿色 --虚线、破折线
b蓝色 -.点划线
w白色 :点虚线、虚线
-- ''留空或空格,无线条
c青色 --
m洋红 --
y黄色 --
k黑色 --
-- --
#00ff0016进制 --
0.8灰度值字符串 --

对比常用统计图

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图
特点:能够显示数据的变化趋势,反映事物的变化情况。变化

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

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


条形图:排列在工作表的列或行中的数据可以绘制到条形图

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


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

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


散点图

示例代码:

from matplotlib import pyplot as plt


y_3 = [11, 17, 16, 11, 12, 11, 12, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18, 21, 16, 17, 20, 14, 15, 19, 21, 22, 22, 22, 23, 24]
y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17, 20, 21, 20, 22, 15, 5, 13, 17, 10, 11, 13, 12, 13, 6, 7]

x_3 = range(1, 31)
x_10 = range(41, 71)

plt.rcParams["font.sans-serif"] = ['SimHei']
plt.figure(figsize=(15, 8), dpi=80)

plt.scatter(x_3, y_3, label="3月份")
plt.scatter(x_10, y_10, label="10月份")

_x = list(x_3)+list(x_10)

plt.xticks(_x[::3], ([f"3月{i}日" for i in x_3] + [f"10月{i-40}日" for i in x_10])[::3], rotation=45)
plt.legend()

plt.xlabel("日期")
plt.ylabel("温度")
plt.title("3月份和10月份温度分布走势图")
plt.savefig("..")
plt.show()

条形图

示例代码:

from matplotlib import pyplot as plt


plt.rcParams["font.sans-serif"] = ["SimHei"]

a = ["猩球崛起3:终极之战", "敦刻尔克", "蜘蛛侠:英雄归来", "战狼2"]
b_16 = [15746, 321, 4497, 219]
b_15 = [12357, 156, 2045, 168]
b_14 = [2358, 399, 2358, 362]

bar_width = 0.2


x_15 = [i+bar_width for i in range(len(a))]
x_16 = [i+bar_width*2 for i in range(len(a))]

plt.figure(figsize=(10, 5))
plt.barh(range(len(a)), b_14, height=bar_width, label="9月14日")
plt.barh(x_15, b_15, height=bar_width, label="9月15日")
plt.barh(x_16, b_16, height=bar_width, label="9月16日")

plt.yticks([i+bar_width for i in range(len(a))], a)

plt.legend()
plt.show()

直方图

把数据分为多少组进行统计??
组数要适当,太少会有较大的统计误差,太多规律不明显
组数:将数据分组,当数据在100个以内时,按数据多少常分5-12组。
组距:指每个小组的两个端点的距离。
组数 = 极差/组距 = (max(a)-min(a))/ bin_width

bin_width = 3  #设置组距为3
num_bins = int((max(a)-min(a))/bin_width)  # 分为多少组 
plt.hist(a, num_bins)  # 传入需要统计的数据,以及组数即可

# plt.hist(a, [min(a)+i*bin_width for i in range(num_bins)])
# 可以传入一个列表,长度为组数,值为分组依据,当组距不均匀的时候使用

# plt.hist(a, num_bins, normed=1)
# normed:bool 是否绘制频率分布直方图,默认为频数直方图

plt.xticks(list(range(min(a), max(a)))[::bin_width], rotation=45)
plt.grid(True, linestyle="-.", alpha=0.5)  # 显示网格,alpha为透明度