Python数据可视化之散点图(实战篇---从入门到精通)
·
1. 为什么选择散点图?
散点图是数据分析中最基础也最实用的可视化工具之一。我第一次接触散点图是在分析电商用户行为时,当时需要找出用户年龄和消费金额之间的关系。散点图就像是一个放大镜,能让你一眼看出数据中隐藏的模式。
举个例子,假设你手上有1000条用户数据,包含年龄和月消费金额。用Excel表格看这些数字,你可能会头晕眼花。但把这些数据点画在散点图上,立刻就能发现:25-35岁的用户消费最活跃,形成明显的密集区域;而50岁以上用户的点则分散在较低位置。这种直观的洞察,是表格数据永远给不了的。
2. 环境准备与数据生成
2.1 三件套安装指南
工欲善其事必先利其器,我们先搞定三个必备工具:
- NumPy:数据生成的瑞士军刀
- Pandas:数据处理的全能选手
- Matplotlib:可视化界的扛把子
安装命令很简单:
pip install numpy pandas matplotlib
如果你遇到安装慢的问题,可以试试国内镜像源:
pip install numpy pandas matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
2.2 创建模拟数据集
让我们生成一份更接近真实场景的数据。假设我们要分析某电商平台的用户数据:
import numpy as np
import pandas as pd
# 设置随机种子保证结果可复现
np.random.seed(42)
# 生成1000个18-70岁的用户年龄
ages = np.random.randint(18, 70, size=1000)
# 生成消费金额:年龄越大消费越低,但存在随机波动
consumption = 3000 - ages * 20 + np.random.normal(0, 500, size=1000)
# 创建DataFrame
df = pd.DataFrame({'Age': ages, 'Consumption': consumption})
# 查看前5行
print(df.head())
这份数据的特点是:
- 年龄范围:18-70岁
- 消费金额与年龄呈负相关
- 加入了随机噪声模拟真实情况
3. 基础散点图绘制
3.1 你的第一个散点图
让我们用最简单的代码画出散点图:
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.scatter(df['Age'], df['Consumption'])
plt.title('Age vs Consumption')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.grid(True)
plt.show()
这段代码虽然简单,但已经包含了散点图的核心要素:
figsize:控制图形大小,10×6是比较适合报告的尺寸scatter:核心绘图函数title/xlabel/ylabel:让图表更易读grid:添加网格线方便观察数据分布
3.2 第一次优化:解决重叠问题
当数据点很多时,你会发现点都挤在一起。这时候可以:
- 调整点的大小(
s参数) - 设置透明度(
alpha参数) - 使用边缘色(
edgecolor)
改进后的代码:
plt.figure(figsize=(10, 6))
plt.scatter(df['Age'], df['Consumption'],
s=20, alpha=0.6, edgecolor='white')
plt.title('Age vs Consumption (Optimized)')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.grid(True, alpha=0.3)
plt.show()
4. 进阶技巧:添加分类维度
4.1 按性别分类着色
假设我们新增了性别数据:
# 随机生成性别数据
genders = np.random.choice(['Male', 'Female'], size=1000)
df['Gender'] = genders
现在可以用不同颜色区分性别:
colors = {'Male': 'blue', 'Female': 'red'}
plt.figure(figsize=(10, 6))
for gender in ['Male', 'Female']:
subset = df[df['Gender'] == gender]
plt.scatter(subset['Age'], subset['Consumption'],
color=colors[gender], label=gender,
s=20, alpha=0.6)
plt.title('Age vs Consumption by Gender')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
4.2 添加趋势线
要更清楚地看到年龄和消费的关系,可以添加趋势线:
from scipy.stats import linregress
# 计算线性回归
slope, intercept, r_value, p_value, std_err = linregress(df['Age'], df['Consumption'])
plt.figure(figsize=(10, 6))
plt.scatter(df['Age'], df['Consumption'], s=20, alpha=0.6)
plt.plot(df['Age'], intercept + slope * df['Age'],
'r', label=f'Y = {intercept:.1f} + {slope:.1f}X')
plt.title('Age vs Consumption with Trendline')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
5. 专业级美化技巧
5.1 使用Seaborn风格
Matplotlib的默认样式比较简陋,可以改用Seaborn风格:
import seaborn as sns
sns.set_style("whitegrid")
plt.figure(figsize=(10, 6))
sns.scatterplot(data=df, x='Age', y='Consumption',
hue='Gender', palette=['blue', 'red'],
alpha=0.6, s=50)
plt.title('Professional Style with Seaborn')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.show()
5.2 添加边际分布图
想要同时看到单变量分布?试试边际分布图:
sns.set_style("whitegrid")
g = sns.JointGrid(data=df, x='Age', y='Consumption', height=8)
g.plot_joint(sns.scatterplot, hue=df['Gender'],
palette=['blue', 'red'], alpha=0.6)
g.plot_marginals(sns.histplot, kde=True)
plt.suptitle('Age vs Consumption with Marginal Distributions')
plt.tight_layout()
plt.show()
6. 实战案例:用户分群分析
6.1 识别高价值用户
假设我们定义:
- 高价值用户:消费 > 2500元
- 普通用户:消费 ≤ 2500元
df['User_Type'] = np.where(df['Consumption'] > 2500, 'High Value', 'Normal')
plt.figure(figsize=(10, 6))
for user_type in ['High Value', 'Normal']:
subset = df[df['User_Type'] == user_type]
plt.scatter(subset['Age'], subset['Consumption'],
label=user_type, alpha=0.6)
plt.axhline(y=2500, color='gray', linestyle='--', alpha=0.5)
plt.title('Identifying High Value Users')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
6.2 添加注释标记
想要突出显示特定数据点:
highlight = df.nlargest(3, 'Consumption')
plt.figure(figsize=(10, 6))
plt.scatter(df['Age'], df['Consumption'], alpha=0.4)
plt.scatter(highlight['Age'], highlight['Consumption'],
color='red', s=100, label='Top 3')
for i, row in highlight.iterrows():
plt.annotate(f"{row['Consumption']:.0f}元",
(row['Age'], row['Consumption']),
textcoords="offset points",
xytext=(0,10), ha='center')
plt.title('Highlighting Top Spenders')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
plt.legend()
plt.show()
7. 导出与分享
7.1 保存高清图片
plt.figure(figsize=(10, 6))
plt.scatter(df['Age'], df['Consumption'], alpha=0.6)
plt.title('Final Version for Report')
plt.xlabel('Age')
plt.ylabel('Monthly Consumption (CNY)')
# 保存为高清PNG
plt.savefig('age_consumption.png', dpi=300, bbox_inches='tight')
7.2 交互式探索
如果你需要交互功能,可以试试Plotly:
import plotly.express as px
fig = px.scatter(df, x='Age', y='Consumption',
color='Gender', hover_data=['User_Type'],
title='Interactive Scatter Plot')
fig.show()
更多推荐



所有评论(0)