本文详细介绍 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)
实际应用部分涵盖了:
掌握这些实际应用对于提高 Matplotlib 的实用性至关重要,它可以帮助我们:
建议在实际项目中注意: