Python数据可视化完全指南:Matplotlib与Seaborn高级技巧与实战案例

2025-09-06 0 190

掌握Matplotlib和Seaborn高级技巧,创建专业级数据可视化图表

Python数据可视化简介

数据可视化是数据分析中至关重要的一环,它通过图形化方式帮助人们理解和解释复杂数据。Python作为数据科学的首选语言,提供了多个强大的可视化库,其中Matplotlib和Seaborn是最受欢迎的两个库。

Matplotlib是Python中最基础、最广泛使用的绘图库,提供了类似MATLAB的绘图接口。Seaborn则是在Matplotlib基础上进行了高级封装,提供了更美观的默认样式和更简洁的API,特别适合统计可视化。

为什么选择Matplotlib和Seaborn?

  • 功能全面 – 支持几乎所有类型的图表
  • 高度可定制 – 可以调整每个图表元素的样式
  • 与Pandas完美集成 – 直接处理DataFrame和Series数据
  • 活跃的社区 – 丰富的文档和示例
  • 免费开源 – 无需支付任何费用

环境配置与安装

安装必要的库

使用pip安装数据可视化所需的库:

# 安装核心库
pip install matplotlib seaborn pandas numpy

# 安装Jupyter Notebook(可选,但推荐用于交互式可视化)
pip install jupyterlab

# 安装额外样式库(可选)
pip install cycler

导入库与设置

在Python脚本或Jupyter Notebook中导入所需库:

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

# 设置Seaborn样式
sns.set_style("whitegrid")

# 设置中文字体支持(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

# 设置图表大小和DPI
plt.rcParams['figure.figsize'] = (10, 6)
plt.rcParams['figure.dpi'] = 100

# 在Jupyter Notebook中显示图表
%matplotlib inline

Matplotlib基础与核心概念

创建第一个图表

# 创建简单折线图
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

plt.plot(x, y)
plt.title('简单折线图')
plt.xlabel('X轴')
plt.ylabel('Y轴')
plt.show()

多种图表类型

# 创建数据
data = [25, 30, 20, 15, 10]
labels = ['A', 'B', 'C', 'D', 'E']

# 创建子图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 折线图
axes[0, 0].plot(labels, data, marker='o', color='blue')
axes[0, 0].set_title('折线图')

# 柱状图
axes[0, 1].bar(labels, data, color='green')
axes[0, 1].set_title('柱状图')

# 饼图
axes[1, 0].pie(data, labels=labels, autopct='%1.1f%%')
axes[1, 0].set_title('饼图')

# 散点图
axes[1, 1].scatter(range(len(data)), data, s=100, color='red')
axes[1, 1].set_title('散点图')

plt.tight_layout()
plt.show()

自定义图表样式

# 创建更专业的图表
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

plt.figure(figsize=(12, 6))

# 绘制两条线
plt.plot(x, y1, label='sin(x)', linewidth=2, linestyle='-', color='blue')
plt.plot(x, y2, label='cos(x)', linewidth=2, linestyle='--', color='red')

# 添加标题和标签
plt.title('三角函数图像', fontsize=16, fontweight='bold')
plt.xlabel('X值', fontsize=12)
plt.ylabel('Y值', fontsize=12)

# 添加网格和图例
plt.grid(True, linestyle=':', alpha=0.7)
plt.legend(loc='best', fontsize=12)

# 设置坐标轴范围
plt.xlim(0, 10)
plt.ylim(-1.2, 1.2)

# 添加注释
plt.annotate('最大值', xy=(np.pi/2, 1), xytext=(np.pi/2+1, 0.8),
            arrowprops=dict(facecolor='black', shrink=0.05))

plt.tight_layout()
plt.show()

Seaborn高级可视化

Seaborn基于Matplotlib,提供了更高级的API和更美观的默认样式,特别适合统计数据分析。

使用内置数据集

# 加载Seaborn内置数据集
tips = sns.load_dataset('tips')
iris = sns.load_dataset('iris')

print("Tips数据集前5行:")
print(tips.head())

print("nIris数据集前5行:")
print(iris.head())

分类数据可视化

# 创建多个子图
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# 箱线图
sns.boxplot(x='day', y='total_bill', data=tips, ax=axes[0, 0])
axes[0, 0].set_title('每天消费金额箱线图')

# 小提琴图
sns.violinplot(x='day', y='total_bill', hue='sex', data=tips, ax=axes[0, 1])
axes[0, 1].set_title('按性别分类的小提琴图')

# 柱状图
sns.barplot(x='day', y='total_bill', hue='sex', data=tips, ax=axes[1, 0])
axes[1, 0].set_title('按性别分类的柱状图')

# 点图
sns.pointplot(x='day', y='total_bill', hue='sex', data=tips, ax=axes[1, 1])
axes[1, 1].set_title('按性别分类的点图')

plt.tight_layout()
plt.show()

分布可视化

# 创建分布图
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# 直方图
sns.histplot(tips['total_bill'], kde=True, ax=axes[0, 0])
axes[0, 0].set_title('消费金额分布直方图')

# 核密度估计图
sns.kdeplot(data=tips, x='total_bill', hue='time', ax=axes[0, 1])
axes[0, 1].set_title('不同时间的消费金额分布')

# 散点图与回归线
sns.regplot(x='total_bill', y='tip', data=tips, ax=axes[1, 0])
axes[1, 0].set_title('消费金额与小费关系图')

# 热力图
corr = tips.corr()
sns.heatmap(corr, annot=True, cmap='coolwarm', ax=axes[1, 1])
axes[1, 1].set_title('数值变量相关性热力图')

plt.tight_layout()
plt.show()

高级可视化技巧

多子图与复杂布局

# 创建复杂布局
fig = plt.figure(figsize=(16, 12))

# 使用GridSpec创建复杂布局
gs = fig.add_gridspec(3, 3)

# 主图 - 散点图
ax1 = fig.add_subplot(gs[0:2, 0:2])
sns.scatterplot(x='total_bill', y='tip', hue='day', size='size', data=tips, ax=ax1)
ax1.set_title('消费金额与小费关系(按天和人数)')

# 右上角 - 箱线图
ax2 = fig.add_subplot(gs[0, 2])
sns.boxplot(y='total_bill', data=tips, ax=ax2)
ax2.set_title('消费金额分布')

# 右下角 - 饼图(需要转换为Matplotlib)
ax3 = fig.add_subplot(gs[1, 2])
day_counts = tips['day'].value_counts()
ax3.pie(day_counts.values, labels=day_counts.index, autopct='%1.1f%%')
ax3.set_title('各天消费比例')

# 底部 - 柱状图
ax4 = fig.add_subplot(gs[2, 0:])
sns.countplot(x='day', hue='sex', data=tips, ax=ax4)
ax4.set_title('各天不同性别消费次数')

plt.tight_layout()
plt.show()

自定义颜色与样式

# 创建自定义颜色方案
custom_palette = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#F9A602", "#9B59B6"]

# 使用自定义调色板
plt.figure(figsize=(12, 6))
sns.set_palette(custom_palette)

# 创建分组柱状图
ax = sns.barplot(x='day', y='total_bill', hue='sex', data=tips, 
                 ci=None, palette=custom_palette)

# 自定义样式
ax.set_title('自定义颜色的分组柱状图', fontsize=16, fontweight='bold')
ax.set_xlabel('星期', fontsize=12)
ax.set_ylabel('平均消费金额', fontsize=12)

# 添加数值标签
for p in ax.patches:
    ax.annotate(f'{p.get_height():.2f}', 
                (p.get_x() + p.get_width() / 2., p.get_height()),
                ha='center', va='center', xytext=(0, 10), 
                textcoords='offset points', fontsize=10)

plt.legend(title='性别')
plt.tight_layout()
plt.show()

交互式可视化

# 使用Plotly创建交互式图表(需要安装plotly)
try:
    import plotly.express as px
    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    
    # 创建交互式散点图
    fig = px.scatter(tips, x='total_bill', y='tip', color='day', 
                     size='size', hover_data=['time', 'sex'],
                     title='交互式消费数据可视化')
    fig.show()
    
except ImportError:
    print("Plotly未安装,请使用 'pip install plotly' 安装")

实战项目:电商销售数据分析可视化

下面我们使用模拟的电商销售数据,创建一个完整的数据可视化项目。

生成模拟数据

# 生成模拟电商数据
np.random.seed(42)  # 确保结果可重现

# 创建日期范围
dates = pd.date_range('2023-01-01', '2023-12-31', freq='D')

# 生成销售数据
n_days = len(dates)
data = {
    'date': np.random.choice(dates, 5000),
    'product_category': np.random.choice(['电子产品', '服装', '家居', '食品', '图书'], 5000),
    'price': np.round(np.random.uniform(10, 500, 5000), 2),
    'quantity': np.random.randint(1, 5, 5000),
    'customer_age': np.random.randint(18, 70, 5000),
    'customer_gender': np.random.choice(['男', '女'], 5000),
    'payment_method': np.random.choice(['信用卡', '支付宝', '微信支付', '银行转账'], 5000)
}

# 创建DataFrame
df = pd.DataFrame(data)
df['revenue'] = df['price'] * df['quantity']

# 添加月份和星期几列
df['month'] = df['date'].dt.month
df['day_of_week'] = df['date'].dt.day_name()

print("数据前5行:")
print(df.head())

print("n数据基本信息:")
print(df.info())

print("n描述性统计:")
print(df.describe())

销售趋势分析

# 按月份分析销售趋势
monthly_sales = df.groupby('month').agg({
    'revenue': 'sum',
    'quantity': 'sum',
    'date': 'count'
}).rename(columns={'date': 'transactions'})

# 创建销售趋势图
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# 月度收入趋势
axes[0, 0].plot(monthly_sales.index, monthly_sales['revenue'], marker='o', linewidth=2)
axes[0, 0].set_title('月度收入趋势')
axes[0, 0].set_xlabel('月份')
axes[0, 0].set_ylabel('收入')
axes[0, 0].grid(True, linestyle=':', alpha=0.7)

# 月度交易量趋势
axes[0, 1].bar(monthly_sales.index, monthly_sales['transactions'], color='orange')
axes[0, 1].set_title('月度交易量')
axes[0, 1].set_xlabel('月份')
axes[0, 1].set_ylabel('交易次数')

# 产品类别销售额占比
category_revenue = df.groupby('product_category')['revenue'].sum()
axes[1, 0].pie(category_revenue, labels=category_revenue.index, autopct='%1.1f%%')
axes[1, 0].set_title('产品类别销售额占比')

# 支付方式分布
payment_counts = df['payment_method'].value_counts()
axes[1, 1].bar(payment_counts.index, payment_counts.values, color=['blue', 'green', 'red', 'purple'])
axes[1, 1].set_title('支付方式分布')
axes[1, 1].tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.show()

客户行为分析

# 客户行为分析
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# 客户年龄分布
sns.histplot(df['customer_age'], bins=20, kde=True, ax=axes[0, 0])
axes[0, 0].set_title('客户年龄分布')
axes[0, 0].set_xlabel('年龄')
axes[0, 0].set_ylabel('频次')

# 不同性别消费金额
gender_sales = df.groupby('customer_gender')['revenue'].sum()
axes[0, 1].bar(gender_sales.index, gender_sales.values, color=['pink', 'lightblue'])
axes[0, 1].set_title('不同性别消费总额')
axes[0, 1].set_ylabel('消费金额')

# 不同年龄段的消费偏好
age_bins = [18, 25, 35, 45, 55, 70]
age_labels = ['18-25', '26-35', '36-45', '46-55', '56-70']
df['age_group'] = pd.cut(df['customer_age'], bins=age_bins, labels=age_labels)

age_category = df.groupby(['age_group', 'product_category'])['revenue'].sum().unstack()
age_category.plot(kind='bar', ax=axes[1, 0])
axes[1, 0].set_title('不同年龄段的产品偏好')
axes[1, 0].set_ylabel('消费金额')
axes[1, 0].legend(title='产品类别')
axes[1, 0].tick_params(axis='x', rotation=45)

# 一周中各天的销售情况
weekday_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
weekday_sales = df.groupby('day_of_week')['revenue'].sum().reindex(weekday_order)
axes[1, 1].plot(weekday_sales.index, weekday_sales.values, marker='o')
axes[1, 1].set_title('一周中各天的销售情况')
axes[1, 1].set_xlabel('星期')
axes[1, 1].set_ylabel('消费金额')
axes[1, 1].tick_params(axis='x', rotation=45)
axes[1, 1].grid(True, linestyle=':', alpha=0.7)

plt.tight_layout()
plt.show()

高级综合仪表板

# 创建综合仪表板
fig = plt.figure(figsize=(18, 14))
gs = fig.add_gridspec(3, 4)

# 1. 销售趋势图
ax1 = fig.add_subplot(gs[0, 0:2])
daily_sales = df.groupby('date')['revenue'].sum()
ax1.plot(daily_sales.index, daily_sales.values, linewidth=1)
ax1.set_title('每日销售趋势', fontweight='bold')
ax1.set_ylabel('销售额')

# 2. 产品类别销售占比
ax2 = fig.add_subplot(gs[0, 2:])
category_sales = df.groupby('product_category')['revenue'].sum()
ax2.pie(category_sales.values, labels=category_sales.index, autopct='%1.1f%%')
ax2.set_title('产品类别销售占比', fontweight='bold')

# 3. 客户年龄与消费关系
ax3 = fig.add_subplot(gs[1, 0:2])
sns.scatterplot(data=df, x='customer_age', y='revenue', hue='customer_gender', alpha=0.6, ax=ax3)
ax3.set_title('客户年龄与消费金额关系', fontweight='bold')
ax3.set_xlabel('年龄')
ax3.set_ylabel('消费金额')

# 4. 支付方式偏好
ax4 = fig.add_subplot(gs[1, 2:])
payment_by_gender = df.groupby(['payment_method', 'customer_gender']).size().unstack()
payment_by_gender.plot(kind='bar', ax=ax4)
ax4.set_title('不同性别的支付方式偏好', fontweight='bold')
ax4.set_ylabel('交易次数')
ax4.tick_params(axis='x', rotation=45)

# 5. 月度销售热力图
ax5 = fig.add_subplot(gs[2, 0:2])
df['week'] = df['date'].dt.isocalendar().week
heatmap_data = df.groupby(['month', 'week']).agg({'revenue': 'sum'}).unstack()
sns.heatmap(heatmap_data, cmap='YlOrRd', ax=ax5)
ax5.set_title('月度销售热力图', fontweight='bold')
ax5.set_xlabel('周')
ax5.set_ylabel('月')

# 6. 客单价分布
ax6 = fig.add_subplot(gs[2, 2:])
sns.boxplot(data=df, x='product_category', y='price', ax=ax6)
ax6.set_title('不同产品类别的价格分布', fontweight='bold')
ax6.set_ylabel('价格')
ax6.tick_params(axis='x', rotation=45)

plt.tight_layout()
plt.suptitle('电商销售数据分析仪表板', fontsize=20, fontweight='bold', y=0.98)
plt.show()

Python数据可视化完全指南:Matplotlib与Seaborn高级技巧与实战案例
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 python Python数据可视化完全指南:Matplotlib与Seaborn高级技巧与实战案例 https://www.taomawang.com/server/python/1034.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务