|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1. 引言
Matplotlib是Python中最流行的数据可视化库之一,它为Python提供了强大的绘图功能,能够生成各种静态、动态和交互式的图表。作为Python数据科学生态系统的核心组件,Matplotlib与NumPy、Pandas等库紧密集成,成为数据分析师和科学家不可或缺的工具。
本教程将带您从Matplotlib的基础知识开始,逐步深入到高级数据可视化技术,帮助您掌握使用Matplotlib进行数据分析可视化的全面技能。
2. Matplotlib基础
2.1 安装和导入
在开始使用Matplotlib之前,首先需要安装该库。可以使用pip进行安装:
安装完成后,在Python脚本或Jupyter Notebook中导入Matplotlib:
- import matplotlib.pyplot as plt
- import numpy as np
复制代码
通常,我们也会导入NumPy,因为它提供了强大的数组操作功能,与Matplotlib配合使用非常方便。
2.2 Matplotlib的基本概念
Matplotlib的核心概念是Figure(图形)和Axes(坐标系)。
• Figure:整个图形窗口,可以包含一个或多个Axes。
• Axes:实际的绘图区域,包含坐标轴、标题、标签等。
创建一个简单的Figure和Axes:
- # 创建一个Figure和一个Axes
- fig, ax = plt.subplots()
- # 显示图形
- plt.show()
复制代码
2.3 第一个简单图表
让我们创建一个简单的线图:
- # 准备数据
- x = np.linspace(0, 10, 100)
- y = np.sin(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制线图
- ax.plot(x, y)
- # 显示图形
- plt.show()
复制代码
这段代码将生成一个简单的正弦波图表。
3. 基础绘图
3.1 线图
线图是最基本的图表类型,适合展示数据随时间或连续变量的变化趋势。
- # 准备数据
- x = np.linspace(0, 10, 100)
- y1 = np.sin(x)
- y2 = np.cos(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制两条线
- ax.plot(x, y1, label='sin(x)')
- ax.plot(x, y2, label='cos(x)')
- # 添加图例
- ax.legend()
- # 添加标题和标签
- ax.set_title('三角函数')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 显示图形
- plt.show()
复制代码
3.2 散点图
散点图适合展示两个变量之间的关系。
- # 生成随机数据
- np.random.seed(42)
- x = np.random.randn(100)
- y = x + np.random.randn(100) * 0.5
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制散点图
- ax.scatter(x, y, alpha=0.6)
- # 添加标题和标签
- ax.set_title('散点图示例')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 显示图形
- plt.show()
复制代码
3.3 柱状图
柱状图适合比较不同类别的数据。
- # 准备数据
- categories = ['A', 'B', 'C', 'D', 'E']
- values = [7, 12, 4, 8, 15]
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制柱状图
- ax.bar(categories, values)
- # 添加标题和标签
- ax.set_title('柱状图示例')
- ax.set_xlabel('类别')
- ax.set_ylabel('值')
- # 显示图形
- plt.show()
复制代码
3.4 饼图
饼图适合展示各部分占整体的比例。
- # 准备数据
- sizes = [15, 30, 45, 10]
- labels = ['A', 'B', 'C', 'D']
- explode = (0, 0.1, 0, 0) # 突出第二块
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制饼图
- ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
- shadow=True, startangle=90)
- # 确保饼图是圆形的
- ax.axis('equal')
- # 添加标题
- ax.set_title('饼图示例')
- # 显示图形
- plt.show()
复制代码
4. 图表定制
4.1 颜色、线型和标记
Matplotlib提供了丰富的选项来自定义图表的外观。
- # 准备数据
- x = np.linspace(0, 10, 20)
- y1 = np.sin(x)
- y2 = np.cos(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制不同样式的线
- ax.plot(x, y1, 'r--', label='sin(x)') # 红色虚线
- ax.plot(x, y2, 'b-o', label='cos(x)') # 蓝色实线带圆点标记
- # 添加图例
- ax.legend()
- # 添加标题和标签
- ax.set_title('自定义线型和标记')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 显示图形
- plt.show()
复制代码
4.2 文本和注释
可以在图表中添加文本和注释来强调重要信息。
- # 准备数据
- x = np.linspace(0, 10, 100)
- y = np.sin(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制线图
- ax.plot(x, y)
- # 添加标题和标签
- ax.set_title('正弦波')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 添加文本
- ax.text(5, 0.5, '正弦波', fontsize=12)
- # 添加注释
- ax.annotate('最大值', xy=(np.pi/2, 1), xytext=(3, 0.5),
- arrowprops=dict(facecolor='black', shrink=0.05))
- # 显示图形
- plt.show()
复制代码
4.3 坐标轴设置
可以自定义坐标轴的范围、刻度和标签。
- # 准备数据
- x = np.linspace(0, 10, 100)
- y = np.sin(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots()
- # 绘制线图
- ax.plot(x, y)
- # 设置坐标轴范围
- ax.set_xlim(0, 10)
- ax.set_ylim(-1.5, 1.5)
- # 设置坐标轴刻度
- ax.set_xticks(np.arange(0, 11, 2))
- ax.set_yticks(np.arange(-1.5, 2, 0.5))
- # 设置坐标轴标签
- ax.set_xticklabels(['0', '2π', '4π', '6π', '8π', '10π'])
- ax.set_yticklabels(['-1.5', '-1.0', '-0.5', '0.0', '0.5', '1.0', '1.5'])
- # 添加标题和标签
- ax.set_title('自定义坐标轴')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 显示图形
- plt.show()
复制代码
5. 多子图绘制
5.1 使用subplots创建多个子图
- # 准备数据
- x = np.linspace(0, 10, 100)
- y1 = np.sin(x)
- y2 = np.cos(x)
- y3 = np.tan(x)
- y4 = np.exp(x/10)
- # 创建2x2的子图网格
- fig, axs = plt.subplots(2, 2, figsize=(12, 10))
- # 在第一个子图中绘制正弦波
- axs[0, 0].plot(x, y1)
- axs[0, 0].set_title('sin(x)')
- # 在第二个子图中绘制余弦波
- axs[0, 1].plot(x, y2)
- axs[0, 1].set_title('cos(x)')
- # 在第三个子图中绘制正切波
- axs[1, 0].plot(x, y3)
- axs[1, 0].set_title('tan(x)')
- axs[1, 0].set_ylim(-5, 5) # 限制y轴范围,因为tan(x)在某些点趋向无穷大
- # 在第四个子图中绘制指数函数
- axs[1, 1].plot(x, y4)
- axs[1, 1].set_title('exp(x/10)')
- # 调整子图间距
- plt.tight_layout()
- # 显示图形
- plt.show()
复制代码
5.2 使用GridSpec创建复杂的子图布局
- # 导入GridSpec
- from matplotlib.gridspec import GridSpec
- # 准备数据
- x = np.linspace(0, 10, 100)
- y1 = np.sin(x)
- y2 = np.cos(x)
- y3 = np.sin(x) * np.cos(x)
- # 创建Figure和GridSpec
- fig = plt.figure(figsize=(12, 8))
- gs = GridSpec(3, 2, figure=fig)
- # 创建不同大小的子图
- ax1 = fig.add_subplot(gs[0, 0]) # 第一行第一列
- ax2 = fig.add_subplot(gs[0, 1]) # 第一行第二列
- ax3 = fig.add_subplot(gs[1:, :]) # 占据剩余所有行和所有列
- # 在子图中绘制数据
- ax1.plot(x, y1)
- ax1.set_title('sin(x)')
- ax2.plot(x, y2)
- ax2.set_title('cos(x)')
- ax3.plot(x, y3)
- ax3.set_title('sin(x) * cos(x)')
- # 调整子图间距
- plt.tight_layout()
- # 显示图形
- plt.show()
复制代码
5.3 共享坐标轴
- # 准备数据
- x = np.linspace(0, 10, 100)
- y1 = np.sin(x)
- y2 = np.cos(x)
- # 创建共享x轴的子图
- fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(10, 8))
- # 在第一个子图中绘制正弦波
- ax1.plot(x, y1)
- ax1.set_title('sin(x)')
- # 在第二个子图中绘制余弦波
- ax2.plot(x, y2)
- ax2.set_title('cos(x)')
- # 设置x轴标签
- ax2.set_xlabel('x')
- # 调整子图间距
- plt.tight_layout()
- # 显示图形
- plt.show()
复制代码
6. 高级图表类型
6.1 热图
热图适合展示矩阵数据或二维分布。
- # 生成随机数据
- data = np.random.randn(10, 10)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(8, 6))
- # 绘制热图
- im = ax.imshow(data, cmap='coolwarm')
- # 添加颜色条
- cbar = fig.colorbar(im, ax=ax)
- # 设置标题
- ax.set_title('热图示例')
- # 显示图形
- plt.show()
复制代码
6.2 等高线图
等高线图适合展示三维数据的二维投影。
- # 创建网格数据
- x = np.linspace(-3.0, 3.0, 100)
- y = np.linspace(-3.0, 3.0, 100)
- X, Y = np.meshgrid(x, y)
- # 计算Z值
- Z = np.exp(-(X**2 + Y**2))
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(8, 6))
- # 绘制等高线图
- contour = ax.contour(X, Y, Z, cmap='viridis')
- # 添加等高线标签
- ax.clabel(contour, inline=True, fontsize=8)
- # 设置标题
- ax.set_title('等高线图示例')
- # 显示图形
- plt.show()
复制代码
6.3 3D图
Matplotlib也支持创建3D图表。
- # 导入3D绘图工具
- from mpl_toolkits.mplot3d import Axes3D
- # 创建网格数据
- x = np.linspace(-5, 5, 50)
- y = np.linspace(-5, 5, 50)
- X, Y = np.meshgrid(x, y)
- # 计算Z值
- Z = np.sin(np.sqrt(X**2 + Y**2))
- # 创建Figure和3D Axes
- fig = plt.figure(figsize=(10, 8))
- ax = fig.add_subplot(111, projection='3d')
- # 绘制3D表面图
- surf = ax.plot_surface(X, Y, Z, cmap='viridis')
- # 添加颜色条
- fig.colorbar(surf, ax=ax, shrink=0.5, aspect=5)
- # 设置标题和标签
- ax.set_title('3D表面图示例')
- ax.set_xlabel('X')
- ax.set_ylabel('Y')
- ax.set_zlabel('Z')
- # 显示图形
- plt.show()
复制代码
7. 统计图表
7.1 直方图
直方图适合展示数据的分布情况。
- # 生成随机数据
- np.random.seed(42)
- data = np.random.normal(0, 1, 1000)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 绘制直方图
- ax.hist(data, bins=30, density=True, alpha=0.7, color='blue')
- # 添加核密度估计曲线
- from scipy.stats import gaussian_kde
- kde = gaussian_kde(data)
- x_range = np.linspace(min(data), max(data), 100)
- ax.plot(x_range, kde(x_range), 'r-', linewidth=2)
- # 添加标题和标签
- ax.set_title('直方图与核密度估计')
- ax.set_xlabel('值')
- ax.set_ylabel('密度')
- # 显示图形
- plt.show()
复制代码
7.2 箱线图
箱线图适合展示数据的分布和异常值。
- # 生成随机数据
- np.random.seed(42)
- data1 = np.random.normal(0, 1, 100)
- data2 = np.random.normal(1, 1.5, 100)
- data3 = np.random.normal(-1, 0.5, 100)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 绘制箱线图
- ax.boxplot([data1, data2, data3], labels=['组1', '组2', '组3'])
- # 添加标题
- ax.set_title('箱线图示例')
- # 显示图形
- plt.show()
复制代码
7.3 小提琴图
小提琴图结合了箱线图和核密度估计的优点。
- # 生成随机数据
- np.random.seed(42)
- data1 = np.random.normal(0, 1, 100)
- data2 = np.random.normal(1, 1.5, 100)
- data3 = np.random.normal(-1, 0.5, 100)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 绘制小提琴图
- ax.violinplot([data1, data2, data3], showmeans=True, showmedians=True)
- # 设置x轴标签
- ax.set_xticks([1, 2, 3])
- ax.set_xticklabels(['组1', '组2', '组3'])
- # 添加标题
- ax.set_title('小提琴图示例')
- # 显示图形
- plt.show()
复制代码
8. 交互式图表
8.1 使用matplotlib.widgets创建交互式控件
- # 导入必要的模块
- import matplotlib.pyplot as plt
- import numpy as np
- from matplotlib.widgets import Slider, Button
- # 创建初始数据
- x = np.linspace(0, 10, 1000)
- y = np.sin(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- plt.subplots_adjust(bottom=0.25) # 为滑块留出空间
- # 绘制初始线图
- line, = ax.plot(x, y, lw=2)
- # 设置坐标轴范围
- ax.set_xlim(0, 10)
- ax.set_ylim(-1.5, 1.5)
- # 添加标题和标签
- ax.set_title('交互式正弦波')
- ax.set_xlabel('x')
- ax.set_ylabel('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.0)
- amp_slider = Slider(ax_amp, '振幅', 0.1, 2.0, valinit=1.0)
- # 定义更新函数
- 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)
- # 创建重置按钮
- resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
- button = Button(resetax, '重置')
- # 定义重置函数
- def reset(event):
- freq_slider.reset()
- amp_slider.reset()
- # 注册重置函数
- button.on_clicked(reset)
- # 显示图形
- plt.show()
复制代码
8.2 使用mplcursors创建交互式数据提示
- # 安装mplcursors(如果尚未安装)
- # pip install mplcursors
- import matplotlib.pyplot as plt
- import numpy as np
- import mplcursors
- # 生成随机数据
- np.random.seed(42)
- x = np.arange(10)
- y = np.random.rand(10)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 绘制散点图
- scatter = ax.scatter(x, y)
- # 添加标题和标签
- ax.set_title('交互式散点图')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 添加光标交互
- cursor = mplcursors.cursor(scatter, hover=True)
- # 显示图形
- plt.show()
复制代码
9. 动画
9.1 使用FuncAnimation创建简单动画
- # 导入必要的模块
- import matplotlib.pyplot as plt
- import numpy as np
- from matplotlib.animation import FuncAnimation
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 设置坐标轴范围
- ax.set_xlim(0, 10)
- ax.set_ylim(-1.5, 1.5)
- # 添加标题和标签
- ax.set_title('正弦波动画')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 创建线对象
- line, = ax.plot([], [], lw=2)
- # 初始化函数
- def init():
- line.set_data([], [])
- return line,
- # 更新函数
- def update(frame):
- x = np.linspace(0, 10, 1000)
- y = np.sin(2 * np.pi * (x - 0.1 * frame))
- line.set_data(x, y)
- return line,
- # 创建动画
- ani = FuncAnimation(fig, update, frames=100, init_func=init,
- blit=True, interval=50)
- # 显示动画
- plt.show()
复制代码
9.2 保存动画
- # 导入必要的模块
- import matplotlib.pyplot as plt
- import numpy as np
- from matplotlib.animation import FuncAnimation, PillowWriter
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 设置坐标轴范围
- ax.set_xlim(0, 10)
- ax.set_ylim(-1.5, 1.5)
- # 添加标题和标签
- ax.set_title('正弦波动画')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 创建线对象
- line, = ax.plot([], [], lw=2)
- # 初始化函数
- def init():
- line.set_data([], [])
- return line,
- # 更新函数
- def update(frame):
- x = np.linspace(0, 10, 1000)
- y = np.sin(2 * np.pi * (x - 0.1 * frame))
- line.set_data(x, y)
- return line,
- # 创建动画
- ani = FuncAnimation(fig, update, frames=100, init_func=init,
- blit=True, interval=50)
- # 保存动画为GIF
- writer = PillowWriter(fps=20)
- ani.save('sine_wave.gif', writer=writer)
- # 显示动画
- plt.show()
复制代码
10. 与其他库的集成
10.1 与Pandas集成
Matplotlib与Pandas数据框无缝集成,可以直接使用Pandas数据框进行绘图。
- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
- # 创建Pandas数据框
- np.random.seed(42)
- dates = pd.date_range('20230101', periods=100)
- data = pd.DataFrame({
- 'A': np.random.randn(100).cumsum(),
- 'B': np.random.randn(100).cumsum(),
- 'C': np.random.randn(100).cumsum()
- }, index=dates)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(12, 6))
- # 使用Pandas的plot方法
- data.plot(ax=ax)
- # 添加标题和标签
- ax.set_title('Pandas数据框绘图')
- ax.set_xlabel('日期')
- ax.set_ylabel('值')
- # 显示图形
- plt.show()
复制代码
10.2 与Seaborn集成
Seaborn是基于Matplotlib的高级可视化库,可以与Matplotlib结合使用。
- import seaborn as sns
- import matplotlib.pyplot as plt
- import numpy as np
- import pandas as pd
- # 创建示例数据
- np.random.seed(42)
- data = pd.DataFrame({
- 'x': np.random.randn(100),
- 'y': np.random.randn(100),
- 'category': np.random.choice(['A', 'B', 'C'], 100)
- })
- # 创建Figure和Axes
- fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
- # 使用Seaborn绘制散点图
- sns.scatterplot(x='x', y='y', hue='category', data=data, ax=ax1)
- ax1.set_title('Seaborn散点图')
- # 使用Seaborn绘制箱线图
- sns.boxplot(x='category', y='y', data=data, ax=ax2)
- ax2.set_title('Seaborn箱线图')
- # 调整子图间距
- plt.tight_layout()
- # 显示图形
- plt.show()
复制代码
11. 最佳实践和技巧
11.1 选择合适的图表类型
不同的数据类型和分析目标需要不同的图表类型:
• 时间序列数据:线图
• 比较类别:柱状图、饼图
• 显示分布:直方图、箱线图、小提琴图
• 显示关系:散点图、热图
• 显示组成:堆叠柱状图、饼图
11.2 颜色选择
选择合适的颜色方案可以提高图表的可读性和美观度:
- import matplotlib.pyplot as plt
- import numpy as np
- import matplotlib.colors as mcolors
- # 创建示例数据
- x = np.linspace(0, 10, 100)
- y1 = np.sin(x)
- y2 = np.cos(x)
- y3 = np.sin(x) * np.cos(x)
- # 创建Figure和Axes
- fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
- # 使用默认颜色
- ax1.plot(x, y1, label='sin(x)')
- ax1.plot(x, y2, label='cos(x)')
- ax1.plot(x, y3, label='sin(x)*cos(x)')
- ax1.set_title('默认颜色')
- ax1.legend()
- # 使用自定义颜色
- colors = ['#1f77b4', '#ff7f0e', '#2ca02c'] # 使用十六进制颜色代码
- ax2.plot(x, y1, color=colors[0], label='sin(x)')
- ax2.plot(x, y2, color=colors[1], label='cos(x)')
- ax2.plot(x, y3, color=colors[2], label='sin(x)*cos(x)')
- ax2.set_title('自定义颜色')
- ax2.legend()
- # 显示图形
- plt.show()
复制代码
11.3 图表布局和排版
良好的布局和排版可以使图表更加清晰和专业:
- import matplotlib.pyplot as plt
- import numpy as np
- from matplotlib.gridspec import GridSpec
- # 创建示例数据
- x = np.linspace(0, 10, 100)
- y1 = np.sin(x)
- y2 = np.cos(x)
- categories = ['A', 'B', 'C', 'D']
- values = [7, 12, 4, 8]
- # 创建Figure和GridSpec
- fig = plt.figure(figsize=(15, 10))
- gs = GridSpec(2, 2, figure=fig, width_ratios=[2, 1], height_ratios=[2, 1])
- # 创建子图
- ax1 = fig.add_subplot(gs[0, 0]) # 大图
- ax2 = fig.add_subplot(gs[0, 1]) # 小图
- ax3 = fig.add_subplot(gs[1, :]) # 底部宽图
- # 在第一个子图中绘制正弦波和余弦波
- ax1.plot(x, y1, label='sin(x)')
- ax1.plot(x, y2, label='cos(x)')
- ax1.set_title('三角函数')
- ax1.legend()
- # 在第二个子图中绘制柱状图
- ax2.bar(categories, values)
- ax2.set_title('柱状图')
- # 在第三个子图中绘制正弦波和余弦波的乘积
- ax3.plot(x, y1 * y2, label='sin(x)*cos(x)')
- ax3.set_title('乘积函数')
- ax3.legend()
- # 添加总标题
- fig.suptitle('多子图布局示例', fontsize=16)
- # 调整子图间距
- plt.tight_layout(rect=[0, 0, 1, 0.96]) # 为总标题留出空间
- # 显示图形
- plt.show()
复制代码
11.4 导出高质量图像
Matplotlib支持多种图像格式,可以根据需要选择合适的格式和分辨率:
- import matplotlib.pyplot as plt
- import numpy as np
- # 创建示例数据
- x = np.linspace(0, 10, 100)
- y = np.sin(x)
- # 创建Figure和Axes
- fig, ax = plt.subplots(figsize=(10, 6))
- # 绘制线图
- ax.plot(x, y)
- # 添加标题和标签
- ax.set_title('正弦波')
- ax.set_xlabel('x')
- ax.set_ylabel('y')
- # 保存为PNG格式(高分辨率)
- plt.savefig('sine_wave.png', dpi=300, bbox_inches='tight')
- # 保存为PDF格式(矢量图,适合出版)
- plt.savefig('sine_wave.pdf', bbox_inches='tight')
- # 保存为SVG格式(矢量图,适合网页)
- plt.savefig('sine_wave.svg', bbox_inches='tight')
- # 显示图形
- plt.show()
复制代码
12. 实际案例
12.1 分析销售数据
- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
- import seaborn as sns
- # 创建示例销售数据
- np.random.seed(42)
- dates = pd.date_range('20220101', periods=365)
- products = ['A', 'B', 'C', 'D']
- regions = ['North', 'South', 'East', 'West']
- # 生成随机销售数据
- data = []
- for date in dates:
- for product in products:
- for region in regions:
- base_sales = np.random.randint(100, 500)
- seasonal_factor = 1 + 0.2 * np.sin(2 * np.pi * (date.dayofyear / 365))
- sales = int(base_sales * seasonal_factor)
- data.append([date, product, region, sales])
- # 创建数据框
- df = pd.DataFrame(data, columns=['Date', 'Product', 'Region', 'Sales'])
- # 按日期汇总销售数据
- daily_sales = df.groupby('Date')['Sales'].sum().reset_index()
- # 创建Figure和Axes
- fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12))
- # 绘制销售趋势图
- ax1.plot(daily_sales['Date'], daily_sales['Sales'])
- ax1.set_title('每日销售趋势')
- ax1.set_xlabel('日期')
- ax1.set_ylabel('销售额')
- ax1.grid(True)
- # 按产品和地区汇总销售数据
- product_sales = df.groupby('Product')['Sales'].sum()
- region_sales = df.groupby('Region')['Sales'].sum()
- # 绘制产品销售饼图
- ax2.pie(product_sales, labels=product_sales.index, autopct='%1.1f%%')
- ax2.set_title('产品销售占比')
- # 调整子图间距
- plt.tight_layout()
- # 显示图形
- plt.show()
- # 创建另一个图来比较不同地区的销售情况
- fig, ax = plt.subplots(figsize=(12, 6))
- # 创建透视表
- pivot_df = df.pivot_table(index='Date', columns='Region', values='Sales', aggfunc='sum')
- # 绘制各地区销售趋势
- for region in regions:
- ax.plot(pivot_df.index, pivot_df[region], label=region)
- # 添加标题和标签
- ax.set_title('各地区销售趋势比较')
- ax.set_xlabel('日期')
- ax.set_ylabel('销售额')
- ax.legend()
- # 显示图形
- plt.show()
复制代码
12.2 分析金融数据
- import pandas as pd
- import matplotlib.pyplot as plt
- import numpy as np
- import yfinance as yf # 需要安装:pip install yfinance
- # 下载股票数据
- tickers = ['AAPL', 'MSFT', 'GOOG', 'AMZN']
- start_date = '2020-01-01'
- end_date = '2023-01-01'
- data = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
- # 计算日收益率
- returns = data.pct_change().dropna()
- # 创建Figure和Axes
- fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12))
- # 绘制股票价格走势
- for ticker in tickers:
- ax1.plot(data.index, data[ticker], label=ticker)
- # 添加标题和标签
- ax1.set_title('股票价格走势')
- ax1.set_xlabel('日期')
- ax1.set_ylabel('价格')
- ax1.legend()
- ax1.grid(True)
- # 绘制收益率分布
- for ticker in tickers:
- ax2.hist(returns[ticker], bins=50, alpha=0.5, label=ticker)
- # 添加标题和标签
- ax2.set_title('收益率分布')
- ax2.set_xlabel('日收益率')
- ax2.set_ylabel('频数')
- ax2.legend()
- # 调整子图间距
- plt.tight_layout()
- # 显示图形
- plt.show()
- # 创建另一个图来显示相关性热图
- fig, ax = plt.subplots(figsize=(10, 8))
- # 计算相关系数矩阵
- corr_matrix = returns.corr()
- # 绘制热图
- im = ax.imshow(corr_matrix, cmap='coolwarm')
- # 设置刻度标签
- ax.set_xticks(np.arange(len(tickers)))
- ax.set_yticks(np.arange(len(tickers)))
- ax.set_xticklabels(tickers)
- ax.set_yticklabels(tickers)
- # 在热图上显示相关系数
- for i in range(len(tickers)):
- for j in range(len(tickers)):
- text = ax.text(j, i, f'{corr_matrix.iloc[i, j]:.2f}',
- ha="center", va="center", color="black")
- # 添加标题
- ax.set_title('股票收益率相关性热图')
- # 添加颜色条
- cbar = fig.colorbar(im, ax=ax)
- # 显示图形
- plt.show()
复制代码
13. 总结
Matplotlib是Python数据科学生态系统中不可或缺的可视化工具,它提供了从基础绘图到高级数据可视化的全面功能。通过本教程,我们学习了:
1. Matplotlib的基础概念和使用方法
2. 各种基础图表类型的创建和定制
3. 多子图的创建和布局
4. 高级图表类型,如热图、等高线图和3D图
5. 统计图表,如直方图、箱线图和小提琴图
6. 交互式图表的创建
7. 动画的制作和保存
8. 与Pandas和Seaborn等其他库的集成
9. 数据可视化的最佳实践和技巧
10. 实际案例分析
要进一步掌握Matplotlib,建议:
1. 多练习不同类型的图表创建
2. 阅读Matplotlib官方文档和示例
3. 尝试解决真实的数据分析问题
4. 学习更高级的可视化技术,如地理空间可视化
5. 探索Matplotlib的扩展库,如mpld3(交互式3D图表)
随着数据科学和人工智能的发展,数据可视化变得越来越重要。掌握Matplotlib将帮助您更好地理解和传达数据中的洞察,为您的数据分析工作增添强大的视觉表达能力。 |
|