#Pandas 数据可视化
数据可视化是数据分析的重要组成部分,它能够帮助我们直观地理解数据的分布、趋势和模式。Pandas 提供了强大的可视化功能,可以与 matplotlib 和 seaborn 无缝集成,让我们能够快速创建各种类型的图表。
#1. 可视化基础设置
#1.1 环境配置
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体和负号显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
# 设置图表样式
plt.style.use('seaborn-v0_8')
sns.set_palette("husl")
# 设置图表大小
plt.rcParams['figure.figsize'] = (12, 8)
plt.rcParams['font.size'] = 10
print("可视化环境配置完成")#1.2 创建示例数据集
# 设置随机种子
np.random.seed(42)
# 创建综合数据集
n_samples = 1000
# 销售数据
sales_data = {
'date': pd.date_range('2022-01-01', periods=365, freq='D'),
'product': np.random.choice(['产品A', '产品B', '产品C', '产品D', '产品E'], 365),
'region': np.random.choice(['北区', '南区', '东区', '西区'], 365),
'sales_amount': np.random.normal(1000, 300, 365),
'quantity': np.random.randint(10, 100, 365),
'customer_satisfaction': np.random.uniform(3.0, 5.0, 365)
}
# 确保销售额为正数
sales_data['sales_amount'] = np.maximum(sales_data['sales_amount'], 100)
sales_df = pd.DataFrame(sales_data)
sales_df['month'] = sales_df['date'].dt.month
sales_df['quarter'] = sales_df['date'].dt.quarter
sales_df['weekday'] = sales_df['date'].dt.day_name()
# 员工数据
employee_data = {
'employee_id': range(1, n_samples + 1),
'department': np.random.choice(['IT', 'HR', 'Finance', 'Marketing', 'Operations'], n_samples),
'position': np.random.choice(['初级', '中级', '高级', '专家', '经理'], n_samples),
'salary': np.random.normal(8000, 2000, n_samples),
'age': np.random.randint(22, 60, n_samples),
'experience_years': np.random.randint(0, 20, n_samples),
'performance_score': np.random.uniform(60, 100, n_samples)
}
employee_data['salary'] = np.maximum(employee_data['salary'], 3000)
employee_df = pd.DataFrame(employee_data)
print("示例数据集创建完成")
print(f"销售数据: {sales_df.shape}")
print(f"员工数据: {employee_df.shape}")#2. 基础图表类型
#2.1 线图 (Line Plot)
print("\n=== 线图示例 ===")
# 时间序列线图
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 基本时间序列线图
daily_sales = sales_df.groupby('date')['sales_amount'].sum()
daily_sales.plot(ax=axes[0,0], color='blue', linewidth=2)
axes[0,0].set_title('每日销售额趋势')
axes[0,0].set_ylabel('销售额')
axes[0,0].grid(True, alpha=0.3)
# 2. 多条线图
product_daily_sales = sales_df.groupby(['date', 'product'])['sales_amount'].sum().unstack()
product_daily_sales.plot(ax=axes[0,1], marker='o', markersize=3)
axes[0,1].set_title('各产品每日销售额')
axes[0,1].set_ylabel('销售额')
axes[0,1].legend(title='产品', bbox_to_anchor=(1.05, 1), loc='upper left')
axes[0,1].grid(True, alpha=0.3)
# 3. 滚动平均线图
daily_sales_ma = daily_sales.rolling(window=7).mean()
axes[1,0].plot(daily_sales.index, daily_sales.values, alpha=0.3, label='原始数据')
axes[1,0].plot(daily_sales_ma.index, daily_sales_ma.values, color='red', linewidth=2, label='7日移动平均')
axes[1,0].set_title('销售额与移动平均')
axes[1,0].set_ylabel('销售额')
axes[1,0].legend()
axes[1,0].grid(True, alpha=0.3)
# 4. 面积图
region_daily_sales = sales_df.groupby(['date', 'region'])['sales_amount'].sum().unstack()
region_daily_sales.plot.area(ax=axes[1,1], alpha=0.7)
axes[1,1].set_title('各区域销售额堆叠面积图')
axes[1,1].set_ylabel('销售额')
axes[1,1].legend(title='区域', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
# 使用 Pandas 内置绘图方法
print("\n使用 Pandas 内置方法绘制线图:")
# 月度销售趋势
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
monthly_sales.plot(kind='line', marker='o', title='月度销售额趋势', figsize=(10, 6))
plt.ylabel('销售额')
plt.xlabel('月份')
plt.grid(True, alpha=0.3)
plt.show()#2.2 柱状图 (Bar Plot)
print("\n=== 柱状图示例 ===")
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 基本柱状图
product_sales = sales_df.groupby('product')['sales_amount'].sum().sort_values(ascending=False)
product_sales.plot(kind='bar', ax=axes[0,0], color='skyblue')
axes[0,0].set_title('各产品总销售额')
axes[0,0].set_ylabel('销售额')
axes[0,0].tick_params(axis='x', rotation=45)
# 2. 水平柱状图
region_sales = sales_df.groupby('region')['sales_amount'].sum().sort_values()
region_sales.plot(kind='barh', ax=axes[0,1], color='lightcoral')
axes[0,1].set_title('各区域总销售额')
axes[0,1].set_xlabel('销售额')
# 3. 分组柱状图
product_region_sales = sales_df.groupby(['product', 'region'])['sales_amount'].sum().unstack()
product_region_sales.plot(kind='bar', ax=axes[1,0])
axes[1,0].set_title('产品-区域销售额分组柱状图')
axes[1,0].set_ylabel('销售额')
axes[1,0].tick_params(axis='x', rotation=45)
axes[1,0].legend(title='区域', bbox_to_anchor=(1.05, 1), loc='upper left')
# 4. 堆叠柱状图
product_region_sales.plot(kind='bar', stacked=True, ax=axes[1,1])
axes[1,1].set_title('产品-区域销售额堆叠柱状图')
axes[1,1].set_ylabel('销售额')
axes[1,1].tick_params(axis='x', rotation=45)
axes[1,1].legend(title='区域', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
# 员工数据柱状图
print("\n员工数据柱状图:")
fig, axes = plt.subplots(1, 2, figsize=(15, 6))
# 部门人数分布
dept_count = employee_df['department'].value_counts()
dept_count.plot(kind='bar', ax=axes[0], color='lightgreen')
axes[0].set_title('各部门人数分布')
axes[0].set_ylabel('人数')
axes[0].tick_params(axis='x', rotation=45)
# 职位分布
position_count = employee_df['position'].value_counts()
position_count.plot(kind='pie', ax=axes[1], autopct='%1.1f%%')
axes[1].set_title('职位分布饼图')
axes[1].set_ylabel('')
plt.tight_layout()
plt.show()#2.3 散点图 (Scatter Plot)
print("\n=== 散点图示例 ===")
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 基本散点图
employee_df.plot.scatter(x='age', y='salary', ax=axes[0,0], alpha=0.6)
axes[0,0].set_title('年龄与薪资关系')
axes[0,0].set_xlabel('年龄')
axes[0,0].set_ylabel('薪资')
# 2. 带颜色分组的散点图
for dept in employee_df['department'].unique():
dept_data = employee_df[employee_df['department'] == dept]
axes[0,1].scatter(dept_data['experience_years'], dept_data['salary'],
label=dept, alpha=0.6)
axes[0,1].set_title('工作经验与薪资关系(按部门分组)')
axes[0,1].set_xlabel('工作经验(年)')
axes[0,1].set_ylabel('薪资')
axes[0,1].legend()
# 3. 气泡图(散点大小表示第三个变量)
scatter = axes[1,0].scatter(employee_df['age'], employee_df['salary'],
s=employee_df['performance_score']*2,
c=employee_df['experience_years'],
alpha=0.6, cmap='viridis')
axes[1,0].set_title('年龄-薪资-绩效-经验综合散点图')
axes[1,0].set_xlabel('年龄')
axes[1,0].set_ylabel('薪资')
colorbar = plt.colorbar(scatter, ax=axes[1,0])
colorbar.set_label('工作经验(年)')
# 4. 销售数据散点图
sales_df.plot.scatter(x='quantity', y='sales_amount',
c='customer_satisfaction',
colormap='RdYlBu', ax=axes[1,1], alpha=0.6)
axes[1,1].set_title('销量与销售额关系(颜色表示客户满意度)')
axes[1,1].set_xlabel('销量')
axes[1,1].set_ylabel('销售额')
plt.tight_layout()
plt.show()
# 相关性矩阵散点图
print("\n相关性分析散点图:")
numeric_cols = ['age', 'salary', 'experience_years', 'performance_score']
fig, ax = plt.subplots(figsize=(10, 8))
pd.plotting.scatter_matrix(employee_df[numeric_cols], ax=ax, alpha=0.6, diagonal='hist')
plt.suptitle('员工数据相关性矩阵散点图')
plt.tight_layout()
plt.show()#2.4 直方图和密度图
print("\n=== 直方图和密度图示例 ===")
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 基本直方图
employee_df['salary'].plot.hist(bins=30, ax=axes[0,0], alpha=0.7, color='skyblue')
axes[0,0].set_title('薪资分布直方图')
axes[0,0].set_xlabel('薪资')
axes[0,0].set_ylabel('频数')
# 2. 密度图
employee_df['salary'].plot.density(ax=axes[0,1], color='red', linewidth=2)
axes[0,1].set_title('薪资分布密度图')
axes[0,1].set_xlabel('薪资')
axes[0,1].set_ylabel('密度')
# 3. 分组直方图
for dept in employee_df['department'].unique():
dept_salary = employee_df[employee_df['department'] == dept]['salary']
axes[1,0].hist(dept_salary, alpha=0.5, label=dept, bins=20)
axes[1,0].set_title('各部门薪资分布对比')
axes[1,0].set_xlabel('薪资')
axes[1,0].set_ylabel('频数')
axes[1,0].legend()
# 4. 多变量密度图
for dept in employee_df['department'].unique():
dept_salary = employee_df[employee_df['department'] == dept]['salary']
dept_salary.plot.density(ax=axes[1,1], alpha=0.7, label=dept)
axes[1,1].set_title('各部门薪资密度分布对比')
axes[1,1].set_xlabel('薪资')
axes[1,1].set_ylabel('密度')
axes[1,1].legend()
plt.tight_layout()
plt.show()
# 使用 seaborn 绘制更美观的分布图
print("\n使用 Seaborn 绘制分布图:")
fig, axes = plt.subplots(1, 2, figsize=(15, 6))
# 直方图 + 密度图
sns.histplot(data=employee_df, x='salary', hue='department',
kde=True, ax=axes[0], alpha=0.6)
axes[0].set_title('各部门薪资分布(直方图+密度图)')
# 小提琴图
sns.violinplot(data=employee_df, x='department', y='salary', ax=axes[1])
axes[1].set_title('各部门薪资分布(小提琴图)')
axes[1].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()#3. 高级图表类型
#3.1 箱线图 (Box Plot)
print("\n=== 箱线图示例 ===")
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 1. 基本箱线图
employee_df.boxplot(column='salary', ax=axes[0,0])
axes[0,0].set_title('薪资分布箱线图')
axes[0,0].set_ylabel('薪资')
# 2. 分组箱线图
employee_df.boxplot(column='salary', by='department', ax=axes[0,1])
axes[0,1].set_title('各部门薪资分布箱线图')
axes[0,1].set_xlabel('部门')
axes[0,1].set_ylabel('薪资')
# 3. 多变量箱线图
employee_df[['salary', 'age', 'performance_score']].boxplot(ax=axes[1,0])
axes[1,0].set_title('多变量箱线图')
axes[1,0].tick_params(axis='x', rotation=45)
# 4. 使用 seaborn 绘制更美观的箱线图
sns.boxplot(data=employee_df, x='position', y='salary', ax=axes[1,1])
axes[1,1].set_title('各职位薪资分布箱线图')
axes[1,1].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
# 销售数据箱线图
print("\n销售数据箱线图:")
fig, axes = plt.subplots(1, 2, figsize=(15, 6))
# 各产品销售额箱线图
sns.boxplot(data=sales_df, x='product', y='sales_amount', ax=axes[0])
axes[0].set_title('各产品销售额分布')
axes[0].tick_params(axis='x', rotation=45)
# 各区域销售额箱线图
sns.boxplot(data=sales_df, x='region', y='sales_amount', ax=axes[1])
axes[1].set_title('各区域销售额分布')
plt.tight_layout()
plt.show()#3.2 热力图 (Heatmap)
print("\n=== 热力图示例 ===")
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
# 1. 相关性热力图
corr_matrix = employee_df[['age', 'salary', 'experience_years', 'performance_score']].corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0, ax=axes[0,0])
axes[0,0].set_title('员工数据相关性热力图')
# 2. 透视表热力图
product_region_pivot = sales_df.pivot_table(
values='sales_amount',
index='product',
columns='region',
aggfunc='mean'
)
sns.heatmap(product_region_pivot, annot=True, fmt='.0f', cmap='YlOrRd', ax=axes[0,1])
axes[0,1].set_title('产品-区域平均销售额热力图')
# 3. 时间序列热力图
sales_df['day'] = sales_df['date'].dt.day
month_day_sales = sales_df.pivot_table(
values='sales_amount',
index='month',
columns='day',
aggfunc='mean'
)
sns.heatmap(month_day_sales, cmap='viridis', ax=axes[1,0], cbar_kws={'label': '平均销售额'})
axes[1,0].set_title('月份-日期销售额热力图')
axes[1,0].set_xlabel('日期')
axes[1,0].set_ylabel('月份')
# 4. 部门-职位薪资热力图
dept_position_salary = employee_df.pivot_table(
values='salary',
index='department',
columns='position',
aggfunc='mean'
)
sns.heatmap(dept_position_salary, annot=True, fmt='.0f', cmap='plasma', ax=axes[1,1])
axes[1,1].set_title('部门-职位平均薪资热力图')
plt.tight_layout()
plt.show()
# 缺失值热力图
print("\n缺失值分析热力图:")
# 创建带缺失值的数据
df_with_missing = employee_df.copy()
np.random.seed(42)
for col in ['salary', 'age', 'performance_score']:
missing_idx = np.random.choice(df_with_missing.index, size=50, replace=False)
df_with_missing.loc[missing_idx, col] = np.nan
# 绘制缺失值热力图
plt.figure(figsize=(10, 6))
sns.heatmap(df_with_missing.isnull(), cbar=True, yticklabels=False, cmap='viridis')
plt.title('数据缺失值分布热力图')
plt.show()#3.3 多子图布局
print("\n=== 多子图布局示例 ===")
# 创建复杂的多子图布局
fig = plt.figure(figsize=(20, 15))
# 使用 GridSpec 创建自定义布局
from matplotlib.gridspec import GridSpec
gs = GridSpec(3, 4, figure=fig, hspace=0.3, wspace=0.3)
# 第一行:时间序列分析
ax1 = fig.add_subplot(gs[0, :2])
daily_sales = sales_df.groupby('date')['sales_amount'].sum()
daily_sales.plot(ax=ax1, color='blue', linewidth=2)
ax1.set_title('每日销售额趋势', fontsize=14)
ax1.grid(True, alpha=0.3)
ax2 = fig.add_subplot(gs[0, 2:])
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
monthly_sales.plot(kind='bar', ax=ax2, color='orange')
ax2.set_title('月度销售额分布', fontsize=14)
ax2.tick_params(axis='x', rotation=0)
# 第二行:产品和区域分析
ax3 = fig.add_subplot(gs[1, 0])
product_sales = sales_df.groupby('product')['sales_amount'].sum()
product_sales.plot(kind='pie', ax=ax3, autopct='%1.1f%%')
ax3.set_title('产品销售额占比', fontsize=14)
ax3.set_ylabel('')
ax4 = fig.add_subplot(gs[1, 1])
region_sales = sales_df.groupby('region')['sales_amount'].sum()
region_sales.plot(kind='bar', ax=ax4, color='lightcoral')
ax4.set_title('区域销售额对比', fontsize=14)
ax4.tick_params(axis='x', rotation=45)
ax5 = fig.add_subplot(gs[1, 2:])
sns.boxplot(data=sales_df, x='product', y='sales_amount', ax=ax5)
ax5.set_title('各产品销售额分布', fontsize=14)
ax5.tick_params(axis='x', rotation=45)
# 第三行:员工数据分析
ax6 = fig.add_subplot(gs[2, 0])
employee_df.plot.scatter(x='age', y='salary', alpha=0.6, ax=ax6)
ax6.set_title('年龄与薪资关系', fontsize=14)
ax7 = fig.add_subplot(gs[2, 1])
dept_count = employee_df['department'].value_counts()
dept_count.plot(kind='bar', ax=ax7, color='lightgreen')
ax7.set_title('部门人数分布', fontsize=14)
ax7.tick_params(axis='x', rotation=45)
ax8 = fig.add_subplot(gs[2, 2:])
corr_matrix = employee_df[['age', 'salary', 'experience_years', 'performance_score']].corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0, ax=ax8)
ax8.set_title('员工数据相关性', fontsize=14)
plt.suptitle('综合数据分析仪表板', fontsize=16, y=0.98)
plt.show()#4. 交互式可视化
#4.1 使用 Plotly 创建交互式图表
print("\n=== 交互式可视化示例 ===")
try:
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
print("创建交互式图表...")
# 1. 交互式散点图
fig_scatter = px.scatter(
employee_df,
x='age',
y='salary',
color='department',
size='performance_score',
hover_data=['experience_years'],
title='员工年龄-薪资交互式散点图'
)
fig_scatter.show()
# 2. 交互式时间序列图
daily_sales_df = sales_df.groupby('date')['sales_amount'].sum().reset_index()
fig_line = px.line(
daily_sales_df,
x='date',
y='sales_amount',
title='每日销售额交互式趋势图'
)
fig_line.show()
# 3. 交互式柱状图
product_sales_df = sales_df.groupby('product')['sales_amount'].sum().reset_index()
fig_bar = px.bar(
product_sales_df,
x='product',
y='sales_amount',
title='产品销售额交互式柱状图'
)
fig_bar.show()
# 4. 交互式热力图
fig_heatmap = px.imshow(
corr_matrix,
text_auto=True,
aspect="auto",
title='相关性交互式热力图'
)
fig_heatmap.show()
except ImportError:
print("Plotly 未安装,跳过交互式可视化演示")
print("可以使用 'pip install plotly' 安装 Plotly")#4.2 动态图表更新
# 创建动态更新的图表示例
def create_animated_chart():
"""创建动画图表"""
try:
import plotly.express as px
# 创建月度数据
monthly_data = []
for month in range(1, 13):
month_data = sales_df[sales_df['month'] == month]
for product in month_data['product'].unique():
product_data = month_data[month_data['product'] == product]
monthly_data.append({
'month': month,
'product': product,
'total_sales': product_data['sales_amount'].sum(),
'avg_satisfaction': product_data['customer_satisfaction'].mean()
})
monthly_df = pd.DataFrame(monthly_data)
# 创建动画散点图
fig = px.scatter(
monthly_df,
x='total_sales',
y='avg_satisfaction',
animation_frame='month',
color='product',
size='total_sales',
title='月度产品销售额与客户满意度动画图'
)
fig.show()
except ImportError:
print("需要安装 Plotly 才能创建动画图表")
# create_animated_chart()#5. 专业图表定制
#5.1 图表样式定制
print("\n=== 图表样式定制 ===")
# 创建专业的图表样式
def create_professional_chart():
"""创建专业样式的图表"""
# 设置专业配色方案
colors = ['#2E86AB', '#A23B72', '#F18F01', '#C73E1D', '#592E83']
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
# 1. 专业柱状图
product_sales = sales_df.groupby('product')['sales_amount'].sum().sort_values(ascending=False)
bars = axes[0,0].bar(product_sales.index, product_sales.values, color=colors)
axes[0,0].set_title('产品销售额排名', fontsize=16, fontweight='bold', pad=20)
axes[0,0].set_ylabel('销售额 (万元)', fontsize=12)
axes[0,0].tick_params(axis='x', rotation=45)
# 添加数值标签
for bar in bars:
height = bar.get_height()
axes[0,0].text(bar.get_x() + bar.get_width()/2., height,
f'{height:.0f}',
ha='center', va='bottom', fontsize=10)
# 美化网格
axes[0,0].grid(True, alpha=0.3, linestyle='--')
axes[0,0].set_axisbelow(True)
# 2. 专业线图
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
axes[0,1].plot(monthly_sales.index, monthly_sales.values,
marker='o', linewidth=3, markersize=8, color=colors[0])
axes[0,1].fill_between(monthly_sales.index, monthly_sales.values, alpha=0.3, color=colors[0])
axes[0,1].set_title('月度销售趋势', fontsize=16, fontweight='bold', pad=20)
axes[0,1].set_ylabel('销售额 (万元)', fontsize=12)
axes[0,1].set_xlabel('月份', fontsize=12)
axes[0,1].grid(True, alpha=0.3, linestyle='--')
axes[0,1].set_axisbelow(True)
# 3. 专业散点图
for i, dept in enumerate(employee_df['department'].unique()):
dept_data = employee_df[employee_df['department'] == dept]
axes[1,0].scatter(dept_data['age'], dept_data['salary'],
label=dept, alpha=0.7, s=60, color=colors[i % len(colors)])
axes[1,0].set_title('年龄与薪资关系分析', fontsize=16, fontweight='bold', pad=20)
axes[1,0].set_xlabel('年龄', fontsize=12)
axes[1,0].set_ylabel('薪资 (元)', fontsize=12)
axes[1,0].legend(frameon=True, fancybox=True, shadow=True)
axes[1,0].grid(True, alpha=0.3, linestyle='--')
axes[1,0].set_axisbelow(True)
# 4. 专业饼图
region_sales = sales_df.groupby('region')['sales_amount'].sum()
wedges, texts, autotexts = axes[1,1].pie(region_sales.values,
labels=region_sales.index,
autopct='%1.1f%%',
colors=colors,
explode=(0.05, 0.05, 0.05, 0.05),
shadow=True,
startangle=90)
axes[1,1].set_title('区域销售额分布', fontsize=16, fontweight='bold', pad=20)
# 美化饼图文字
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
# 调整整体布局
plt.tight_layout()
plt.suptitle('销售数据分析报告', fontsize=20, fontweight='bold', y=0.98)
plt.show()
create_professional_chart()#5.2 主题和配色方案
print("\n=== 主题和配色方案 ===")
# 定义多种配色方案
color_schemes = {
'business': ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd'],
'pastel': ['#AEC7E8', '#FFBB78', '#98DF8A', '#FF9896', '#C5B0D5'],
'dark': ['#2E3440', '#3B4252', '#434C5E', '#4C566A', '#5E81AC'],
'vibrant': ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
}
def apply_theme(theme_name='business'):
"""应用指定主题"""
colors = color_schemes.get(theme_name, color_schemes['business'])
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 应用主题色彩
product_sales = sales_df.groupby('product')['sales_amount'].sum()
product_sales.plot(kind='bar', ax=axes[0,0], color=colors)
axes[0,0].set_title(f'{theme_name.title()} 主题 - 产品销售额')
region_sales = sales_df.groupby('region')['sales_amount'].sum()
region_sales.plot(kind='pie', ax=axes[0,1], colors=colors, autopct='%1.1f%%')
axes[0,1].set_title(f'{theme_name.title()} 主题 - 区域分布')
# 多线图
for i, product in enumerate(sales_df['product'].unique()):
product_data = sales_df[sales_df['product'] == product]
monthly_data = product_data.groupby('month')['sales_amount'].sum()
axes[1,0].plot(monthly_data.index, monthly_data.values,
marker='o', label=product, color=colors[i % len(colors)])
axes[1,0].set_title(f'{theme_name.title()} 主题 - 月度趋势')
axes[1,0].legend()
axes[1,0].grid(True, alpha=0.3)
# 散点图
for i, dept in enumerate(employee_df['department'].unique()):
dept_data = employee_df[employee_df['department'] == dept]
axes[1,1].scatter(dept_data['age'], dept_data['salary'],
label=dept, alpha=0.7, color=colors[i % len(colors)])
axes[1,1].set_title(f'{theme_name.title()} 主题 - 年龄薪资')
axes[1,1].legend()
axes[1,1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 展示不同主题
for theme in ['business', 'pastel', 'vibrant']:
print(f"\n应用 {theme} 主题:")
apply_theme(theme)#6. 数据故事讲述
#6.1 创建数据故事
print("\n=== 数据故事讲述 ===")
def create_data_story():
"""创建完整的数据故事"""
fig = plt.figure(figsize=(20, 24))
gs = GridSpec(6, 3, figure=fig, hspace=0.4, wspace=0.3)
# 标题页
title_ax = fig.add_subplot(gs[0, :])
title_ax.text(0.5, 0.5, '2022年度销售业绩分析报告',
ha='center', va='center', fontsize=24, fontweight='bold')
title_ax.text(0.5, 0.3, '基于Pandas数据分析的深度洞察',
ha='center', va='center', fontsize=16, style='italic')
title_ax.axis('off')
# 第一部分:总体概况
ax1 = fig.add_subplot(gs[1, 0])
total_sales = sales_df['sales_amount'].sum()
total_orders = len(sales_df)
avg_order_value = total_sales / total_orders
metrics = ['总销售额', '订单数量', '平均订单价值']
values = [total_sales/10000, total_orders, avg_order_value]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
bars = ax1.bar(metrics, values, color=colors)
ax1.set_title('2022年度业绩概览', fontsize=14, fontweight='bold')
ax1.set_ylabel('数值')
# 添加数值标签
for i, (bar, value) in enumerate(zip(bars, values)):
if i == 0:
label = f'{value:.1f}万'
elif i == 1:
label = f'{value:.0f}'
else:
label = f'{value:.0f}元'
ax1.text(bar.get_x() + bar.get_width()/2., bar.get_height(),
label, ha='center', va='bottom', fontweight='bold')
# 第二部分:时间趋势
ax2 = fig.add_subplot(gs[1, 1:])
daily_sales = sales_df.groupby('date')['sales_amount'].sum()
monthly_avg = daily_sales.resample('M').mean()
ax2.plot(daily_sales.index, daily_sales.values, alpha=0.3, color='lightblue', label='每日销售额')
ax2.plot(monthly_avg.index, monthly_avg.values, linewidth=3, color='darkblue',
marker='o', markersize=8, label='月度平均')
ax2.set_title('销售额时间趋势分析', fontsize=14, fontweight='bold')
ax2.set_ylabel('销售额')
ax2.legend()
ax2.grid(True, alpha=0.3)
# 第三部分:产品分析
ax3 = fig.add_subplot(gs[2, 0])
product_sales = sales_df.groupby('product')['sales_amount'].sum().sort_values(ascending=True)
product_sales.plot(kind='barh', ax=ax3, color='lightcoral')
ax3.set_title('产品销售额排名', fontsize=14, fontweight='bold')
ax3.set_xlabel('销售额')
# 第四部分:区域分析
ax4 = fig.add_subplot(gs[2, 1])
region_sales = sales_df.groupby('region')['sales_amount'].sum()
wedges, texts, autotexts = ax4.pie(region_sales.values, labels=region_sales.index,
autopct='%1.1f%%', startangle=90,
colors=['#FF9999', '#66B2FF', '#99FF99', '#FFCC99'])
ax4.set_title('区域销售分布', fontsize=14, fontweight='bold')
# 第五部分:客户满意度分析
ax5 = fig.add_subplot(gs[2, 2])
satisfaction_by_product = sales_df.groupby('product')['customer_satisfaction'].mean()
satisfaction_by_product.plot(kind='bar', ax=ax5, color='lightgreen')
ax5.set_title('产品客户满意度', fontsize=14, fontweight='bold')
ax5.set_ylabel('满意度评分')
ax5.tick_params(axis='x', rotation=45)
# 第六部分:相关性分析
ax6 = fig.add_subplot(gs[3, :])
# 创建相关性数据
correlation_data = sales_df[['sales_amount', 'quantity', 'customer_satisfaction']].corr()
im = ax6.imshow(correlation_data, cmap='RdBu', aspect='auto')
ax6.set_xticks(range(len(correlation_data.columns)))
ax6.set_yticks(range(len(correlation_data.columns)))
ax6.set_xticklabels(correlation_data.columns)
ax6.set_yticklabels(correlation_data.columns)
ax6.set_title('销售指标相关性分析', fontsize=14, fontweight='bold')
# 添加相关系数标注
for i in range(len(correlation_data.columns)):
for j in range(len(correlation_data.columns)):
ax6.text(j, i, f'{correlation_data.iloc[i, j]:.2f}',
ha='center', va='center', fontweight='bold')
plt.colorbar(im, ax=ax6, shrink=0.8)
# 第七部分:关键洞察
insights_ax = fig.add_subplot(gs[4, :])
insights_text = """
关键洞察与建议:
1. 销售趋势:全年销售呈现稳定增长态势,第四季度表现尤为突出
2. 产品表现:产品A和产品B占据主要市场份额,建议加大投入
3. 区域分布:各区域发展相对均衡,可考虑差异化策略
4. 客户满意度:整体满意度良好,但仍有提升空间
5. 相关性发现:销售额与数量正相关,客户满意度影响复购率
建议行动:
• 加强产品A和B的市场推广
• 提升客户服务质量,提高满意度
• 优化供应链,确保产品质量稳定
• 建立客户反馈机制,持续改进
"""
insights_ax.text(0.05, 0.95, insights_text, transform=insights_ax.transAxes,
fontsize=12, verticalalignment='top', fontfamily='monospace',
bbox=dict(boxstyle='round', facecolor='lightgray', alpha=0.8))
insights_ax.axis('off')
# 第八部分:数据来源和方法
method_ax = fig.add_subplot(gs[5, :])
method_text = """
数据来源与分析方法:
• 数据来源:2022年1月1日至12月31日销售系统数据
• 样本量:365个数据点,涵盖5个产品线和4个销售区域
• 分析工具:Python Pandas + Matplotlib + Seaborn
• 统计方法:描述性统计、相关性分析、趋势分析
• 可视化:多维度图表展示,支持交互式探索
"""
method_ax.text(0.05, 0.5, method_text, transform=method_ax.transAxes,
fontsize=10, verticalalignment='center', fontfamily='monospace',
bbox=dict(boxstyle='round', facecolor='lightyellow', alpha=0.8))
method_ax.axis('off')
plt.suptitle('数据驱动的业务洞察报告', fontsize=20, fontweight='bold', y=0.98)
plt.show()
create_data_story()#7. 导出和保存图表
#7.1 多格式导出
print("\n=== 图表导出示例 ===")
import os
# 创建输出目录
output_dir = 'charts_output'
if not os.path.exists(output_dir):
os.makedirs(output_dir)
def export_charts():
"""导出各种格式的图表"""
# 创建示例图表
fig, ax = plt.subplots(figsize=(10, 6))
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
monthly_sales.plot(kind='bar', ax=ax, color='skyblue')
ax.set_title('月度销售额分析', fontsize=16, fontweight='bold')
ax.set_ylabel('销售额')
ax.set_xlabel('月份')
ax.grid(True, alpha=0.3)
# 导出为不同格式
formats = ['png', 'pdf', 'svg', 'jpg']
for fmt in formats:
filename = f'{output_dir}/monthly_sales.{fmt}'
plt.savefig(filename, format=fmt, dpi=300, bbox_inches='tight')
print(f"图表已保存为: {filename}")
plt.show()
# 批量导出多个图表
chart_configs = [
{
'data': sales_df.groupby('product')['sales_amount'].sum(),
'kind': 'bar',
'title': '产品销售额对比',
'filename': 'product_sales'
},
{
'data': sales_df.groupby('region')['sales_amount'].sum(),
'kind': 'pie',
'title': '区域销售分布',
'filename': 'region_distribution'
}
]
for config in chart_configs:
fig, ax = plt.subplots(figsize=(10, 6))
if config['kind'] == 'bar':
config['data'].plot(kind='bar', ax=ax, color='lightcoral')
elif config['kind'] == 'pie':
config['data'].plot(kind='pie', ax=ax, autopct='%1.1f%%')
ax.set_ylabel('')
ax.set_title(config['title'], fontsize=16, fontweight='bold')
# 保存为PNG格式
filename = f"{output_dir}/{config['filename']}.png"
plt.savefig(filename, dpi=300, bbox_inches='tight')
print(f"图表已保存为: {filename}")
plt.close() # 关闭图表以释放内存
export_charts()
# 创建图表模板
def create_chart_template(data, chart_type, title, filename):
"""创建标准化的图表模板"""
fig, ax = plt.subplots(figsize=(12, 8))
# 应用统一样式
plt.style.use('seaborn-v0_8')
if chart_type == 'line':
data.plot(kind='line', ax=ax, linewidth=3, marker='o', markersize=8)
elif chart_type == 'bar':
data.plot(kind='bar', ax=ax, color='#2E86AB')
elif chart_type == 'pie':
data.plot(kind='pie', ax=ax, autopct='%1.1f%%', startangle=90)
ax.set_ylabel('')
ax.set_title(title, fontsize=18, fontweight='bold', pad=20)
ax.grid(True, alpha=0.3)
# 添加水印
fig.text(0.99, 0.01, 'Generated by Pandas Analytics',
ha='right', va='bottom', alpha=0.5, fontsize=8)
# 保存图表
plt.savefig(f'{output_dir}/{filename}.png', dpi=300, bbox_inches='tight')
plt.show()
return fig
print("\n使用图表模板:")
create_chart_template(
sales_df.groupby('month')['sales_amount'].sum(),
'line',
'月度销售趋势分析',
'monthly_trend_template'
)#8. 性能优化和最佳实践
#8.1 大数据可视化优化
print("\n=== 大数据可视化优化 ===")
# 创建大数据集
large_sales_data = pd.concat([sales_df] * 100, ignore_index=True)
print(f"大数据集大小: {large_sales_data.shape}")
def optimize_large_data_viz(df, sample_size=1000):
"""优化大数据可视化"""
import time
# 方法1: 数据采样
start_time = time.time()
sampled_df = df.sample(n=min(sample_size, len(df)))
sampled_df.plot.scatter(x='quantity', y='sales_amount', alpha=0.6, figsize=(10, 6))
plt.title(f'采样可视化 (样本量: {len(sampled_df)})')
plt.show()
sampling_time = time.time() - start_time
# 方法2: 数据聚合
start_time = time.time()
aggregated_df = df.groupby(['product', 'region']).agg({
'sales_amount': 'mean',
'quantity': 'mean',
'customer_satisfaction': 'mean'
}).reset_index()
aggregated_df.plot.scatter(x='quantity', y='sales_amount',
s=aggregated_df['customer_satisfaction']*20,
c='customer_satisfaction', colormap='viridis',
figsize=(10, 6))
plt.title(f'聚合可视化 (数据点: {len(aggregated_df)})')
plt.show()
aggregation_time = time.time() - start_time
print(f"采样方法耗时: {sampling_time:.3f} 秒")
print(f"聚合方法耗时: {aggregation_time:.3f} 秒")
return sampled_df, aggregated_df
sampled_data, aggregated_data = optimize_large_data_viz(large_sales_data)#8.2 内存优化技巧
print("\n=== 内存优化技巧 ===")
def memory_efficient_plotting():
"""内存高效的绘图方法"""
# 1. 使用生成器避免创建大量中间变量
def plot_generator(df, group_col):
for group_name, group_data in df.groupby(group_col):
yield group_name, group_data
# 2. 分批处理大数据
chunk_size = 1000
fig, ax = plt.subplots(figsize=(12, 8))
colors = plt.cm.Set3(np.linspace(0, 1, len(sales_df['product'].unique())))
for i, (product, product_data) in enumerate(plot_generator(sales_df, 'product')):
# 只绘制前100个点以节省内存
sample_data = product_data.head(100)
ax.scatter(sample_data['quantity'], sample_data['sales_amount'],
label=product, alpha=0.6, color=colors[i])
ax.set_title('内存优化散点图')
ax.set_xlabel('销量')
ax.set_ylabel('销售额')
ax.legend()
plt.show()
# 3. 及时清理图表对象
plt.close('all') # 关闭所有图表
# 4. 使用上下文管理器
with plt.style.context('seaborn-v0_8'):
fig, ax = plt.subplots(figsize=(10, 6))
sales_df.groupby('month')['sales_amount'].sum().plot(ax=ax)
ax.set_title('使用上下文管理器的图表')
plt.show()
# 样式会自动恢复
memory_efficient_plotting()#9. 可视化最佳实践
#9.1 图表选择指南
print("\n=== 图表选择指南 ===")
def chart_selection_guide()#9.2 可视化设计原则
print("\n=== 可视化设计原则 ===")
def visualization_principles():
"""可视化设计原则示例"""
principles = {
"简洁性原则": "避免不必要的装饰,突出数据本身",
"准确性原则": "确保图表准确反映数据,避免误导",
"一致性原则": "保持颜色、字体、样式的一致性",
"可读性原则": "确保标签、图例清晰可读",
"目的性原则": "根据分析目的选择合适的图表类型"
}
print("可视化设计五大原则:")
for principle, description in principles.items():
print(f"• {principle}: {description}")
# 好的设计示例
fig, axes = plt.subplots(1, 2, figsize=(15, 6))
# 好的设计
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
axes[0].plot(monthly_sales.index, monthly_sales.values,
linewidth=2, marker='o', markersize=6, color='#2E86AB')
axes[0].set_title('月度销售趋势', fontsize=14, fontweight='bold', pad=15)
axes[0].set_xlabel('月份', fontsize=12)
axes[0].set_ylabel('销售额 (万元)', fontsize=12)
axes[0].grid(True, alpha=0.3, linestyle='--')
axes[0].set_axisbelow(True)
# 添加数据标签
for i, v in enumerate(monthly_sales.values):
if i % 2 == 0: # 只显示部分标签避免拥挤
axes[0].annotate(f'{v:.0f}', (monthly_sales.index[i], v),
textcoords="offset points", xytext=(0,10), ha='center')
axes[0].text(0.02, 0.98, '✓ 好的设计', transform=axes[0].transAxes,
fontsize=12, fontweight='bold', color='green',
verticalalignment='top', bbox=dict(boxstyle='round', facecolor='lightgreen', alpha=0.3))
# 不好的设计示例
axes[1].plot(monthly_sales.index, monthly_sales.values,
linewidth=5, marker='s', markersize=12, color='red')
axes[1].set_title('MONTHLY SALES TREND!!!', fontsize=16, color='red')
axes[1].set_facecolor('yellow')
axes[1].grid(True, alpha=0.8, linewidth=2, color='blue')
# 添加过多装饰
for i, v in enumerate(monthly_sales.values):
axes[1].annotate(f'{v:.2f}万元', (monthly_sales.index[i], v),
textcoords="offset points", xytext=(0,15), ha='center',
fontsize=8, rotation=45)
axes[1].text(0.02, 0.98, '✗ 不好的设计', transform=axes[1].transAxes,
fontsize=12, fontweight='bold', color='red',
verticalalignment='top', bbox=dict(boxstyle='round', facecolor='lightcoral', alpha=0.3))
plt.tight_layout()
plt.show()
visualization_principles()#9.3 常见错误和解决方案
print("\n=== 常见可视化错误 ===")
def common_mistakes_and_solutions():
"""常见可视化错误及解决方案"""
mistakes = {
"错误1: 使用不合适的图表类型": {
"问题": "用饼图显示时间序列数据",
"解决方案": "时间序列数据应使用线图"
},
"错误2: 颜色使用不当": {
"问题": "使用过多颜色或颜色对比度不够",
"解决方案": "使用色盲友好的配色方案"
},
"错误3: 坐标轴问题": {
"问题": "Y轴不从0开始,夸大差异",
"解决方案": "合理设置坐标轴范围"
},
"错误4: 信息过载": {
"问题": "在一个图表中显示过多信息",
"解决方案": "分解为多个简单图表"
},
"错误5: 缺少标签和说明": {
"问题": "图表缺少标题、轴标签或图例",
"解决方案": "添加完整的标签和说明"
}
}
print("常见可视化错误及解决方案:")
for mistake, details in mistakes.items():
print(f"\n{mistake}")
print(f" 问题: {details['问题']}")
print(f" 解决方案: {details['解决方案']}")
# 错误示例对比
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# 错误1: 坐标轴不从0开始
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
axes[0,0].plot(monthly_sales.index, monthly_sales.values, marker='o')
axes[0,0].set_ylim(monthly_sales.min() * 0.9, monthly_sales.max() * 1.1)
axes[0,0].set_title('错误:Y轴不从0开始')
axes[0,0].text(0.02, 0.98, '✗ 夸大了差异', transform=axes[0,0].transAxes,
fontsize=10, color='red', verticalalignment='top')
# 正确1: 坐标轴从0开始
axes[0,1].plot(monthly_sales.index, monthly_sales.values, marker='o')
axes[0,1].set_ylim(0, monthly_sales.max() * 1.1)
axes[0,1].set_title('正确:Y轴从0开始')
axes[0,1].text(0.02, 0.98, '✓ 真实反映差异', transform=axes[0,1].transAxes,
fontsize=10, color='green', verticalalignment='top')
# 错误2: 颜色过多
product_sales = sales_df.groupby('product')['sales_amount'].sum()
colors_bad = ['red', 'blue', 'yellow', 'purple', 'orange']
product_sales.plot(kind='bar', ax=axes[1,0], color=colors_bad)
axes[1,0].set_title('错误:颜色过多且刺眼')
axes[1,0].tick_params(axis='x', rotation=45)
# 正确2: 统一配色
colors_good = ['#2E86AB'] * len(product_sales)
product_sales.plot(kind='bar', ax=axes[1,1], color=colors_good)
axes[1,1].set_title('正确:统一配色方案')
axes[1,1].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
common_mistakes_and_solutions()#10. 实际应用案例
#10.1 商业报告可视化
print("\n=== 商业报告可视化案例 ===")
def create_business_report():
"""创建完整的商业报告"""
# 设置报告样式
plt.style.use('seaborn-v0_8-whitegrid')
fig = plt.figure(figsize=(16, 20))
gs = GridSpec(5, 2, figure=fig, hspace=0.4, wspace=0.3)
# 报告标题
title_ax = fig.add_subplot(gs[0, :])
title_ax.text(0.5, 0.7, '2022年度业务分析报告',
ha='center', va='center', fontsize=24, fontweight='bold')
title_ax.text(0.5, 0.3, f'报告生成时间: {datetime.now().strftime("%Y-%m-%d %H:%M")}',
ha='center', va='center', fontsize=12, style='italic')
title_ax.axis('off')
# 1. 销售趋势分析
ax1 = fig.add_subplot(gs[1, :])
daily_sales = sales_df.groupby('date')['sales_amount'].sum()
monthly_avg = daily_sales.resample('M').mean()
ax1.plot(daily_sales.index, daily_sales.values, alpha=0.3, color='lightblue', label='每日销售')
ax1.plot(monthly_avg.index, monthly_avg.values, linewidth=3, color='darkblue',
marker='o', markersize=8, label='月度平均')
ax1.fill_between(monthly_avg.index, monthly_avg.values, alpha=0.2, color='darkblue')
ax1.set_title('销售趋势分析', fontsize=16, fontweight='bold', pad=20)
ax1.set_ylabel('销售额 (元)')
ax1.legend()
ax1.grid(True, alpha=0.3)
# 2. 产品表现对比
ax2 = fig.add_subplot(gs[2, 0])
product_metrics = sales_df.groupby('product').agg({
'sales_amount': 'sum',
'quantity': 'sum',
'customer_satisfaction': 'mean'
})
bars = ax2.bar(product_metrics.index, product_metrics['sales_amount'],
color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'])
ax2.set_title('产品销售额对比', fontsize=14, fontweight='bold')
ax2.set_ylabel('销售额 (元)')
ax2.tick_params(axis='x', rotation=45)
# 添加数值标签
for bar in bars:
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width()/2., height,
f'{height:.0f}', ha='center', va='bottom')
# 3. 区域分布
ax3 = fig.add_subplot(gs[2, 1])
region_sales = sales_df.groupby('region')['sales_amount'].sum()
wedges, texts, autotexts = ax3.pie(region_sales.values, labels=region_sales.index,
autopct='%1.1f%%', startangle=90,
colors=['#FF9999', '#66B2FF', '#99FF99', '#FFCC99'])
ax3.set_title('区域销售分布', fontsize=14, fontweight='bold')
# 4. 客户满意度分析
ax4 = fig.add_subplot(gs[3, 0])
satisfaction_by_product = sales_df.groupby('product')['customer_satisfaction'].mean()
bars = ax4.barh(satisfaction_by_product.index, satisfaction_by_product.values,
color='lightgreen')
ax4.set_title('产品客户满意度', fontsize=14, fontweight='bold')
ax4.set_xlabel('满意度评分')
# 添加满意度等级线
ax4.axvline(x=4.0, color='orange', linestyle='--', alpha=0.7, label='良好线')
ax4.axvline(x=4.5, color='green', linestyle='--', alpha=0.7, label='优秀线')
ax4.legend()
# 5. 关键指标总结
ax5 = fig.add_subplot(gs[3, 1])
# 计算关键指标
total_revenue = sales_df['sales_amount'].sum()
total_orders = len(sales_df)
avg_order_value = total_revenue / total_orders
best_product = sales_df.groupby('product')['sales_amount'].sum().idxmax()
best_region = sales_df.groupby('region')['sales_amount'].sum().idxmax()
metrics_text = f"""
关键业务指标
总收入: {total_revenue:,.0f} 元
订单总数: {total_orders:,} 笔
平均订单价值: {avg_order_value:.0f} 元
最佳产品: {best_product}
最佳区域: {best_region}
平均客户满意度: {sales_df['customer_satisfaction'].mean():.2f}/5.0
"""
ax5.text(0.1, 0.9, metrics_text, transform=ax5.transAxes,
fontsize=12, verticalalignment='top', fontfamily='monospace',
bbox=dict(boxstyle='round', facecolor='lightblue', alpha=0.3))
ax5.axis('off')
# 6. 建议和结论
ax6 = fig.add_subplot(gs[4, :])
recommendations = """
业务建议与行动计划:
1. 产品策略: 加大对表现优异产品的投入,考虑扩大生产规模
2. 区域发展: 在表现较弱的区域加强市场推广和渠道建设
3. 客户体验: 持续提升客户满意度,建立客户反馈机制
4. 销售优化: 分析销售波动原因,制定更稳定的销售策略
5. 数据驱动: 建立定期数据分析机制,及时调整业务策略
下一步行动:
• 深入分析客户细分和购买行为
• 建立预测模型,提前识别市场趋势
• 优化供应链,提高运营效率
"""
ax6.text(0.05, 0.95, recommendations, transform=ax6.transAxes,
fontsize=11, verticalalignment='top',
bbox=dict(boxstyle='round', facecolor='lightyellow', alpha=0.5))
ax6.axis('off')
plt.suptitle('数据驱动的业务洞察', fontsize=18, fontweight='bold', y=0.98)
plt.show()
create_business_report()#本章小结
本章全面介绍了 Pandas 的数据可视化功能:
#核心内容回顾
- 基础图表类型:线图、柱状图、散点图、直方图等
- 高级图表:箱线图、热力图、多子图布局
- 交互式可视化:使用 Plotly 创建动态图表
- 专业定制:样式设计、主题配色、图表模板
- 数据故事:创建完整的分析报告和业务洞察
#关键技能
- 根据数据类型选择合适的图表
- 使用 Pandas 内置绘图功能快速可视化
- 结合 matplotlib 和 seaborn 创建专业图表
- 优化大数据可视化性能
- 遵循可视化设计原则
#最佳实践
- 保持图表简洁明了
- 选择合适的颜色和样式
- 添加必要的标签和说明
- 考虑目标受众的需求
- 用数据讲述有意义的故事
#实际应用
- 业务报告和仪表板
- 数据探索和分析
- 学术研究和论文
- 产品分析和用户洞察
- 市场研究和竞争分析
掌握这些可视化技能,能够帮助你:
- 快速发现数据中的模式和趋势
- 有效传达分析结果和洞察
- 制作专业的数据报告
- 支持数据驱动的决策制定
#练习题
- 创建一个包含多种图表类型的综合仪表板
- 设计一个交互式的销售分析工具
- 制作一份完整的数据分析报告
- 优化大数据集的可视化性能
- 开发一套标准化的图表模板
下一章我们将学习 Pandas 的高级功能,探索更复杂的数据处理和分析技术。: """图表选择指南和示例"""
guide = {
"比较数值": {
"适用图表": ["柱状图", "条形图", "雷达图"],
"示例": "各产品销售额对比"
},
"显示趋势": {
"适用图表": ["线图", "面积图"],
"示例": "月度销售趋势"
},
"显示分布": {
"适用图表": ["直方图", "箱线图", "小提琴图"],
"示例": "员工薪资分布"
},
"显示关系": {
"适用图表": ["散点图", "气泡图", "热力图"],
"示例": "年龄与薪资关系"
},
"显示构成": {
"适用图表": ["饼图", "堆叠柱状图", "树状图"],
"示例": "区域销售占比"
}
}
print("图表选择指南:")
for purpose, info in guide.items():
print(f"\n{purpose}:")
print(f" 推荐图表: {', '.join(info['适用图表'])}")
print(f" 应用示例: {info['示例']}")
# 创建对比示例
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
# 1. 比较 - 柱状图
product_sales = sales_df.groupby('product')['sales_amount'].sum()
product_sales.plot(kind='bar', ax=axes[0,0], color='skyblue')
axes[0,0].set_title('比较:产品销售额')
axes[0,0].tick_params(axis='x', rotation=45)
# 2. 趋势 - 线图
monthly_sales = sales_df.groupby('month')['sales_amount'].sum()
monthly_sales.plot(kind='line', ax=axes[0,1], marker='o', color='red')
axes[0,1].set_title('趋势:月度销售额')
axes[0,1].grid(True, alpha=0.3)
# 3. 分布 - 直方图
employee_df['salary'].plot.hist(bins=30, ax=axes[0,2], alpha=0.7, color='green')
axes[0,2].set_title('分布:薪资分布')
axes[0,2].set_xlabel('薪资')
# 4. 关系 - 散点图
employee_df.plot.scatter(x='age', y='salary', ax=axes[1,0], alpha=0.6, color='purple')
axes[1,0].set_title('关系:年龄与薪资')
# 5. 构成 - 饼图
region_sales = sales_df.groupby('region')['sales_amount'].sum()
region_sales.plot(kind='pie', ax=axes[1,1], autopct='%1.1f%%')
axes[1,1].set_title('构成:区域销售占比')
axes[1,1].set_ylabel('')
# 6. 相关性 - 热力图
corr_data = employee_df[['age', 'salary', 'experience_years', 'performance_score']].corr()
im = axes[1,2].imshow(corr_data, cmap='coolwarm', aspect='auto')
axes[1,2].set_title('相关性:员工数据热力图')
axes[1,2].set_xticks(range(len(corr_data.columns)))
axes[1,2].set_yticks(range(len(corr_data.columns)))
axes[1,2].set_xticklabels(corr_data.columns, rotation=45)
axes[1,2].set_yticklabels(corr_data.columns)
plt.tight_layout()
plt.show()chart_selection_guide()