互联网技术

7个常用 Matplotlib 绘图方法详解

2024年1月7日 · admin
openmagic ad

绘图是数据分析中非常重要的一环,不仅用于展示结果,也是探索数据规律的重要手段。Matplotlib 是 Python 生态中使用最广泛的可视化库之一,适合绘制多种常见统计图形。本文围绕 7 类常用图表,梳理 Matplotlib 的典型用法与适用场景,帮助你更高效地完成可视化分析。

Matplotlib 是一个跨平台的 2D 绘图库,支持在 Python、IPython、Jupyter Notebook 以及各类应用和 Web 环境中使用。它提供了较完整的面向对象 API,也包含常用的 pyplot 接口,便于快速绘图。

在实际工作中,Matplotlib 常被用于绘制散点图、条形图、折线图、饼图、直方图、箱形图,以及由多个子图组成的组合图。下面按图表类型分别介绍。

1. 散点图

散点图用于展示两个变量之间的分布关系,常见于回归分析、相关性观察和异常点识别。通过点在坐标系中的位置,可以直观判断变量之间是否存在趋势、聚集或离散现象。

例如,在广告分析场景中,可以借助散点图观察两个指标之间的关系,如曝光量与点击量、投放成本与转化数等。

下面是一个简单的散点图示例:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(30)
y = np.arange(30) + 3 * np.random.randn(30)

plt.scatter(x, y, s=50)
plt.show()

其结果可以清晰展示样本点在二维空间中的分布情况。

[[[IMG_1]]]

2. 条形图

条形图通过条形的高度或长度表示数值大小,适合用于不同类别之间的数量对比。它可以横向展示,也可以纵向展示;纵向形式通常也称为柱状图。

如果需要比较多个对象在某一指标上的差异,条形图通常是最直接的表达方式。例如比较多部电影的票房表现、不同渠道的投放金额,或不同产品的销量。

示例代码如下:

a = ['战狼2', '速度与激情8', '功夫瑜伽', '西游伏妖篇', '变形金刚5:最后的骑士', '摔跤吧!爸爸', '加勒比海盗5:死无对证', '金刚:骷髅岛', '极限特工:终极回归', '生化危机6:终章']
b = [56.01, 26.94, 17.53, 16.49, 15.45, 12.96, 11.8, 11.61, 11.28, 11.12]

plt.rcParams['font.sans-serif'] = ['SimHei', 'Times New Roman']
plt.rcParams['axes.unicode_minus'] = False

plt.bar(range(len(a)), b, width=0.3)
plt.xticks(range(len(a)), a, rotation=90)
plt.grid(False)
plt.show()

这种图表非常适合做分类数据的直观对比。

[[[IMG_2]]]

3. 折线图

折线图适合表现连续数据随时间或顺序变化的趋势,是分析时间序列数据时最常见的图形之一。通过连接各个数据点,可以直观观察指标的上升、下降或波动情况。

例如,在广告平台数据中,可以使用折线图展示每日请求量、点击量、转化量或活跃用户数的变化趋势。

示例代码如下:

import matplotlib.dates as mdate

dateparse = lambda dates: pd.datetime.strptime(dates, '%Y%m%d')
data = pd.read_csv('Req_User.csv', encoding='utf-8', parse_dates=['date'], date_parser=dateparse)

plt.figure(figsize=(10, 7))
plt.plot(data['date'], data['Req_User'])
plt.xlabel('date', fontsize=15)
plt.ylabel('Req_User', fontsize=15)
plt.tick_params(labelsize=10)
plt.show()

折线图能够帮助分析者快速发现趋势变化和周期性规律。

[[[IMG_3]]]

4. 饼图

饼图用于展示各部分在总体中的占比,适合表现结构关系。每一个扇区代表一个类别,面积大小对应其所占比例。

当数据类别较少、重点在于体现构成比例时,饼图是一种较为直观的方式。例如家庭支出构成、渠道流量占比或产品销售结构等。

示例代码如下:

import matplotlib.pyplot as plt

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

labels = ['娱乐', '育儿', '饮食', '房贷', '交通', '其他']
sizes = [4, 10, 18, 60, 2, 6]
explode = (0, 0, 0, 0.1, 0, 0)

plt.figure(figsize=(10, 7))
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', shadow=False, startangle=150)
plt.title('饼图示例-10月份家庭支出')
plt.show()

需要注意的是,饼图更适合类别数量较少的场景,类别过多时会影响可读性。

[[[IMG_4]]]

5. 直方图

直方图用于展示连续型数据的分布情况。它会先将数值范围划分为多个区间,再统计各区间内数据出现的频数,因此非常适合用来观察数据是否集中、是否偏态、是否存在长尾分布等。

例如,在分析用户年龄、消费金额、访问时长时,直方图都能帮助我们快速了解样本分布特征。

以下示例基于泰坦尼克号数据集绘制年龄分布直方图:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

titanic = pd.read_csv('train.csv')
any(titanic.Age.isnull())
titanic.dropna(subset=['Age'], inplace=True)

plt.style.use('ggplot')
plt.hist(titanic.Age, bins=20, color='steelblue', edgecolor='k', label='直方图')
plt.tick_params(top='off', right='off')
plt.legend()
plt.grid(False)
plt.show()

借助直方图,可以比较直观地看到不同年龄段的乘客分布情况。

[[[IMG_5]]]

6. 箱形图

箱形图也称箱线图,主要用于展示一组数据的分散程度和分布特征。它通常能够显示中位数、上下四分位数、极值范围以及异常值,因此在数据探索阶段非常实用。

如果需要比较多组数据的离散程度、判断是否存在异常值,箱形图会比均值或简单统计量更直观。

示例代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(np.random.rand(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
plt.boxplot(df, patch_artist=True)
plt.show()

箱形图既可以纵向绘制,也可以横向绘制,适合进行多组数据间的分布对比。

[[[IMG_6]]]

[[[IMG_7]]]

7. 组合图与子图布局

在很多分析任务中,单张图无法完整表达信息,这时就需要在同一个画布中放置多个子图。Matplotlib 可以通过 add_subplotsubplots 快速创建组合图。

使用 add_subplot 创建 2 行 2 列的多个子图示例如下:

from numpy.random import randn
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
ax4 = fig.add_subplot(2, 2, 4)

ax1.scatter(np.arange(30), np.arange(30) + 3 * randn(30))
ax2.bar(np.arange(8), [1, 2, 3, 7, 8, 5, 6, 4])
ax3.hist(randn(100), bins=20)
ax4.plot(randn(60).cumsum())

plt.show()

这种方式适合将不同图表集中展示,便于整体比较。

[[[IMG_8]]]

还可以通过 subplots 结合循环批量生成子图:

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
for i in range(2):
    for j in range(2):
        axes[i, j].plot(randn(100).cumsum())

plt.subplots_adjust(wspace=0, hspace=0)
plt.show()

通过调整 wspacehspace 参数,可以灵活控制子图之间的横向和纵向间距。

[[[IMG_9]]]

总结

Matplotlib 提供了完整且灵活的绘图能力,能够覆盖日常数据分析中的大多数可视化需求。散点图适合看相关关系,条形图适合看类别对比,折线图适合看趋势变化,饼图适合看结构占比,直方图适合看分布情况,箱形图适合看离散程度和异常值,而组合图则适合进行多维度联合展示。

掌握这些基础图表后,就能够构建出更清晰、更有说服力的数据表达方式,也为进一步使用更复杂的可视化工具打下基础。