【AI Study】第五天,Matplotlib(10)- 实际应用

文章概要

本文详细介绍 Matplotlib 的实际应用,包括:

  • 数据分析可视化
  • 科学计算可视化
  • 交互式应用
  • 报告生成

数据分析可视化

时间序列分析

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, MonthLocator

def plot_time_series_analysis(data, title='时间序列分析'):
    """
    绘制时间序列分析图
    
    参数:
        data: 时间序列数据
        title: 图表标题
    """
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))
    
    # 绘制原始数据
    ax1.plot(data.index, data.values, label='原始数据')
    ax1.set_title('时间序列数据')
    ax1.xaxis.set_major_formatter(DateFormatter('%Y-%m'))
    ax1.xaxis.set_major_locator(MonthLocator())
    ax1.grid(True)
    
    # 绘制移动平均
    ma = data.rolling(window=30).mean()
    ax1.plot(ma.index, ma.values, label='30天移动平均', color='red')
    ax1.legend()
    
    # 绘制自相关图
    pd.plotting.autocorrelation_plot(data, ax=ax2)
    ax2.set_title('自相关图')
    ax2.grid(True)
    
    plt.tight_layout()
    return fig

# 使用示例
dates = pd.date_range('2023-01-01', periods=365)
data = pd.Series(np.sin(np.linspace(0, 10, 365)) + np.random.normal(0, 0.1, 365),
                 index=dates)
fig = plot_time_series_analysis(data)
plt.show()

统计分析

def plot_statistical_analysis(data, title='统计分析'):
    """
    绘制统计分析图
    
    参数:
        data: 数据
        title: 图表标题
    """
    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 8))
    
    # 直方图
    ax1.hist(data, bins=30, density=True, alpha=0.7)
    ax1.set_title('直方图')
    ax1.grid(True)
    
    # 箱线图
    ax2.boxplot(data)
    ax2.set_title('箱线图')
    ax2.grid(True)
    
    # Q-Q图
    from scipy import stats
    stats.probplot(data, dist="norm", plot=ax3)
    ax3.set_title('Q-Q图')
    
    # 核密度估计
    from scipy.stats import gaussian_kde
    kde = gaussian_kde(data)
    x = np.linspace(data.min(), data.max(), 100)
    ax4.plot(x, kde(x))
    ax4.set_title('核密度估计')
    ax4.grid(True)
    
    plt.tight_layout()
    return fig

# 使用示例
data = np.random.normal(0, 1, 1000)
fig = plot_statistical_analysis(data)
plt.show()

地理数据可视化

def plot_geographic_data(data, title='地理数据可视化'):
    """
    绘制地理数据可视化图
    
    参数:
        data: 地理数据
        title: 图表标题
    """
    import cartopy.crs as ccrs
    import cartopy.feature as cfeature
    
    fig = plt.figure(figsize=(12, 8))
    ax = plt.axes(projection=ccrs.PlateCarree())
    
    # 添加地图特征
    ax.add_feature(cfeature.COASTLINE)
    ax.add_feature(cfeature.BORDERS, linestyle=':')
    ax.add_feature(cfeature.LAND, facecolor='lightgray')
    ax.add_feature(cfeature.OCEAN, facecolor='lightblue')
    
    # 绘制数据
    scatter = ax.scatter(data['longitude'], data['latitude'],
                        c=data['value'],
                        cmap='viridis',
                        transform=ccrs.PlateCarree())
    
    # 添加颜色条
    plt.colorbar(scatter, label='数值')
    
    # 设置地图范围
    ax.set_extent([data['longitude'].min()-1, data['longitude'].max()+1,
                   data['latitude'].min()-1, data['latitude'].max()+1])
    
    plt.title(title)
    return fig

# 使用示例
data = pd.DataFrame({
    'longitude': np.random.uniform(-180, 180, 100),
    'latitude': np.random.uniform(-90, 90, 100),
    'value': np.random.rand(100)
})
fig = plot_geographic_data(data)
plt.show()

科学计算可视化

数学函数

def plot_math_functions():
    """
    绘制数学函数图
    """
    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 8))
    
    x = np.linspace(-5, 5, 100)
    
    # 三角函数
    ax1.plot(x, np.sin(x), label='sin(x)')
    ax1.plot(x, np.cos(x), label='cos(x)')
    ax1.set_title('三角函数')
    ax1.grid(True)
    ax1.legend()
    
    # 指数函数
    ax2.plot(x, np.exp(x), label='exp(x)')
    ax2.set_title('指数函数')
    ax2.grid(True)
    ax2.legend()
    
    # 对数函数
    x_pos = np.linspace(0.1, 5, 100)
    ax3.plot(x_pos, np.log(x_pos), label='log(x)')
    ax3.set_title('对数函数')
    ax3.grid(True)
    ax3.legend()
    
    # 多项式函数
    ax4.plot(x, x**2, label='x^2')
    ax4.plot(x, x**3, label='x^3')
    ax4.set_title('多项式函数')
    ax4.grid(True)
    ax4.legend()
    
    plt.tight_layout()
    return fig

fig = plot_math_functions()
plt.show()

物理模拟

def plot_physics_simulation():
    """
    绘制物理模拟图
    """
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
    
    # 简谐运动
    t = np.linspace(0, 10, 1000)
    x = np.sin(t)
    v = np.cos(t)
    
    ax1.plot(t, x, label='位移')
    ax1.plot(t, v, label='速度')
    ax1.set_title('简谐运动')
    ax1.set_xlabel('时间')
    ax1.grid(True)
    ax1.legend()
    
    # 相空间图
    ax2.plot(x, v)
    ax2.set_title('相空间图')
    ax2.set_xlabel('位移')
    ax2.set_ylabel('速度')
    ax2.grid(True)
    
    plt.tight_layout()
    return fig

fig = plot_physics_simulation()
plt.show()

工程计算

def plot_engineering_calculation():
    """
    绘制工程计算图
    """
    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 8))
    
    # 应力-应变曲线
    strain = np.linspace(0, 0.1, 100)
    stress = 200e9 * strain  # 假设弹性模量为 200 GPa
    
    ax1.plot(strain, stress)
    ax1.set_title('应力-应变曲线')
    ax1.set_xlabel('应变')
    ax1.set_ylabel('应力 (Pa)')
    ax1.grid(True)
    
    # 频率响应
    f = np.linspace(0, 1000, 1000)
    H = 1 / (1 + 1j*f/100)  # 一阶系统
    
    ax2.plot(f, np.abs(H))
    ax2.set_title('频率响应')
    ax2.set_xlabel('频率 (Hz)')
    ax2.set_ylabel('幅值')
    ax2.grid(True)
    
    # 温度分布
    x = np.linspace(0, 1, 100)
    y = np.linspace(0, 1, 100)
    X, Y = np.meshgrid(x, y)
    T = np.sin(np.pi*X) * np.sin(np.pi*Y)
    
    im = ax3.imshow(T, cmap='hot')
    ax3.set_title('温度分布')
    plt.colorbar(im, ax=ax3)
    
    # 流速分布
    r = np.linspace(0, 1, 100)
    v = 1 - r**2  # 抛物线分布
    
    ax4.plot(r, v)
    ax4.set_title('流速分布')
    ax4.set_xlabel('径向距离')
    ax4.set_ylabel('流速')
    ax4.grid(True)
    
    plt.tight_layout()
    return fig

fig = plot_engineering_calculation()
plt.show()

交互式应用

数据探索

def create_interactive_plot():
    """
    创建交互式数据探索图
    """
    from matplotlib.widgets import Slider, Button
    
    # 创建数据
    x = np.linspace(0, 10, 100)
    y = np.sin(x)
    
    # 创建图形
    fig, ax = plt.subplots(figsize=(10, 6))
    plt.subplots_adjust(bottom=0.25)
    
    # 绘制初始数据
    line, = ax.plot(x, y)
    
    # 创建滑块
    ax_freq = plt.axes([0.25, 0.1, 0.65, 0.03])
    ax_amp = plt.axes([0.25, 0.15, 0.65, 0.03])
    
    freq_slider = Slider(ax_freq, '频率', 0.1, 5.0, valinit=1)
    amp_slider = Slider(ax_amp, '振幅', 0.1, 2.0, valinit=1)
    
    # 更新函数
    def update(val):
        freq = freq_slider.val
        amp = amp_slider.val
        line.set_ydata(amp * np.sin(freq * x))
        fig.canvas.draw_idle()
    
    # 注册更新函数
    freq_slider.on_changed(update)
    amp_slider.on_changed(update)
    
    # 添加重置按钮
    reset_ax = plt.axes([0.8, 0.025, 0.1, 0.04])
    button = Button(reset_ax, '重置')
    
    def reset(event):
        freq_slider.reset()
        amp_slider.reset()
    
    button.on_clicked(reset)
    
    return fig

fig = create_interactive_plot()
plt.show()

参数调整

def create_parameter_adjustment():
    """
    创建参数调整界面
    """
    from matplotlib.widgets import RadioButtons, CheckButtons
    
    # 创建数据
    x = np.linspace(0, 10, 100)
    y = np.sin(x)
    
    # 创建图形
    fig, ax = plt.subplots(figsize=(10, 6))
    plt.subplots_adjust(left=0.3)
    
    # 绘制初始数据
    line, = ax.plot(x, y)
    
    # 创建单选按钮
    rax = plt.axes([0.05, 0.7, 0.15, 0.15])
    radio = RadioButtons(rax, ('sin', 'cos', 'tan'))
    
    # 创建复选框
    check_ax = plt.axes([0.05, 0.4, 0.15, 0.15])
    check = CheckButtons(check_ax, ('网格', '图例'))
    
    # 更新函数
    def func(label):
        if label == 'sin':
            line.set_ydata(np.sin(x))
        elif label == 'cos':
            line.set_ydata(np.cos(x))
        elif label == 'tan':
            line.set_ydata(np.tan(x))
        fig.canvas.draw_idle()
    
    def check_func(label):
        if label == '网格':
            ax.grid(not ax.get_xgrid())
        elif label == '图例':
            if ax.get_legend() is None:
                ax.legend(['函数'])
            else:
                ax.get_legend().remove()
        fig.canvas.draw_idle()
    
    # 注册更新函数
    radio.on_clicked(func)
    check.on_clicked(check_func)
    
    return fig

fig = create_parameter_adjustment()
plt.show()

实时更新

def create_real_time_plot():
    """
    创建实时更新图
    """
    import time
    
    # 创建图形
    fig, ax = plt.subplots(figsize=(10, 6))
    
    # 初始化数据
    x = np.linspace(0, 10, 100)
    line, = ax.plot(x, np.sin(x))
    
    # 设置图形
    ax.set_ylim(-1.5, 1.5)
    ax.grid(True)
    
    # 实时更新
    for i in range(100):
        # 更新数据
        line.set_ydata(np.sin(x + i/10))
        
        # 重绘图形
        fig.canvas.draw()
        fig.canvas.flush_events()
        
        # 暂停
        time.sleep(0.1)
    
    return fig

fig = create_real_time_plot()
plt.show()

报告生成

自动报告

def generate_automated_report(data, filename='report.pdf'):
    """
    生成自动报告
    
    参数:
        data: 数据
        filename: 输出文件名
    """
    from matplotlib.backends.backend_pdf import PdfPages
    
    with PdfPages(filename) as pdf:
        # 创建多个页面
        pages = [
            ('时间序列分析', plot_time_series_analysis),
            ('统计分析', plot_statistical_analysis),
            ('数学函数', plot_math_functions),
            ('物理模拟', plot_physics_simulation)
        ]
        
        for title, plot_func in pages:
            # 创建图形
            fig = plot_func(data)
            
            # 添加标题
            fig.suptitle(title, fontsize=16)
            
            # 保存到 PDF
            pdf.savefig(fig)
            plt.close(fig)
    
    return filename

# 使用示例
data = pd.Series(np.random.normal(0, 1, 1000))
report_file = generate_automated_report(data)

批量处理

def batch_process_data(data_list, output_dir='output'):
    """
    批量处理数据
    
    参数:
        data_list: 数据列表
        output_dir: 输出目录
    """
    import os
    
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    # 处理每个数据集
    for i, data in enumerate(data_list):
        # 创建图形
        fig = plot_statistical_analysis(data)
        
        # 保存图形
        filename = os.path.join(output_dir, f'analysis_{i+1}.png')
        fig.savefig(filename, dpi=300)
        plt.close(fig)
    
    return output_dir

# 使用示例
data_list = [
    np.random.normal(0, 1, 1000),
    np.random.normal(1, 2, 1000),
    np.random.normal(-1, 1.5, 1000)
]
output_dir = batch_process_data(data_list)

格式转换

def convert_plot_formats(input_file, output_formats):
    """
    转换图形格式
    
    参数:
        input_file: 输入文件
        output_formats: 输出格式列表
    """
    # 读取图形
    fig = plt.imread(input_file)
    
    # 转换为不同格式
    for fmt in output_formats:
        output_file = input_file.rsplit('.', 1)[0] + '.' + fmt
        plt.imsave(output_file, fig, format=fmt)
    
    return output_formats

# 使用示例
formats = ['png', 'jpg', 'pdf', 'svg']
converted_files = convert_plot_formats('input.png', formats)

总结

实际应用部分涵盖了:

  1. 数据分析可视化(时间序列分析、统计分析、地理数据可视化)
  2. 科学计算可视化(数学函数、物理模拟、工程计算)
  3. 交互式应用(数据探索、参数调整、实时更新)
  4. 报告生成(自动报告、批量处理、格式转换)

掌握这些实际应用对于提高 Matplotlib 的实用性至关重要,它可以帮助我们:

  • 进行数据分析和可视化
  • 展示科学计算结果
  • 创建交互式应用
  • 生成专业报告

建议在实际项目中注意:

  • 选择合适的可视化方法
  • 注重交互性
  • 优化性能
  • 保持代码可维护性
  • 考虑用户体验
  • 注意数据安全

你可能感兴趣的:(AI,Study,人工智能,matplotlib,ai,python)