「AI Python 系列」第 02 栏 · AI+数据可视化
全栏 15 篇 · 零成本跟完 🍃
作者:梅雅达编程笔记
首发:CSDN


摘要: 从这篇开始正式画图。Matplotlib 是 Python 可视化的一切基础,后面的 SeabornPyecharts 都是在它之上封装的。本篇用同一份电商销售数据,分别画出四种最常用的基础图表:折线图看趋势、柱状图看对比、饼图看占比、散点图看关系。每种图都给出完整代码和适用场景说明,拿来就能用。


数据洗干净了,终于可以画图了。

Matplotlib 是 Python 可视化世界的地基。不管你以后用 seabornpyecharts 还是 plotly,底层都是它。搞懂了 matplotlib,其他库学起来特别快。


一、准备数据

后面所有图都用这份数据:

import pandas as pd
import matplotlib.pyplot as plt

# 设置中文显示(每次都记得加,不然中文变方块)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False

# 月度销售数据
months = ['1月', '2月', '3月', '4月', '5月', '6月',
          '7月', '8月', '9月', '10月', '11月', '12月']
sales = [12.3, 10.1, 15.8, 14.2, 18.6, 22.1,
         19.5, 24.3, 21.7, 26.8, 30.2, 35.5]

# 商品分类数据
products = ['商品A', '商品B', '商品C', '商品D']
category_sales = [320, 280, 195, 205]

# 渠道占比
channels = ['线上', '线下', '分销']
channel_share = [55, 30, 15]

# 价格-销量关系(散点图用)
prices = [59, 79, 99, 129, 159, 199, 249, 299]
volumes = [420, 350, 280, 180, 120, 85, 45, 20]


二、折线图:看趋势

折线图最适合展示随时间变化的趋势

plt.figure(figsize=(10, 5))
plt.plot(months, sales, marker='o', color='#2196F3', linewidth=2)
plt.title('全年月度销售额趋势', fontsize=14, fontweight='bold')
plt.ylabel('销售额(万元)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('折线图_月度销售趋势.png', dpi=150)
plt.show()

在这里插入图片描述

关键参数解释:

  • marker='o':每个数据点画一个圆点
  • color='#2196F3':颜色用十六进制,这个是我觉得最好看的蓝色之一
  • linewidth=2:线宽,默认是 1,2 会粗一点更醒目
  • alpha=0.3:网格线的透明度,太实了会干扰视线

多条折线对比:

# 两条产品线对比
sales_a = [5.2, 4.8, 6.1, 5.5, 7.2, 8.5, 7.8, 9.1, 8.3, 10.2, 11.5, 13.2]
sales_b = [4.1, 3.5, 5.2, 4.8, 6.5, 7.8, 6.9, 8.5, 7.5, 9.8, 11.0, 12.8]

plt.figure(figsize=(10, 5))
plt.plot(months, sales_a, marker='o', label='商品A', color='#2196F3', linewidth=2)
plt.plot(months, sales_b, marker='s', label='商品B', color='#FF5722', linewidth=2)
plt.title('商品 A vs 商品 B 月度销售对比', fontsize=14, fontweight='bold')
plt.ylabel('销售额(万元)', fontsize=12)
plt.legend()  # 显示图例
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('折线图_多线对比.png', dpi=150)
plt.show()

在这里插入图片描述

label + plt.legend() 是多条线的标配。


三、柱状图:看对比

柱状图最适合比较不同类别的数值大小

# 基础柱状图
plt.figure(figsize=(8, 5))
plt.bar(products, category_sales, color=['#2196F3', '#FF5722', '#4CAF50', '#FFC107'])
plt.title('各商品年度销量对比', fontsize=14, fontweight='bold')
plt.ylabel('销量(件)', fontsize=12)

# 在每个柱子上标注数值
for i, (product, value) in enumerate(zip(products, category_sales)):
    plt.text(i, value + 5, str(value), ha='center', fontsize=11)

plt.tight_layout()
plt.savefig('柱状图_商品对比.png', dpi=150)
plt.show()

在这里插入图片描述

横向柱状图(标签太长时更好用):

plt.figure(figsize=(8, 5))
plt.barh(products, category_sales, color=['#2196F3', '#FF5722', '#4CAF50', '#FFC107'])
plt.title('各商品年度销量对比', fontsize=14, fontweight='bold')
plt.xlabel('销量(件)', fontsize=12)

# 标注数值
for i, (product, value) in enumerate(zip(products, category_sales)):
    plt.text(value + 5, i, str(value), va='center', fontsize=11)

plt.tight_layout()
plt.savefig('柱状图_横向.png', dpi=150)
plt.show()

在这里插入图片描述

分组柱状图(每个类别有多个对比项):

import numpy as np

# 各商品在各渠道的销量
data = {
    '线上': [180, 150, 100, 110],
    '线下': [100, 90, 65, 70],
    '分销': [40, 40, 30, 25]
}

x = np.arange(len(products))
width = 0.25

fig, ax = plt.subplots(figsize=(10, 5))
bars1 = ax.bar(x - width, data['线上'], width, label='线上', color='#2196F3')
bars2 = ax.bar(x, data['线下'], width, label='线下', color='#FF5722')
bars3 = ax.bar(x + width, data['分销'], width, label='分销', color='#4CAF50')

ax.set_title('各商品分渠道销量对比', fontsize=14, fontweight='bold')
ax.set_xticks(x)
ax.set_xticklabels(products)
ax.legend()
plt.tight_layout()
plt.savefig('柱状图_分组.png', dpi=150)
plt.show()

在这里插入图片描述


四、饼图:看占比

饼图适合展示整体中各部分的比例

plt.figure(figsize=(7, 7))
colors = ['#2196F3', '#FF5722', '#4CAF50']

# 基础饼图
plt.pie(channel_share, labels=channels, colors=colors,
        autopct='%1.1f%%',   # 显示百分比
        startangle=90,       # 起始角度
        textprops={'fontsize': 13})

plt.title('销售渠道占比', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.savefig('饼图_渠道占比.png', dpi=150)
plt.show()

在这里插入图片描述

突出显示某一块:

plt.figure(figsize=(7, 7))
explode = (0.05, 0, 0)  # 第一块"拉出来"一点

plt.pie(channel_share, labels=channels, colors=colors,
        autopct='%1.1f%%', startangle=90,
        explode=explode,
        textprops={'fontsize': 13})

plt.title('销售渠道占比(线上为主)', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.savefig('饼图_突出显示.png', dpi=150)
plt.show()

在这里插入图片描述

💡 什么时候不用饼图? 分类超过 5-6 个的时候,饼图就挤成一团了。这时候换成横向柱状图更好。


五、散点图:看关系

散点图用来展示两个变量之间有没有关系

plt.figure(figsize=(8, 6))
plt.scatter(prices, volumes, s=100, color='#2196F3', edgecolors='white', linewidth=1)

# 加上标签
for i, price in enumerate(prices):
    plt.annotate(f'¥{price}', (price, volumes[i]), 
                textcoords="offset points", xytext=(5, 5), fontsize=9)

plt.title('价格 vs 销量:价格越高,卖得越少', fontsize=14, fontweight='bold')
plt.xlabel('价格(元)', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('散点图_价格vs销量.png', dpi=150)
plt.show()

在这里插入图片描述

一眼就能看出:价格越高,销量越低。这就是负相关。

加一条趋势线:

from scipy import stats

# 计算线性回归
slope, intercept, r_value, p_value, std_err = stats.linregress(prices, volumes)
line = [slope * x + intercept for x in prices]

plt.figure(figsize=(8, 6))
plt.scatter(prices, volumes, s=100, color='#2196F3', edgecolors='white', 
            linewidth=1, zorder=3)
plt.plot(prices, line, color='#FF5722', linewidth=2, linestyle='--', 
         label=f'趋势线 (R²={r_value**2:.2f})', zorder=2)

plt.title('价格 vs 销量(含趋势线)', fontsize=14, fontweight='bold')
plt.xlabel('价格(元)', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('散点图_趋势线.png', dpi=150)
plt.show()

R² 越接近 1,说明两个变量的关系越强。

在这里插入图片描述


六、四大图表适用场景速查

图表类型 一句话用途 典型场景
折线图 看趋势 月度销售走势、日活变化
柱状图 看对比 各产品销量、各部门业绩
饼图 看占比 渠道分布、成本构成
散点图 看关系 价格与销量、广告投入与转化

记住这个表,大部分场景选图就不会错。


七、通用小技巧

保存高清图片:

plt.savefig('图表.png', dpi=150, bbox_inches='tight')
# dpi=150 足够清晰,要打印用 dpi=300
# bbox_inches='tight' 去掉多余白边

子图布局(一张图里放多个小图):

fig, axes = plt.subplots(2, 2, figsize=(12, 8))

axes[0, 0].plot(months, sales, color='#2196F3')
axes[0, 0].set_title('月度趋势')

axes[0, 1].bar(products, category_sales, color='#FF5722')
axes[0, 1].set_title('商品对比')

axes[1, 0].pie(channel_share, labels=channels, autopct='%1.1f%%')
axes[1, 0].set_title('渠道占比')

axes[1, 1].scatter(prices, volumes, color='#4CAF50')
axes[1, 1].set_title('价格vs销量')

plt.tight_layout()
plt.savefig('四图合一.png', dpi=150)
plt.show()

在这里插入图片描述

八、小结

四大基础图表画完了。核心代码其实都很短,关键是知道什么场景用什么图

  • 有时间维度 → 折线图
  • 要比较大小 → 柱状图
  • 要看比例 → 饼图
  • 要看两个变量的关系 → 散点图

Matplotlib 的 API 很多,不需要全记住。记住常用的,遇到不会的查文档或者问 AI 就行。

下一篇讲怎么把这些基础图表变好看——配色、标注、布局这些"审美"层面的东西。


下期预告: Day 06 图表美化——配色方案、标注技巧、子图布局、中文显示问题解决,让你的图从"能用"变成"好看"。


往期回顾

Day 01 · 数据可视化到底在干啥?为什么 AI 让它变简单了

Day 02:环境搭建 Python 数据分析零成本工具包

Day 03 · Pandas 快速上手:读取、清洗、整理数据

Day 04 · 数据清洗:缺失值、异常值、重复值一站式处理

专栏

-「AI Python 系列」第 02 栏 ·AI+数据可视化(连载中)
-「AI Python 系列」第 01 栏 · AI+自动化办公(连载中)
-「AI Python 系列」第 03 栏 · Python 爬虫实战(连载中)

资源领取

  • 关注作者获取本栏完整代码和数据集

原创声明:本文为梅雅达编程笔记原创作品,未经允许不得转载。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐