Matplotlib数据可视化实战:Matplotlib子图布局与管理入门

Matplotlib多子图布局实战

学习目标

通过本课程的学习,学员将掌握如何在Matplotlib中创建和管理多个子图,了解子图布局的基本原理和调整方法,能够有效地展示多个数据集,提升数据可视化的效果。

相关知识点

  • Matplotlib子图

学习内容

1 Matplotlib子图

1.1 创建子图

在数据可视化中,经常需要在一个画布上展示多个数据集,这时就需要使用到子图。Matplotlib提供了多种创建子图的方法,其中最常用的是plt.subplots()函数。这个函数可以一次性创建一个画布和多个子图,并返回一个包含所有子图的数组,使得管理和操作子图变得非常方便。

1.1.1理论知识

plt.subplots()函数的基本语法如下:

python 复制代码
%pip install matplotlib
%pip install mplcursors
python 复制代码
fig, axs = plt.subplots(nrows, ncols, sharex=False, sharey=False, figsize=(8, 6))
  • nrowsncols分别指定了子图的行数和列数。
  • sharexsharey参数用于控制子图之间是否共享x轴或y轴,这对于需要比较不同数据集的图表非常有用。
  • figsize参数用于设置整个画布的大小,单位为英寸。
1.1.2 实践代码

下面的代码示例展示了如何使用plt.subplots()创建一个2x2的子图布局,并在每个子图中绘制不同的数据。

python 复制代码
import matplotlib.pyplot as plt
import numpy as np

# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
y3 = np.tan(x)
y4 = np.log(x)

# 创建2x2的子图布局
fig, axs = plt.subplots(2, 2, figsize=(10, 8))

# 绘制子图
axs[0, 0].plot(x, y1, 'r')  # 第一个子图
axs[0, 0].set_title('Sine Wave')
axs[0, 1].plot(x, y2, 'g')  # 第二个子图
axs[0, 1].set_title('Cosine Wave')
axs[1, 0].plot(x, y3, 'b')  # 第三个子图
axs[1, 0].set_title('Tangent Wave')
axs[1, 1].plot(x, y4, 'm')  # 第四个子图
axs[1, 1].set_title('Logarithmic Wave')

# 调整布局
plt.tight_layout()

# 显示图表
plt.show()
1.2 子图布局调整

虽然plt.subplots()函数提供了一个方便的默认布局,但在实际应用中,可能需要对子图的布局进行更精细的调整,以适应不同的数据展示需求。Matplotlib提供了多种方法来调整子图的布局,包括使用plt.subplots_adjust()函数和GridSpec对象。

1.2.1理论知识
  • plt.subplots_adjust()函数允许手动调整子图之间的间距,包括左、右、上、下边距以及子图之间的水平和垂直间距。
  • GridSpec对象提供了一种更灵活的方式来定义子图的布局,可以指定每个子图在画布上的具体位置和大小。
1.2.2 实践代码

下面的代码示例展示了如何使用plt.subplots_adjust()GridSpec来调整子图的布局。

python 复制代码
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 使用plt.subplots_adjust()调整布局
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
axs[0, 0].plot(x, y1, 'r')
axs[0, 1].plot(x, y2, 'g')
axs[1, 0].plot(x, y1, 'b')
axs[1, 1].plot(x, y2, 'm')

# 调整子图间距
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1, wspace=0.4, hspace=0.4)

# 使用GridSpec调整布局
fig = plt.figure(figsize=(10, 8))
gs = gridspec.GridSpec(2, 2, width_ratios=[1, 2], height_ratios=[1, 2])

ax1 = plt.subplot(gs[0, 0])
ax1.plot(x, y1, 'r')
ax1.set_title('Sine Wave')

ax2 = plt.subplot(gs[0, 1])
ax2.plot(x, y2, 'g')
ax2.set_title('Cosine Wave')

ax3 = plt.subplot(gs[1, 0])
ax3.plot(x, y1, 'b')
ax3.set_title('Sine Wave')

ax4 = plt.subplot(gs[1, 1])
ax4.plot(x, y2, 'm')
ax4.set_title('Cosine Wave')

# 显示图表
plt.show()
1.3 子图间的交互

在某些情况下,可能需要在多个子图之间实现交互,例如,当鼠标悬停在一个子图上的某个数据点时,其他子图中的相应数据点也会高亮显示。Matplotlib提供了mplcursors库来实现这种交互效果。

1.3.1理论知识

mplcursors库是一个第三方库,可以与Matplotlib结合使用,实现图表的交互功能。通过mplcursors.cursor()函数,可以为图表添加交互式注释,当鼠标悬停在数据点上时,会显示该点的详细信息。

1.3.2 实践代码

下面的代码示例展示了如何使用mplcursors库在多个子图之间实现交互。

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
import mplcursors

# 创建数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 创建2x2子图
fig, axs = plt.subplots(2, 2, figsize=(10, 8))
lines = []

# 绘制各子图
lines.append(axs[0, 0].plot(x, y1, 'r.-', label='Sine Wave 1')[0])
lines.append(axs[0, 1].plot(x, y2, 'g.-', label='Cosine Wave 1')[0])
lines.append(axs[1, 0].plot(x, y1, 'b.-', label='Sine Wave 2')[0])
lines.append(axs[1, 1].plot(x, y2, 'm.-', label='Cosine Wave 2')[0])

# 设置标题和图例
axs[0, 0].set_title('Sine Wave 1')
axs[0, 0].legend()
axs[0, 1].set_title('Cosine Wave 1')
axs[0, 1].legend()
axs[1, 0].set_title('Sine Wave 2')
axs[1, 0].legend()
axs[1, 1].set_title('Cosine Wave 2')
axs[1, 1].legend()

fig.tight_layout()

# 创建交互光标
cursor = mplcursors.cursor(lines, hover=True)

@cursor.connect("add")
def on_add(sel):
    # 获取悬停点的x坐标并找到对应的数据索引
    hover_x_coord = sel.target[0]
    actual_data_index = np.argmin(np.abs(x - hover_x_coord))
    
    # 设置注释文本
    current_y_value = sel.artist.get_ydata()[actual_data_index]
    text_content = (f'{sel.artist.get_label()}\n'
                   f'x = {x[actual_data_index]:.2f}\n'
                   f'y = {current_y_value:.2f}')
    sel.annotation.set_text(text_content)
    
    # 在所有子图中高亮对应点
    for ax_plot in axs.flat:
        if ax_plot.lines:
            line_in_ax = ax_plot.lines[0]
            line_in_ax.set_marker('o')
            line_in_ax.set_markersize(12)
            line_in_ax.set_markevery([actual_data_index])
    
    fig.canvas.draw_idle()

plt.show()
相关推荐
你知道网上冲浪吗1 分钟前
【原创理论】Stochastic Coupled Dyadic System (SCDS):一个用于两性关系动力学建模的随机耦合系统框架
python·算法·数学建模·数值分析
钢铁男儿5 分钟前
Python 正则表达式核心元字符全解析
python
杨荧31 分钟前
基于Python的宠物服务管理系统 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python·信息可视化
CodeCraft Studio1 小时前
在 Python 中操作 Excel 文件的高效方案 —— Aspose.Cells for Python
python·ui·excel·报表·aspose·aspose.cells
l1t1 小时前
利用DeepSeek辅助WPS电子表格ET格式分析
人工智能·python·wps·插件·duckdb
WSSWWWSSW2 小时前
Matplotlib数据可视化实战:Matplotlib图表美化与进阶教程
python·信息可视化·matplotlib
mftang2 小时前
Python可视化工具-Bokeh:动态显示数据
开发语言·python
Seeklike2 小时前
diffuxers学习--AutoPipeline
人工智能·python·stable diffusion·diffusers
前端小趴菜052 小时前
python - 数据类型
python