# 勤奋的凯尔森同学10000h刻意练习Day4:Python数据可视化

所属专栏: 凯尔森的10000h刻意练习
Slogan: 一个36岁程序员, 研究生(学硕),前世界500强top20软件开发Java工程师,用10000小时深耕AI, 目标Top10 AI资深工程师, 全程日更记录。
tips: 文章末尾附有jupyter完整代码

数据可视化是数据分析中至关重要的一环,它能帮助我们直观地理解数据分布、趋势和关系。Python拥有丰富的数据可视化库,本部分将详细介绍其中最常用的四个:Matplotlib、Pandas内置绘图、Seaborn和Pyecharts。前三者主要用于静态图表,而Pyecharts则专注于交互式可视化。我们将从基础开始,逐步深入,并提供大量代码示例,所有示例均在JupyterLab中成功运行。

# 1.1 Matplotlib基础

Matplotlib是Python中最基础、最强大的绘图库,它提供了高度自定义的绘图接口。虽然语法相对底层,但它是许多高级绘图库(如Seaborn)的基础。

# 1.1.1 基本绘图流程

Matplotlib的基本使用流程通常包括:创建图形和坐标轴、调用绘图函数、设置标签和标题、显示或保存图像。

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

# 解决中文乱码
plt.rcParams['font.sans-serif'] = ['PingFang SC']  # 苹方,macOS默认中文字体
plt.rcParams['axes.unicode_minus'] = False

# 准备数据
# 在0到10之间均匀生成100个点(包含端点),作为横坐标x
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 创建图形和坐标轴
plt.figure(figsize=(8, 5))  # 可选,设置图形大小

# 绘图
plt.plot(x, y, label='sin(x)')

# 添加标签和标题
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.title('正弦函数曲线')
plt.legend()

# 显示图形
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 1.1.2 Figure和Axes

Matplotlib的核心概念是Figure(画布)和Axes(坐标系)。一个Figure可以包含多个Axes(子图)。通常我们使用 plt.subplots() 创建Figure和Axes对象,然后调用Axes的方法进行绘图。

fig, ax = plt.subplots(figsize=(8, 5))  # 创建一个画布和一个坐标系
ax.plot(x, y)
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.set_title('正弦函数')
ax.legend(['sin(x)'])
plt.show()
1
2
3
4
5
6
7

使用Axes对象的方法更加面向对象,适合复杂布局。

# 1.1.3 常用图表类型

折线图

x = np.arange(0, 10, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, label='sin')
plt.plot(x, y2, label='cos')
plt.legend()
plt.title('折线图示例')
plt.show()
1
2
3
4
5
6
7
8
9

散点图

np.random.seed(42)
x = np.random.randn(100)
y = 2 * x + np.random.randn(100) * 0.5

plt.scatter(x, y, alpha=0.6, c='red', edgecolors='black')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('散点图示例')
plt.show()
1
2
3
4
5
6
7
8
9

柱状图

categories = ['A', 'B', 'C', 'D']
values = [23, 45, 56, 78]

plt.bar(categories, values, color=['blue', 'orange', 'green', 'red'])
plt.xlabel('类别')
plt.ylabel('值')
plt.title('柱状图示例')
plt.show()
1
2
3
4
5
6
7
8

直方图

data = np.random.randn(1000)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.xlabel('值')
plt.ylabel('频数')
plt.title('直方图示例')
plt.show()
1
2
3
4
5
6

饼图

sizes = [25, 35, 20, 20]
labels = ['苹果', '香蕉', '橘子', '葡萄']
explode = (0.1, 0, 0, 0)  # 突出显示第一块

plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', startangle=90)
plt.axis('equal')  # 保证饼图是圆形
plt.title('饼图示例')
plt.show()
1
2
3
4
5
6
7
8

# 1.1.4 自定义样式

Matplotlib提供了丰富的自定义选项,包括颜色、线型、标记、标签、标题、图例等。

颜色和线型

x = np.linspace(0, 5, 50)
y1 = x
y2 = x**2
y3 = x**3

plt.plot(x, y1, color='red', linestyle='-', linewidth=2, label='线性')
plt.plot(x, y2, color='#00FF00', linestyle='--', marker='o', markersize=5, label='平方')
plt.plot(x, y3, color=(0.2, 0.4, 0.6), linestyle='-.', marker='^', label='立方')
plt.legend()
plt.show()
1
2
3
4
5
6
7
8
9
10

文本与注释

plt.plot(x, np.sin(x))
plt.text(2, 0.5, '局部最大值', fontsize=12, bbox=dict(facecolor='yellow', alpha=0.5))
plt.annotate('峰值', xy=(np.pi/2, 1), xytext=(np.pi/2+1, 0.8),
             arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
1
2
3
4
5

坐标轴设置

plt.plot(x, np.sin(x))
plt.xlim(0, 2*np.pi)  # 设置x轴范围
plt.ylim(-1.5, 1.5)  # 设置y轴范围
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
           ['0', 'π/2', 'π', '3π/2', '2π'])
plt.yticks([-1, 0, 1])
plt.grid(True, linestyle='--', alpha=0.5)
plt.show()
1
2
3
4
5
6
7
8

# 1.1.5 子图布局

使用 subplots 可以创建多个子图,并通过 axs 索引访问每个子图。

fig, axs = plt.subplots(2, 2, figsize=(10, 8))  # 2行2列

x = np.linspace(0, 2*np.pi, 100)
axs[0, 0].plot(x, np.sin(x))
axs[0, 0].set_title('sin')

axs[0, 1].plot(x, np.cos(x))
axs[0, 1].set_title('cos')

axs[1, 0].plot(x, np.tan(x))
axs[1, 0].set_ylim(-5, 5)
axs[1, 0].set_title('tan')

axs[1, 1].plot(x, np.exp(-x) * np.sin(x))
axs[1, 1].set_title('阻尼振荡')

plt.tight_layout()  # 自动调整子图间距
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 1.2 Pandas内置绘图

Pandas的Series和DataFrame对象提供了 plot() 方法,它基于Matplotlib实现,可以快速绘制常见图表,特别适合数据探索阶段。

# 1.2.1 Series和DataFrame的plot方法

plot() 方法的参数与Matplotlib类似,但更加简洁。

import pandas as pd

# 创建示例DataFrame
# np.random.randn(100)生成100个服从标准正态分布的随机数,.cumsum()计算这些随机数的累积和,生成一个随机游走序列
# index=pd.date_range('2026-09-10', periods=100, freq='D')创建一个日期索引,从2026年9月10日开始,连续100天,频率为每日
df = pd.DataFrame({
    'A': np.random.randn(100).cumsum(),
    'B': np.random.randn(100).cumsum(),
    'C': np.random.randn(100).cumsum()
}, index=pd.date_range('2026-09-10', periods=100, freq='D'))

# 默认折线图
df.plot(figsize=(10, 6))
plt.title('Pandas 默认折线图')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 1.2.2 常用图表快速绘制

通过 kind 参数指定图表类型,如 'line'、'bar'、'barh'、'hist'、'box'、'kde'、'area'、'scatter'、'hexbin' 等。

柱状图

df_bar = pd.DataFrame({
    'group': ['A', 'B', 'C', 'D'],
    'values': [23, 45, 56, 78]
}).set_index('group')

df_bar.plot(kind='bar', legend=False)
plt.title('Pandas 柱状图')
plt.show()
1
2
3
4
5
6
7
8

直方图

# df[['A', 'B']]:从原始DataFrame df中选取列A和B,形成一个新的DataFrame
# kind='hist':指定绘制直方图
# bins=30:将数据范围划分为30个等宽的区间。这个值越大,柱子越细,对数据分布刻画越细致;值越小,柱子越宽,分布更平滑
# alpha=0.5:设置透明度为0.5半透明
# stacked=True:启用堆叠模式。对于每个区间,不同列(A和B)的频数会堆叠在一起,形成一个总柱子,不同颜色代表不同列。如果不堆叠(默认),两列会并排显示(并排直方图)
df[['A', 'B']].plot(kind='hist', bins=30, alpha=0.5, stacked=True)
plt.title('Pandas 直方图')
plt.show()
1
2
3
4
5
6
7
8

箱线图

# 箱线图(也称盒须图)通过五个统计量概括数据的分布:
# 最小值(下须端点):通常指数据中非异常值的最小值(Q1-1.5×IQR范围内)。
# 第一四分位数(Q1):数据的25%分位数,即箱子的下边界。
# 中位数(Q2):数据的50%分位数,箱子内部的横线。
# 第三四分位数(Q3):数据的75%分位数,箱子的上边界。
# 最大值(上须端点):非异常值的最大值(Q3+1.5×IQR范围内)。
# 异常值(离群点):用散点(通常是圆圈)表示落在须线范围之外的数据点。
df.plot(kind='box')
plt.title('Pandas 箱线图')
plt.show()
1
2
3
4
5
6
7
8
9
10

散点图

df.plot(kind='scatter', x='A', y='B', c='C', colormap='viridis')
plt.title('Pandas 散点图')
plt.show()
1
2
3

面积图

df.plot(kind='area', stacked=False, alpha=0.5)
plt.title('Pandas 面积图')
plt.show()
1
2
3

# 1.3 Seaborn统计绘图

Seaborn是基于Matplotlib的高级可视化库,它提供了更美观的默认样式和更简洁的接口,特别适合统计图表的绘制。Seaborn通常与Pandas数据框结合使用。

# 1.3.1 Seaborn风格与主题

Seaborn自带多种主题和颜色调色板,可以轻松美化图表。

import seaborn as sns

# 设置主题
sns.set_theme(style="whitegrid")  # 可选:darkgrid, whitegrid, dark, white, ticks

# 设置调色板
sns.set_palette("husl")

# 加载内置数据集
tips = sns.load_dataset("tips")
print(tips.head())
1
2
3
4
5
6
7
8
9
10
11

# 1.3.2 关系型图表

用于展示两个或多个变量之间的关系。

  • 散点图:scatterplot()
  • 折线图:lineplot()
  • 关系类图:relplot()(可绘制分面图)
import matplotlib.pyplot as plt
import seaborn as sns

# 设置字体,解决中文乱码ubuntu
# plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']
# plt.rcParams['axes.unicode_minus'] = False
# macos26
plt.rcParams['font.sans-serif'] = ['PingFang SC']  # 苹方,macOS默认中文字体
plt.rcParams['axes.unicode_minus'] = False

# 加载数据
tips = sns.load_dataset("tips")

# 绘制散点图
sns.scatterplot(data=tips, x='total_bill', y='tip', hue='time', style='sex', size='size')
plt.title('小费数据散点图')
plt.show()

# 折线图
sns.lineplot(data=tips, x='size', y='tip', errorbar=('ci', 95))
plt.show()

# 分面散点图
sns.relplot(data=tips, x='total_bill', y='tip', col='time', hue='sex')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 1.3.3 分类型图表

用于展示分类变量与数值变量的关系。

  • 条形图:barplot()(显示均值及误差条)
  • 箱线图:boxplot()
  • 小提琴图:violinplot()(结合箱线图与核密度估计)
  • 计数图:countplot()(统计频次)
# 条形图
sns.barplot(data=tips, x='day', y='total_bill', hue='sex')
plt.title('每日消费额条形图')
plt.show()

# 箱线图
sns.boxplot(data=tips, x='day', y='total_bill', hue='smoker')
plt.show()

# 小提琴图
sns.violinplot(data=tips, x='day', y='total_bill', split=True)
plt.show()

# 计数图
sns.countplot(data=tips, x='day', hue='time')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 1.3.4 分布型图表

用于展示单个变量或多个变量的分布。

  • 直方图:histplot()(可叠加核密度估计)
  • 核密度估计图:kdeplot()
  • 联合分布图:jointplot()(同时展示两个变量的分布和散点)
  • 配对图:pairplot()(展示所有数值变量的两两关系)
# 直方图+核密度
sns.histplot(data=tips, x='total_bill', kde=True, bins=30)
plt.show()

# 核密度图(可分组)
sns.kdeplot(data=tips, x='total_bill', hue='time', fill=True)
plt.show()

# 联合分布图
sns.jointplot(data=tips, x='total_bill', y='tip', kind='scatter')  # kind可选 'kde', 'hex', 'reg' 等
plt.show()

# 配对图(只选数值列)
sns.pairplot(tips[['total_bill', 'tip', 'size']])
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 1.3.5 回归图

展示变量间的线性关系。

  • regplot():绘制散点图并拟合回归线。
  • lmplot():结合 regplot 和分面功能。
# 简单回归
sns.regplot(data=tips, x='total_bill', y='tip', ci=95)
plt.show()

# 分面回归
sns.lmplot(data=tips, x='total_bill', y='tip', col='day', hue='sex')
plt.show()
1
2
3
4
5
6
7

# 1.4 Pyecharts交互式可视化

Pyecharts是一个用于生成ECharts图表的Python库。ECharts是百度开源的一个强大的数据可视化库,支持丰富的交互效果。Pyecharts使得在Python中轻松创建交互式图表变得可能,尤其适合Web应用和Jupyter Notebook。

# 1.4.1 Pyecharts简介

Pyecharts分为v1和v2版本,我们使用最新的v2(实际上当前最新为v2.x,但注意版本兼容性)。在Jupyter Notebook中,Pyecharts可以直接渲染,无需额外配置(可能需要安装 jupyter-echarts 扩展,但一般内置支持)。如果图表不显示,可以尝试:

from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
1
2

# 1.4.2 基本用法

Pyecharts的绘图流程:创建一个图表对象(如 Bar、Line),添加数据,设置全局配置项,然后在Jupyter中直接输出(调用 .render_notebook())或保存为HTML文件(.render())。

from pyecharts.charts import Bar
from pyecharts import options as opts

# 创建柱状图
bar = (
    Bar()
    .add_xaxis(['苹果', '香蕉', '橘子', '葡萄'])
    .add_yaxis('销量', [23, 45, 56, 78])
    .set_global_opts(title_opts=opts.TitleOpts(title='水果销量柱状图'))
)

# 在Jupyter Notebook中显示
bar.render_notebook()
1
2
3
4
5
6
7
8
9
10
11
12
13

# 1.4.3 常用图表

柱状图

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = (
    Bar()
    .add_xaxis(['A', 'B', 'C', 'D'])
    .add_yaxis('系列1', [10, 20, 30, 40])
    .add_yaxis('系列2', [15, 25, 35, 45])
    .set_global_opts(
        title_opts=opts.TitleOpts(title='多系列柱状图'),
        toolbox_opts=opts.ToolboxOpts(is_show=True),  # 显示工具箱(保存、缩放等)
        legend_opts=opts.LegendOpts(pos_left='center')
    )
    .set_series_opts(
        label_opts=opts.LabelOpts(is_show=True)  # 显示数据标签
    )
)
bar.render_notebook()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

折线图

from pyecharts.charts import Line
from pyecharts import options as opts

months  = ["1月", "2月", "3月", "4月", "5月", "6月"]
sales_a = [120, 132, 101, 134, 90, 230]
sales_b = [220, 182, 191, 234, 290, 330]

line = (
    Line()
    .add_xaxis(months)
    .add_yaxis("手机", sales_a, is_smooth=True)
    .add_yaxis("笔记本", sales_b, is_smooth=True)
    .set_global_opts(title_opts=opts.TitleOpts(title="平滑折线"))
)
line.render_notebook()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

散点图

from pyecharts.charts import Scatter
import random

data = [[random.randint(0, 100), random.randint(0, 100)] for _ in range(50)]

scatter = (
    Scatter()
    .add_xaxis([d[0] for d in data])
    .add_yaxis('随机点', [d[1] for d in data])
    .set_global_opts(
        title_opts=opts.TitleOpts(title='散点图'),
        xaxis_opts=opts.AxisOpts(name='X'),
        yaxis_opts=opts.AxisOpts(name='Y'),
        visualmap_opts=opts.VisualMapOpts()  # 添加视觉映射组件
    )
)
scatter.render_notebook()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

饼图

from pyecharts.charts import Pie

data_pair = [('苹果', 25), ('香蕉', 35), ('橘子', 20), ('葡萄', 20)]

pie = (
    Pie()
    .add('', data_pair)
    .set_global_opts(title_opts=opts.TitleOpts(title='水果占比'))
    .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}: {d}%'))  # 显示百分比
)
pie.render_notebook()
1
2
3
4
5
6
7
8
9
10
11

地图

Pyecharts支持中国地图、世界地图等,需要安装扩展包:

pip install echarts-china-provinces-pypkg echarts-china-cities-pypkg echarts-china-counties-pypkg
1
from pyecharts.charts import Map
from pyecharts import options as opts

# 示例:中国各省份数据
data = [('广东省', 100), ('江苏省', 80), ('浙江省', 70), ('北京市', 60), ('上海市', 90)]

map_chart = (
    Map()
    .add('', data, 'china')
    .set_global_opts(
        title_opts=opts.TitleOpts(title='中国地图示例'),
        visualmap_opts=opts.VisualMapOpts(max_=100, is_piecewise=True)
    )
)
map_chart.render_notebook()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 1.4.4 多图表组合

使用 Grid、Tab 等组件可以将多个图表组合在一起。

from pyecharts.charts import Grid, Bar, Line

bar = (
    Bar()
    .add_xaxis(['A', 'B', 'C'])
    .add_yaxis('销量', [23, 45, 56])
)
line = (
    Line()
    .add_xaxis(['A', 'B', 'C'])
    .add_yaxis('增长率', [0.2, 0.3, 0.1])
)

grid = (
    Grid()
    .add(bar, grid_opts=opts.GridOpts(pos_bottom='60%'))
    .add(line, grid_opts=opts.GridOpts(pos_top='60%'))
)
grid.render_notebook()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 1.4.5 在Jupyter Notebook中的显示注意事项

  • 确保notebook是最新版本,并安装了 ipywidgets。
  • 如果图表不显示,可以尝试调用 chart.render_notebook() 后检查是否有JavaScript错误。
  • 也可以使用 chart.render('output.html') 生成HTML文件,在浏览器中打开。

# 小结

数据可视化是数据分析不可或缺的环节。本部分介绍了从基础静态绘图(Matplotlib、Pandas内置绘图、Seaborn)到交互式绘图(Pyecharts)的完整体系。Matplotlib提供了底层控制,Pandas内置绘图适合快速探索,Seaborn让统计图表更加美观易用,而Pyecharts则为生成交互式图表提供了便捷途径。掌握这些工具,您可以根据需求选择合适的可视化方式。

明天Day5见!See you tomorrow!

最近更新: 2026/9/30
 |  Copyright © -Present Kelsen All Rights Reserved. | Author KelsenJing