前言
数据可视化是数据分析中最核心的环节之一,它能将枯燥的数字转化为直观的图形,帮助我们快速发现数据规律、洞察业务问题。本文将从基础到进阶,全面讲解 Python 中两大主流可视化库(Matplotlib、Seaborn)的使用方法,所有代码均可直接运行,配套详细注释和效果展示。
1. 环境准备:可视化库安装与基础配置
1.1 库安装
首先确保安装以下核心库,执行以下命令:
pip install matplotlib seaborn pandas numpy
Python 数据可视化核心在于使用 Matplotlib 和 Seaborn 库将数据转化为直观图形。内容涵盖环境配置、基础图形(折线、柱状、散点、饼图)绘制、统计可视化(热力、箱线、小提琴图)及电商实战案例。涉及图形美化、多图组合布局、中文显示处理及高清保存技巧。提供避坑指南与最佳实践,帮助开发者高效完成数据分析与报告生成。
数据可视化是数据分析中最核心的环节之一,它能将枯燥的数字转化为直观的图形,帮助我们快速发现数据规律、洞察业务问题。本文将从基础到进阶,全面讲解 Python 中两大主流可视化库(Matplotlib、Seaborn)的使用方法,所有代码均可直接运行,配套详细注释和效果展示。
首先确保安装以下核心库,执行以下命令:
pip install matplotlib seaborn pandas numpy
在开始绘图前,先进行全局配置,解决中文显示、负号显示等常见问题:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
# 设置全局字体,解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei'] # 黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 设置图形风格和大小
sns.set_style("whitegrid") # 网格风格
plt.rcParams['figure.figsize'] = (10, 6) # 默认图形大小
Matplotlib 是 Python 可视化的基础库,灵活性极高,能绘制几乎所有类型的静态图形。
适用场景:时间序列数据、连续变量变化趋势
# 构造示例数据:月度销售额
months = ['1 月', '2 月', '3 月', '4 月', '5 月', '6 月']
sales = [120, 150, 130, 180, 200, 220]
# 创建画布
fig, ax = plt.subplots()
# 绘制折线图
ax.plot(months, sales, color='#FF6B6B', linewidth=2, marker='o', markersize=8)
# 添加标题和标签
ax.set_title('2024 年上半年销售额趋势', fontsize=16, pad=20)
ax.set_xlabel('月份', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
# 添加数值标签
for x, y in zip(months, sales):
ax.text(x, y+5, f'{y}', ha='center', fontsize=10)
# 保存图片(高清)
plt.savefig('sales_trend.png', dpi=300, bbox_inches='tight')
plt.show()
适用场景:不同类别数据的对比分析
# 构造示例数据:各产品销量
products = ['产品 A', '产品 B', '产品 C', '产品 D']
sales_2023 = [80, 100, 90, 70]
sales_2024 = [95, 110, 85, 88]
# 计算柱子位置
x = np.arange(len(products))
width = 0.35
# 绘制分组柱状图
fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, sales_2023, width, label='2023 年', color='#4ECDC4')
rects2 = ax.bar(x + width/2, sales_2024, width, label='2024 年', color='#FFE66D')
# 添加标题和标签
ax.set_title('2023-2024 年各产品销量对比', fontsize=16, pad=20)
ax.set_xlabel('产品类型', fontsize=12)
ax.set_ylabel('销量(件)', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(products)
ax.legend()
# 添加数值标签
def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax.annotate(f'{height}', xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=10)
autolabel(rects1)
autolabel(rects2)
plt.savefig('product_sales.png', dpi=300, bbox_inches='tight')
plt.show()
适用场景:分析两个连续变量之间的关系
# 构造示例数据:广告投入与销售额
np.random.seed(42)
ad_spend = np.random.uniform(10, 50, 50)
sales = 2 * ad_spend + np.random.normal(0, 8, 50)
# 绘制散点图
fig, ax = plt.subplots()
scatter = ax.scatter(ad_spend, sales, c='#FF6B6B', alpha=0.7, s=60)
# 添加趋势线
z = np.polyfit(ad_spend, sales, 1)
p = np.poly1d(z)
ax.plot(ad_spend, p(ad_spend), "k--", linewidth=2, label=f'趋势线:y={z[0]:.2f}x+{z[1]:.2f}')
# 添加标题和标签
ax.set_title('广告投入与销售额相关性分析', fontsize=16, pad=20)
ax.set_xlabel('广告投入(万元)', fontsize=12)
ax.set_ylabel('销售额(万元)', fontsize=12)
ax.legend()
plt.savefig('ad_sales_corr.png', dpi=300, bbox_inches='tight')
plt.show()
适用场景:各类别占总体的比例分析
# 构造示例数据:用户来源渠道
channels = ['抖音', '小红书', '公众号', '朋友圈', '其他']
user_counts = [45, 25, 15, 10, 5]
colors = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99', '#FF99CC']
explode = (0.1, 0, 0, 0, 0)
# 绘制饼图
fig, ax = plt.subplots()
wedges, texts, autotexts = ax.pie(user_counts, explode=explode, labels=channels, colors=colors, autopct='%1.1f%%', shadow=True, startangle=90)
# 美化文字
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(10)
ax.set_title('用户来源渠道分布', fontsize=16, pad=20)
ax.axis('equal')
plt.savefig('user_channel.png', dpi=300, bbox_inches='tight')
plt.show()
Seaborn 基于 Matplotlib 开发,专为统计可视化设计,语法更简洁,样式更美观,尤其适合分析复杂的数据集。
适用场景:多变量之间的相关性分析
# 构造示例数据:鸢尾花数据集
iris = sns.load_dataset('iris')
corr = iris.iloc[:, :-1].corr()
# 绘制热力图
fig, ax = plt.subplots(figsize=(8, 6))
heatmap = sns.heatmap(corr, annot=True, cmap='RdBu_r', vmin=-1, vmax=1, square=True, ax=ax)
ax.set_title('鸢尾花特征相关性热力图', fontsize=16, pad=20)
plt.savefig('corr_heatmap.png', dpi=300, bbox_inches='tight')
plt.show()
适用场景:展示数据的四分位数、中位数和异常值
# 构造示例数据:不同地区的用户消费金额
data = pd.DataFrame({
'地区': ['华北']*30 + ['华东']*30 + ['华南']*30,
'消费金额': np.concatenate([
np.random.normal(500, 80, 30),
np.random.normal(600, 100, 30),
np.random.normal(550, 90, 30)
])
})
# 绘制箱线图
fig, ax = plt.subplots()
boxplot = sns.boxplot(x='地区', y='消费金额', data=data, palette='Set2', ax=ax)
ax.set_title('不同地区用户消费金额分布', fontsize=16, pad=20)
ax.set_xlabel('地区', fontsize=12)
ax.set_ylabel('消费金额(元)', fontsize=12)
plt.savefig('consume_boxplot.png', dpi=300, bbox_inches='tight')
plt.show()
适用场景:更细致地展示数据分布形态
# 使用上述消费金额数据绘制小提琴图
fig, ax = plt.subplots()
violin = sns.violinplot(x='地区', y='消费金额', data=data, palette='Pastel1', inner='quartile', ax=ax)
ax.set_title('不同地区用户消费金额分布(小提琴图)', fontsize=16, pad=20)
ax.set_xlabel('地区', fontsize=12)
ax.set_ylabel('消费金额(元)', fontsize=12)
plt.savefig('consume_violin.png', dpi=300, bbox_inches='tight')
plt.show()
首先构造一份模拟的电商用户行为数据(实际使用时替换为真实数据):
# 构造电商用户行为数据
np.random.seed(42)
dates = pd.date_range(start='2024-01-01', end='2024-01-31', freq='D')
user_data = pd.DataFrame({
'日期': np.repeat(dates, 100),
'用户 ID': np.random.randint(10000, 99999, 3100),
'行为类型': np.random.choice(['浏览', '加购', '下单', '支付'], 3100, p=[0.6, 0.2, 0.15, 0.05]),
'消费金额': np.where(
np.random.choice(['浏览', '加购', '下单', '支付'], 3100, p=[0.6, 0.2, 0.15, 0.05]) == '支付',
np.random.uniform(50, 1000, 3100),
0
),
'用户等级': np.random.choice(['普通', 'VIP', 'SVIP'], 3100, p=[0.7, 0.2, 0.1])
})
# 数据概览
print("数据前 5 行:")
print(user_data.head())
print("\n数据基本信息:")
print(user_data.info())
print("\n数据统计描述:")
print(user_data.describe())
# 1. 每日行为类型统计
daily_behavior = user_data.groupby(['日期', '行为类型']).size().unstack(fill_value=0)
# 2. 各用户等级消费金额统计
level_consume = user_data.groupby('用户等级')['消费金额'].agg(['sum', 'mean', 'count']).round(2)
level_consume.columns = ['总消费金额', '平均消费金额', '支付用户数']
print("每日用户行为类型统计(前 5 行):")
print(daily_behavior.head())
print("\n各用户等级消费金额统计:")
print(level_consume)
# 保存表格为 CSV(可选)
daily_behavior.to_csv('daily_behavior.csv')
level_consume.to_csv('level_consume.csv')
表格展示:
| 用户等级 | 总消费金额 | 平均消费金额 | 支付用户数 |
|---|---|---|---|
| 普通 | 12568.78 | 452.46 | 28 |
| VIP | 8956.32 | 688.95 | 13 |
| SVIP | 6789.21 | 848.65 | 8 |
# 创建 2x2 子图布局
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
# 子图 1:每日各行为类型数量趋势
daily_behavior.plot(kind='line', ax=ax1, marker='o', linewidth=1.5)
ax1.set_title('每日用户行为类型趋势', fontsize=14)
ax1.set_xlabel('日期')
ax1.set_ylabel('行为次数')
ax1.legend(loc='upper right')
ax1.tick_params(axis='x', rotation=45)
# 子图 2:行为类型占比饼图
behavior_count = user_data['行为类型'].value_counts()
ax2.pie(behavior_count.values, labels=behavior_count.index, autopct='%1.1f%%', colors=['#FF9999', '#66B2FF', '#99FF99', '#FFCC99'])
ax2.set_title('用户行为类型占比', fontsize=14)
# 子图 3:各用户等级消费金额对比
level_consume['总消费金额'].plot(kind='bar', ax=ax3, color=['#4ECDC4', '#FF6B6B', '#FFE66D'])
ax3.set_title('各用户等级总消费金额', fontsize=14)
ax3.set_xlabel('用户等级')
ax3.set_ylabel('消费金额(元)')
# 添加数值标签
for x, y in enumerate(level_consume['总消费金额']):
ax3.text(x, y+200, f'{y}', ha='center', fontsize=10)
# 子图 4:各用户等级平均消费金额
level_consume['平均消费金额'].plot(kind='barh', ax=ax4, color=['#9999FF', '#FF99CC', '#FFB366'])
ax4.set_title('各用户等级平均消费金额', fontsize=14)
ax4.set_xlabel('平均消费金额(元)')
ax4.set_ylabel('用户等级')
# 添加数值标签
for x, y in enumerate(level_consume['平均消费金额']):
ax4.text(y+20, x, f'{y}', va='center', fontsize=10)
# 整体标题
fig.suptitle('2024 年 1 月电商用户行为分析报告', fontsize=18, y=0.98)
# 调整子图间距
plt.tight_layout()
plt.savefig('ecommerce_analysis.png', dpi=300, bbox_inches='tight')
plt.show()
# 自定义颜色方案
my_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
# 自定义样式
plt.style.use('ggplot')
fig, ax = plt.subplots()
ax.bar(['A', 'B', 'C', 'D', 'E'], [10, 20, 15, 25, 18], color=my_colors)
# 添加网格
ax.grid(True, axis='y', alpha=0.3, linestyle='--')
# 隐藏边框
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# 调整刻度字体
ax.tick_params(axis='both', labelsize=11)
ax.set_title('自定义样式示例', fontsize=16)
plt.show()
# 不等比例子图布局
fig = plt.figure(figsize=(15, 10))
# 创建子图:1 行 2 列,第一个子图占 1 列,第二个子图占 1 列
ax1 = plt.subplot2grid((2, 2), (0, 0), colspan=1)
ax2 = plt.subplot2grid((2, 2), (0, 1), colspan=1)
ax3 = plt.subplot2grid((2, 2), (1, 0), colspan=2)
# 子图 1:折线图
ax1.plot([1,2,3,4], [10,20,15,25], color=my_colors[0], linewidth=2)
ax1.set_title('子图 1:折线图')
# 子图 2:散点图
ax2.scatter([1,2,3,4], [5,15,10,20], color=my_colors[1], s=50)
ax2.set_title('子图 2:散点图')
# 子图 3:柱状图
ax3.bar([1,2,3,4], [8,18,13,23], color=my_colors[2])
ax3.set_title('子图 3:柱状图(跨列)')
plt.suptitle('不等比例子图布局示例', fontsize=18)
plt.tight_layout()
plt.show()
plt.rcParams['font.sans-serif'] 和 plt.rcParams['axes.unicode_minus']dpi=300,并添加 bbox_inches='tight' 避免内容被裁剪
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online