Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • python 学习指南
  • python 中的设计模式
  • module

    • python modules
    • pandas
    • numpy
    • matplotlib
      • 基础知识
        • 基本概念
        • Figure and Axis
        • 基本绘图
        • 绘图样式设置
      • 图表类型
        • 1. 线图 (Line Plot)
        • 2. 散点图 (Scatter Plot)
        • 3. 柱状图 (Bar Plot)
        • 4. 直方图 (Histogram)
        • 5. 饼图 (Pie Chart)
        • 6. 箱线图 (Box Plot)
        • 7. 热力图 (Heatmap)
      • 3D绘图
        • 基础知识大纲
        • 1. 3D坐标系概念
        • 2. 3D图形基本元素
        • 3. 视角和投影
        • 4. 3D绘图基本步骤
        • 1. 3D线图
        • 2. 3D散点图
        • 3. 3D表面图
      • 高级特性
        • 1. 自定义样式
        • 2. 子图布局
        • 3. 动画
        • 4. 交互式绘图
      • 实际应用案例
        • 1. 数据分析可视化
        • 股票数据分析
        • 时间序列分析
        • 2. 机器学习结果可视化
        • 分类结果可视化
        • 回归结果可视化
        • 3. 科学计算可视化
        • 偏微分方程可视化
        • 信号处理可视化
        • 4. 数据故事化
      • 扩展资源
        • 1. 相关库
        • 2. 学习资源
        • 3. 社区资源
      • link
    • scipy
    • python typing 模块
    • inspect
    • beautysoup
    • scrapy
    • splash
    • pytorch
  • tool

  • other

  • 《python》
  • module
Jacky
2023-09-30
目录

matplotlib

# 基础知识

Matplotlib是Python中最流行的绘图库,提供了丰富的2D和3D绘图功能,是数据可视化的基础工具。

# 基本概念

# Figure and Axis

在Matplotlib中,Figure和Axis是两个重要的概念,它们分别代表了绘图的整个图像和图像上的一个子区域。

  1. Figure(图像):

    • Figure是整个绘图的最顶层容器,它包含了所有的绘图元素
    • 可以通过plt.figure()函数创建一个新的Figure对象
    • 一个Figure对象可以包含多个子区域(Axis对象)
    • Figure对象可以保存为图片文件,如PNG、PDF等格式
  2. Axis(轴):

    • Axis是Figure内部的一个子区域,包含坐标轴、刻度、标签以及绘图区域
    • 每个Axis对象都有自己的X轴和Y轴
    • 可以通过ax.set_xlabel()、ax.set_ylabel()设置轴标签
    • 可以通过ax.set_xlim()、ax.set_ylim()设置轴的范围

# 基本绘图

import matplotlib.pyplot as plt
import numpy as np

# 创建简单的线图
x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.figure(figsize=(8, 6))
plt.plot(x, y, 'b-', linewidth=2, label='sin(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.title('正弦函数')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 创建子图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# 第一个子图
ax1.plot(x, np.sin(x), 'b-', label='sin(x)')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_title('正弦函数')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 第二个子图
ax2.plot(x, np.cos(x), 'r-', label='cos(x)')
ax2.set_xlabel('x')
ax2.set_ylabel('y')
ax2.set_title('余弦函数')
ax2.legend()
ax2.grid(True, alpha=0.3)

plt.tight_layout()
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
28
29
30
31
32
33
34
35
36
37

# 绘图样式设置

# 设置绘图样式
plt.style.use('seaborn-v0_8')  # 使用seaborn样式

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 设置图形大小和DPI
plt.figure(figsize=(10, 6), dpi=100)

# 设置颜色和线型
colors = ['red', 'blue', 'green', 'orange', 'purple']
line_styles = ['-', '--', '-.', ':', '-']
markers = ['o', 's', '^', 'D', 'v']
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 图表类型

# 1. 线图 (Line Plot)

# 基本线图
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

plt.figure(figsize=(10, 6))
plt.plot(x, y1, 'b-', linewidth=2, label='sin(x)')
plt.plot(x, y2, 'r--', linewidth=2, label='cos(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.title('三角函数')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 多线图
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

# 子图1:基本线图
axes[0, 0].plot(x, y1)
axes[0, 0].set_title('基本线图')

# 子图2:带标记的线图
axes[0, 1].plot(x, y1, 'o-', markersize=4)
axes[0, 1].set_title('带标记的线图')

# 子图3:多条线
axes[1, 0].plot(x, y1, label='sin(x)')
axes[1, 0].plot(x, y2, label='cos(x)')
axes[1, 0].legend()
axes[1, 0].set_title('多条线')

# 子图4:填充区域
axes[1, 1].fill_between(x, y1, y2, alpha=0.3)
axes[1, 1].plot(x, y1, 'b-', label='sin(x)')
axes[1, 1].plot(x, y2, 'r-', label='cos(x)')
axes[1, 1].legend()
axes[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
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 2. 散点图 (Scatter Plot)

# 基本散点图
np.random.seed(42)
x = np.random.randn(100)
y = np.random.randn(100)
colors = np.random.rand(100)
sizes = 1000 * np.random.rand(100)

plt.figure(figsize=(10, 6))
plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
plt.colorbar(label='颜色值')
plt.xlabel('x')
plt.ylabel('y')
plt.title('散点图')
plt.grid(True, alpha=0.3)
plt.show()

# 分类散点图
categories = np.random.choice(['A', 'B', 'C'], 100)
colors_map = {'A': 'red', 'B': 'blue', 'C': 'green'}

plt.figure(figsize=(10, 6))
for category in ['A', 'B', 'C']:
    mask = categories == category
    plt.scatter(x[mask], y[mask], c=colors_map[category], 
                label=category, alpha=0.7, s=50)

plt.xlabel('x')
plt.ylabel('y')
plt.title('分类散点图')
plt.legend()
plt.grid(True, alpha=0.3)
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
28
29
30
31
32

# 3. 柱状图 (Bar Plot)

# 基本柱状图
categories = ['A', 'B', 'C', 'D', 'E']
values = [23, 45, 56, 78, 32]

plt.figure(figsize=(10, 6))
bars = plt.bar(categories, values, color='skyblue', alpha=0.7)
plt.xlabel('类别')
plt.ylabel('数值')
plt.title('基本柱状图')

# 在柱子上添加数值标签
for bar, value in zip(bars, values):
    plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 1,
             str(value), ha='center', va='bottom')

plt.grid(True, alpha=0.3, axis='y')
plt.show()

# 分组柱状图
categories = ['A', 'B', 'C', 'D']
group1 = [23, 45, 56, 78]
group2 = [34, 56, 67, 89]

x = np.arange(len(categories))
width = 0.35

plt.figure(figsize=(10, 6))
plt.bar(x - width/2, group1, width, label='组1', alpha=0.7)
plt.bar(x + width/2, group2, width, label='组2', alpha=0.7)

plt.xlabel('类别')
plt.ylabel('数值')
plt.title('分组柱状图')
plt.xticks(x, categories)
plt.legend()
plt.grid(True, alpha=0.3, axis='y')
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
28
29
30
31
32
33
34
35
36
37

# 4. 直方图 (Histogram)

# 基本直方图
data = np.random.normal(0, 1, 1000)

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

plt.subplot(1, 3, 1)
plt.hist(data, bins=30, alpha=0.7, color='skyblue', edgecolor='black')
plt.xlabel('值')
plt.ylabel('频次')
plt.title('基本直方图')
plt.grid(True, alpha=0.3)

plt.subplot(1, 3, 2)
plt.hist(data, bins=30, alpha=0.7, color='lightgreen', 
         edgecolor='black', density=True)
plt.xlabel('值')
plt.ylabel('密度')
plt.title('密度直方图')
plt.grid(True, alpha=0.3)

plt.subplot(1, 3, 3)
plt.hist(data, bins=30, alpha=0.7, color='lightcoral', 
         edgecolor='black', cumulative=True)
plt.xlabel('值')
plt.ylabel('累积频次')
plt.title('累积直方图')
plt.grid(True, alpha=0.3)

plt.tight_layout()
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
28
29
30

# 5. 饼图 (Pie Chart)

# 基本饼图
sizes = [30, 25, 20, 15, 10]
labels = ['A', 'B', 'C', 'D', 'E']
colors = ['lightblue', 'lightgreen', 'lightcoral', 'lightyellow', 'lightpink']

plt.figure(figsize=(10, 6))
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', 
        startangle=90, explode=(0.1, 0, 0, 0, 0))
plt.title('基本饼图')
plt.axis('equal')
plt.show()

# 环形图
plt.figure(figsize=(10, 6))
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
        startangle=90, pctdistance=0.85)
centre_circle = plt.Circle((0,0), 0.70, fc='white')
fig = plt.gcf()
fig.gca().add_artist(centre_circle)
plt.title('环形图')
plt.axis('equal')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 6. 箱线图 (Box Plot)

# 基本箱线图
data1 = np.random.normal(0, 1, 100)
data2 = np.random.normal(2, 1.5, 100)
data3 = np.random.normal(-1, 0.5, 100)

plt.figure(figsize=(10, 6))
plt.boxplot([data1, data2, data3], labels=['组1', '组2', '组3'])
plt.ylabel('值')
plt.title('基本箱线图')
plt.grid(True, alpha=0.3)
plt.show()

# 分组箱线图
group1 = [np.random.normal(0, 1, 50), np.random.normal(0, 1, 50)]
group2 = [np.random.normal(2, 1, 50), np.random.normal(2, 1, 50)]

plt.figure(figsize=(10, 6))
plt.boxplot(group1 + group2, labels=['A1', 'A2', 'B1', 'B2'])
plt.ylabel('值')
plt.title('分组箱线图')
plt.grid(True, alpha=0.3)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 7. 热力图 (Heatmap)

# 基本热力图
data = np.random.rand(10, 10)

plt.figure(figsize=(8, 6))
im = plt.imshow(data, cmap='viridis')
plt.colorbar(im)
plt.title('基本热力图')
plt.show()

# 相关性热力图
import pandas as pd

# 创建示例数据
np.random.seed(42)
df = pd.DataFrame(np.random.randn(100, 4), columns=['A', 'B', 'C', 'D'])
correlation_matrix = df.corr()

plt.figure(figsize=(8, 6))
im = plt.imshow(correlation_matrix, cmap='coolwarm', vmin=-1, vmax=1)
plt.colorbar(im)

# 添加数值标签
for i in range(len(correlation_matrix.columns)):
    for j in range(len(correlation_matrix.columns)):
        plt.text(j, i, f'{correlation_matrix.iloc[i, j]:.2f}',
                ha='center', va='center')

plt.xticks(range(len(correlation_matrix.columns)), correlation_matrix.columns)
plt.yticks(range(len(correlation_matrix.columns)), correlation_matrix.columns)
plt.title('相关性热力图')
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
28
29
30
31

# 3D绘图

# 基础知识大纲

# 1. 3D坐标系概念

  • X轴、Y轴、Z轴:三维空间的基本坐标轴
  • 坐标点:(x, y, z) 表示三维空间中的位置
  • 投影:3D图形在2D平面上的投影显示

# 2. 3D图形基本元素

  • 3D线图:三维空间中的曲线
  • 3D散点图:三维空间中的点集
  • 3D表面图:三维空间中的曲面
  • 3D等高线图:三维数据的等高线表示

# 3. 视角和投影

  • 视角控制:azim(方位角)、elev(仰角)
  • 投影类型:正交投影、透视投影
  • 缩放和平移:3D图形的交互操作

# 4. 3D绘图基本步骤

  1. 创建3D轴:ax = fig.add_subplot(111, projection='3d')
  2. 准备数据:X, Y, Z坐标数据
  3. 选择绘图类型:plot、scatter、plot_surface等
  4. 设置视角和标签
  5. 显示图形

# 1. 3D线图

from mpl_toolkits.mplot3d import Axes3D

# 3D螺旋线
t = np.linspace(0, 10, 100)
x = np.cos(t)
y = np.sin(t)
z = t

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z, 'b-', linewidth=2)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D螺旋线')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 2. 3D散点图

# 3D散点图
np.random.seed(42)
x = np.random.randn(100)
y = np.random.randn(100)
z = np.random.randn(100)
colors = np.random.rand(100)

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter(x, y, z, c=colors, cmap='viridis', s=50)
plt.colorbar(scatter)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D散点图')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 3. 3D表面图

# 3D表面图
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))

fig = plt.figure(figsize=(12, 5))

# 表面图
ax1 = fig.add_subplot(121, projection='3d')
surf = ax1.plot_surface(X, Y, Z, cmap='viridis', alpha=0.8)
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('Z')
ax1.set_title('3D表面图')
fig.colorbar(surf, ax=ax1)

# 等高线图
ax2 = fig.add_subplot(122, projection='3d')
contour = ax2.contour3D(X, Y, Z, 50, cmap='viridis')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('Z')
ax2.set_title('3D等高线图')
fig.colorbar(contour, ax=ax2)

plt.tight_layout()
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
28

# 高级特性

# 1. 自定义样式

# 自定义样式
plt.style.use('default')  # 重置为默认样式

# 自定义颜色
custom_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']

# 自定义字体
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 12
plt.rcParams['axes.titlesize'] = 14
plt.rcParams['axes.labelsize'] = 12
plt.rcParams['xtick.labelsize'] = 10
plt.rcParams['ytick.labelsize'] = 10

# 创建自定义样式图
fig, ax = plt.subplots(figsize=(10, 6))
x = np.linspace(0, 10, 100)
y = np.sin(x)

ax.plot(x, y, color=custom_colors[0], linewidth=2, label='sin(x)')
ax.plot(x, np.cos(x), color=custom_colors[1], linewidth=2, label='cos(x)')
ax.set_xlabel('x轴', fontsize=12)
ax.set_ylabel('y轴', fontsize=12)
ax.set_title('自定义样式图', fontsize=14, fontweight='bold')
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
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
28
29

# 2. 子图布局

# 复杂的子图布局
fig = plt.figure(figsize=(15, 10))

# 使用GridSpec创建复杂布局
from matplotlib.gridspec import GridSpec
gs = GridSpec(3, 3, figure=fig)

# 主图(占据2x2区域)
ax_main = fig.add_subplot(gs[0:2, 0:2])
x = np.linspace(0, 10, 100)
ax_main.plot(x, np.sin(x), 'b-', label='sin(x)')
ax_main.plot(x, np.cos(x), 'r-', label='cos(x)')
ax_main.set_title('主图')
ax_main.legend()
ax_main.grid(True, alpha=0.3)

# 右侧小图
ax_right = fig.add_subplot(gs[0:2, 2])
ax_right.hist(np.random.normal(0, 1, 1000), bins=30, alpha=0.7)
ax_right.set_title('直方图')

# 底部小图
ax_bottom = fig.add_subplot(gs[2, :])
ax_bottom.scatter(np.random.rand(50), np.random.rand(50), alpha=0.7)
ax_bottom.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
19
20
21
22
23
24
25
26
27
28

# 3. 动画

# 基本动画
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots(figsize=(8, 6))
x = np.linspace(0, 10, 100)
line, = ax.plot([], [], 'b-', linewidth=2)
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.set_title('动画正弦波')
ax.grid(True, alpha=0.3)

def animate(frame):
    y = np.sin(x + frame * 0.1)
    line.set_data(x, y)
    return line,

ani = FuncAnimation(fig, animate, frames=100, interval=50, blit=True)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 4. 交互式绘图

# 交互式绘图
from matplotlib.widgets import Slider, Button

fig, ax = plt.subplots(figsize=(10, 6))
plt.subplots_adjust(bottom=0.25)

x = np.linspace(0, 10, 100)
y = np.sin(x)
line, = ax.plot(x, y, 'b-', linewidth=2)
ax.set_xlabel('x')
ax.set_ylabel('sin(x)')
ax.set_title('交互式正弦波')
ax.grid(True, alpha=0.3)

# 添加滑块
ax_freq = plt.axes([0.25, 0.1, 0.65, 0.03])
freq_slider = Slider(ax_freq, '频率', 0.1, 2.0, valinit=1.0)

def update(val):
    freq = freq_slider.val
    line.set_ydata(np.sin(freq * x))
    fig.canvas.draw_idle()

freq_slider.on_changed(update)
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. 数据分析可视化

# 股票数据分析

# 股票数据分析
import pandas as pd
import yfinance as yf

# 获取股票数据
ticker = "AAPL"
stock_data = yf.download(ticker, start="2023-01-01", end="2023-12-31")

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

# 价格走势
axes[0, 0].plot(stock_data.index, stock_data['Close'], 'b-', linewidth=1)
axes[0, 0].set_title(f'{ticker} 收盘价走势')
axes[0, 0].set_ylabel('价格 ($)')
axes[0, 0].grid(True, alpha=0.3)

# 成交量
axes[0, 1].bar(stock_data.index, stock_data['Volume'], alpha=0.7, color='green')
axes[0, 1].set_title('成交量')
axes[0, 1].set_ylabel('成交量')
axes[0, 1].grid(True, alpha=0.3)

# 日收益率分布
daily_returns = stock_data['Close'].pct_change().dropna()
axes[1, 0].hist(daily_returns, bins=50, alpha=0.7, color='orange')
axes[1, 0].set_title('日收益率分布')
axes[1, 0].set_xlabel('收益率')
axes[1, 0].set_ylabel('频次')
axes[1, 0].grid(True, alpha=0.3)

# 移动平均线
ma_20 = stock_data['Close'].rolling(window=20).mean()
ma_50 = stock_data['Close'].rolling(window=50).mean()
axes[1, 1].plot(stock_data.index, stock_data['Close'], 'b-', label='收盘价', alpha=0.7)
axes[1, 1].plot(stock_data.index, ma_20, 'r-', label='20日均线', linewidth=2)
axes[1, 1].plot(stock_data.index, ma_50, 'g-', label='50日均线', linewidth=2)
axes[1, 1].set_title('移动平均线')
axes[1, 1].legend()
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 时间序列分析

# 时间序列分析
def time_series_analysis():
    # 生成时间序列数据
    dates = pd.date_range('2023-01-01', periods=365, freq='D')
    np.random.seed(42)
    
    # 趋势 + 季节性 + 噪声
    trend = np.linspace(0, 10, 365)
    seasonal = 5 * np.sin(2 * np.pi * np.arange(365) / 365)
    noise = np.random.normal(0, 1, 365)
    data = trend + seasonal + noise
    
    # 创建时间序列图
    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    
    # 原始数据
    axes[0, 0].plot(dates, data, 'b-', linewidth=1)
    axes[0, 0].set_title('原始时间序列')
    axes[0, 0].set_ylabel('值')
    axes[0, 0].grid(True, alpha=0.3)
    
    # 趋势分解
    from scipy import signal
    detrended = signal.detrend(data)
    axes[0, 1].plot(dates, detrended, 'g-', linewidth=1)
    axes[0, 1].set_title('去趋势数据')
    axes[0, 1].set_ylabel('值')
    axes[0, 1].grid(True, alpha=0.3)
    
    # 自相关图
    from statsmodels.graphics.tsaplots import plot_acf
    plot_acf(data, ax=axes[1, 0], lags=40)
    axes[1, 0].set_title('自相关函数')
    
    # 功率谱密度
    from scipy import signal
    freqs, psd = signal.welch(data)
    axes[1, 1].semilogy(freqs, psd)
    axes[1, 1].set_title('功率谱密度')
    axes[1, 1].set_xlabel('频率')
    axes[1, 1].set_ylabel('功率谱密度')
    axes[1, 1].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.show()

# time_series_analysis()  # 需要安装statsmodels
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 2. 机器学习结果可视化

# 分类结果可视化

# 分类结果可视化
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, classification_report

# 生成数据
X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0, 
                          n_informative=2, random_state=42, n_clusters_per_class=1)

# 训练模型
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# 可视化结果
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

# 散点图
scatter = axes[0].scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap='viridis', alpha=0.7)
axes[0].set_title('真实标签')
axes[0].set_xlabel('特征1')
axes[0].set_ylabel('特征2')
plt.colorbar(scatter, ax=axes[0])

# 预测结果
scatter = axes[1].scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='viridis', alpha=0.7)
axes[1].set_title('预测标签')
axes[1].set_xlabel('特征1')
axes[1].set_ylabel('特征2')
plt.colorbar(scatter, ax=axes[1])

# 混淆矩阵
cm = confusion_matrix(y_test, y_pred)
im = axes[2].imshow(cm, cmap='Blues', interpolation='nearest')
axes[2].set_title('混淆矩阵')
axes[2].set_xlabel('预测标签')
axes[2].set_ylabel('真实标签')

# 添加数值标签
for i in range(2):
    for j in range(2):
        axes[2].text(j, i, str(cm[i, j]), ha='center', va='center')

plt.tight_layout()
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 回归结果可视化

# 回归结果可视化
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score, mean_squared_error

# 生成回归数据
np.random.seed(42)
X = np.random.rand(100, 1) * 10
y = 2 * X.flatten() + 1 + np.random.normal(0, 1, 100)

# 训练模型
model = LinearRegression()
model.fit(X, y)
y_pred = model.predict(X)

# 可视化结果
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

# 散点图和回归线
axes[0, 0].scatter(X, y, alpha=0.7, label='数据点')
axes[0, 0].plot(X, y_pred, 'r-', linewidth=2, label='回归线')
axes[0, 0].set_xlabel('X')
axes[0, 0].set_ylabel('y')
axes[0, 0].set_title('回归结果')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

# 残差图
residuals = y - y_pred
axes[0, 1].scatter(y_pred, residuals, alpha=0.7)
axes[0, 1].axhline(y=0, color='r', linestyle='--')
axes[0, 1].set_xlabel('预测值')
axes[0, 1].set_ylabel('残差')
axes[0, 1].set_title('残差图')
axes[0, 1].grid(True, alpha=0.3)

# 残差分布
axes[1, 0].hist(residuals, bins=20, alpha=0.7, edgecolor='black')
axes[1, 0].set_xlabel('残差')
axes[1, 0].set_ylabel('频次')
axes[1, 0].set_title('残差分布')
axes[1, 0].grid(True, alpha=0.3)

# Q-Q图
from scipy import stats
stats.probplot(residuals, dist="norm", plot=axes[1, 1])
axes[1, 1].set_title('Q-Q图')

plt.tight_layout()
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 3. 科学计算可视化

# 偏微分方程可视化

# 偏微分方程可视化
from scipy.integrate import solve_bvp
import numpy as np

# 求解热传导方程
def heat_equation():
    def fun(x, y):
        return np.vstack((y[1], -np.exp(y[0])))
    
    def bc(ya, yb):
        return np.array([ya[0], yb[0] - np.log(2)])
    
    x = np.linspace(1, 2, 25)
    y = np.zeros((2, x.size))
    y[0] = np.log(x)
    
    sol = solve_bvp(fun, bc, x, y)
    
    # 可视化结果
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))
    
    # 数值解
    axes[0].plot(sol.x, sol.y[0], 'b-', linewidth=2, label='数值解')
    axes[0].plot(x, np.log(x), 'r--', linewidth=2, label='解析解')
    axes[0].set_xlabel('x')
    axes[0].set_ylabel('y')
    axes[0].set_title('热传导方程解')
    axes[0].legend()
    axes[0].grid(True, alpha=0.3)
    
    # 误差
    error = np.abs(sol.y[0] - np.log(sol.x))
    axes[1].semilogy(sol.x, error, 'g-', linewidth=2)
    axes[1].set_xlabel('x')
    axes[1].set_ylabel('误差')
    axes[1].set_title('数值误差')
    axes[1].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.show()

heat_equation()
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 信号处理可视化

# 信号处理可视化
def signal_processing_visualization():
    # 生成信号
    t = np.linspace(0, 1, 1000)
    signal = np.sin(2 * np.pi * 10 * t) + 0.5 * np.sin(2 * np.pi * 50 * t)
    noisy_signal = signal + 0.1 * np.random.randn(len(t))
    
    # 傅里叶变换
    from scipy.fft import fft, fftfreq
    fft_signal = fft(noisy_signal)
    freqs = fftfreq(len(t), t[1] - t[0])
    
    # 可视化
    fig, axes = plt.subplots(2, 2, figsize=(12, 8))
    
    # 原始信号
    axes[0, 0].plot(t, signal, 'b-', linewidth=1, label='原始信号')
    axes[0, 0].set_xlabel('时间')
    axes[0, 0].set_ylabel('幅度')
    axes[0, 0].set_title('原始信号')
    axes[0, 0].legend()
    axes[0, 0].grid(True, alpha=0.3)
    
    # 含噪声信号
    axes[0, 1].plot(t, noisy_signal, 'r-', linewidth=1, label='含噪声信号')
    axes[0, 1].set_xlabel('时间')
    axes[0, 1].set_ylabel('幅度')
    axes[0, 1].set_title('含噪声信号')
    axes[0, 1].legend()
    axes[0, 1].grid(True, alpha=0.3)
    
    # 频谱
    positive_freqs = freqs[:len(freqs)//2]
    positive_fft = np.abs(fft_signal[:len(freqs)//2])
    axes[1, 0].plot(positive_freqs, positive_fft, 'g-', linewidth=1)
    axes[1, 0].set_xlabel('频率 (Hz)')
    axes[1, 0].set_ylabel('幅度')
    axes[1, 0].set_title('频谱')
    axes[1, 0].grid(True, alpha=0.3)
    
    # 滤波后的信号
    # 简单的低通滤波
    cutoff_freq = 20
    fft_filtered = fft_signal.copy()
    fft_filtered[np.abs(freqs) > cutoff_freq] = 0
    filtered_signal = np.real(np.fft.ifft(fft_filtered))
    
    axes[1, 1].plot(t, filtered_signal, 'm-', linewidth=1, label='滤波后信号')
    axes[1, 1].plot(t, signal, 'b--', linewidth=1, label='原始信号')
    axes[1, 1].set_xlabel('时间')
    axes[1, 1].set_ylabel('幅度')
    axes[1, 1].set_title('滤波后信号')
    axes[1, 1].legend()
    axes[1, 1].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.show()

signal_processing_visualization()
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 4. 数据故事化

# 数据故事化
def data_storytelling():
    # 创建一个完整的数据故事
    fig = plt.figure(figsize=(16, 12))
    gs = GridSpec(3, 3, figure=fig)
    
    # 标题
    fig.suptitle('数据故事:气候变化趋势分析', fontsize=16, fontweight='bold')
    
    # 1. 问题引入
    ax_intro = fig.add_subplot(gs[0, :])
    years = np.arange(1950, 2024)
    temp_anomaly = 0.5 + 0.02 * (years - 1950) + 0.1 * np.sin(2*np.pi*(years-1950)/11)
    ax_intro.plot(years, temp_anomaly, 'r-', linewidth=2, label='温度异常')
    ax_intro.fill_between(years, temp_anomaly, alpha=0.3, color='red')
    ax_intro.set_title('全球温度异常趋势(1950-2023)')
    ax_intro.set_ylabel('温度异常 (°C)')
    ax_intro.grid(True, alpha=0.3)
    ax_intro.legend()
    
    # 2. 详细分析
    ax_detail = fig.add_subplot(gs[1, 0:2])
    recent_years = years[-30:]
    recent_temp = temp_anomaly[-30:]
    ax_detail.plot(recent_years, recent_temp, 'b-', linewidth=2, marker='o')
    ax_detail.set_title('最近30年趋势')
    ax_detail.set_ylabel('温度异常 (°C)')
    ax_detail.grid(True, alpha=0.3)
    
    # 3. 季节性分析
    ax_seasonal = fig.add_subplot(gs[1, 2])
    months = np.arange(1, 13)
    seasonal_pattern = 0.1 * np.sin(2*np.pi*(months-1)/12)
    ax_seasonal.plot(months, seasonal_pattern, 'g-', linewidth=2, marker='s')
    ax_seasonal.set_title('季节性模式')
    ax_seasonal.set_xlabel('月份')
    ax_seasonal.grid(True, alpha=0.3)
    
    # 4. 预测
    ax_forecast = fig.add_subplot(gs[2, :])
    future_years = np.arange(2024, 2050)
    forecast = 0.5 + 0.02 * (future_years - 1950) + 0.1 * np.sin(2*np.pi*(future_years-1950)/11)
    ax_forecast.plot(years, temp_anomaly, 'b-', linewidth=2, label='历史数据')
    ax_forecast.plot(future_years, forecast, 'r--', linewidth=2, label='预测')
    ax_forecast.fill_between(future_years, forecast-0.1, forecast+0.1, alpha=0.3, color='red')
    ax_forecast.set_title('未来预测(2024-2050)')
    ax_forecast.set_xlabel('年份')
    ax_forecast.set_ylabel('温度异常 (°C)')
    ax_forecast.legend()
    ax_forecast.grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.show()

data_storytelling()
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# 扩展资源

# 1. 相关库

  • Seaborn: 基于Matplotlib的统计数据可视化库
  • Plotly: 交互式绘图库
  • Bokeh: 现代Web浏览器绘图库
  • Altair: 声明式统计可视化库
  • PyViz: 高级可视化工具集

# 2. 学习资源

  • 官方文档: https://matplotlib.org/
  • Matplotlib教程: https://matplotlib.org/stable/tutorials/
  • Matplotlib示例: https://matplotlib.org/stable/gallery/
  • Matplotlib中文文档: https://matplotlib.org.cn/

# 3. 社区资源

  • Stack Overflow: Matplotlib相关问题
  • GitHub: Matplotlib源码和示例
  • Reddit: r/Python和r/DataVisualization
  • Discord: Python和科学计算社区

# link

  • matplotlib (opens new window)
    • tutorials (opens new window)
    • gallery (opens new window)
    • api (opens new window)
  • matplotlib 中文网 (opens new window)
  • seaborn (opens new window)
  • plotly (opens new window)
#matplotlib#Python#data-visualization#plotting
上次更新: 2025/10/08, 16:24:59
numpy
scipy

← numpy scipy→

最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式