Matplotlib 图形大小和子图布局:全面指南

Matplotlib 图形大小和子图布局:全面指南

参考:matplotlib figure size subplots

MatplotlibPython 中最流行的数据可视化库之一,它提供了强大而灵活的工具来创建各种类型的图表和绘图。在使用 Matplotlib 时,了解如何控制图形大小和创建子图布局是非常重要的。本文将深入探讨 Matplotlib 中的 figure size 和 subplots 概念,帮助你更好地掌握这些关键技术。

1. 图形大小(Figure Size)

在 Matplotlib 中,图形大小指的是整个图形(Figure)的尺寸。控制图形大小对于创建美观、易读的可视化效果至关重要。

1.1 设置图形大小

最常用的设置图形大小的方法是使用 plt.figure() 函数的 figsize 参数。这个参数接受一个元组,表示宽度和高度(以英寸为单位)。

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
plt.title("How2matplotlib.com - Figure Size Example")
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

在这个例子中,我们创建了一个宽 10 英寸、高 6 英寸的图形。figsize=(10, 6) 参数设置了图形的大小。

1.2 动态调整图形大小

有时,我们可能需要根据数据或其他条件动态调整图形大小。以下是一个示例:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.randn(100, 5)
num_columns = data.shape[1]

# 动态设置图形大小
fig_width = 2 * num_columns  # 每列 2 英寸宽
fig_height = 6  # 固定高度为 6 英寸

plt.figure(figsize=(fig_width, fig_height))
plt.boxplot(data)
plt.title("How2matplotlib.com - Dynamic Figure Size")
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子中,我们根据数据的列数动态设置图形的宽度,使每个箱线图有足够的空间显示。

1.3 保存特定大小的图形

当保存图形时,我们也可以指定输出文件的大小:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.figure(figsize=(8, 4))
plt.plot(x, y)
plt.title("How2matplotlib.com - Saving Specific Size")
plt.savefig('sine_wave.png', dpi=300, bbox_inches='tight')
plt.close()

这里,我们创建了一个 8×4 英寸的图形,并以 300 DPI 的分辨率保存为 PNG 文件。bbox_inches='tight' 参数确保图形被紧密裁剪,不留多余的空白。

2. 子图(Subplots)

子图允许在一个图形中创建多个相关的图表。这对于比较不同数据集或展示数据的不同方面非常有用。

2.1 创建基本子图

最简单的创建子图的方法是使用 plt.subplot() 函数:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)

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

plt.subplot(131)
plt.plot(x, np.sin(x))
plt.title("How2matplotlib.com - Sin")

plt.subplot(132)
plt.plot(x, np.cos(x))
plt.title("How2matplotlib.com - Cos")

plt.subplot(133)
plt.plot(x, np.tan(x))
plt.title("How2matplotlib.com - Tan")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子创建了一个包含三个子图的图形,分别显示正弦、余弦和正切函数。plt.subplot(131) 表示创建一个 1 行 3 列的子图布局,并选择第一个子图。

2.2 使用 plt.subplots() 函数

plt.subplots() 函数提供了一种更方便的方式来创建子图网格:

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(10, 8))
x = np.linspace(0, 5, 100)

axs[0, 0].plot(x, x)
axs[0, 0].set_title("How2matplotlib.com - Linear")

axs[0, 1].plot(x, x**2)
axs[0, 1].set_title("How2matplotlib.com - Quadratic")

axs[1, 0].plot(x, np.sqrt(x))
axs[1, 0].set_title("How2matplotlib.com - Square Root")

axs[1, 1].plot(x, np.exp(x))
axs[1, 1].set_title("How2matplotlib.com - Exponential")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子创建了一个 2×2 的子图网格,每个子图显示不同的数学函数。

2.3 不规则子图布局

有时,我们可能需要创建不规则的子图布局。gridspec 模块提供了更灵活的布局选项:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

fig = plt.figure(figsize=(12, 8))
gs = gridspec.GridSpec(3, 3)

ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :-1])
ax3 = fig.add_subplot(gs[1:, -1])
ax4 = fig.add_subplot(gs[-1, 0])
ax5 = fig.add_subplot(gs[-1, -2])

x = np.linspace(0, 5, 100)

ax1.plot(x, np.sin(x))
ax1.set_title("How2matplotlib.com - Sine Wave")

ax2.plot(x, np.cos(x))
ax2.set_title("How2matplotlib.com - Cosine Wave")

ax3.plot(x, np.tan(x))
ax3.set_title("How2matplotlib.com - Tangent")

ax4.plot(x, x**2)
ax4.set_title("How2matplotlib.com - Quadratic")

ax5.plot(x, np.sqrt(x))
ax5.set_title("How2matplotlib.com - Square Root")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何创建一个复杂的不规则子图布局,其中子图的大小和位置各不相同。

2.4 共享轴

在某些情况下,我们可能希望子图之间共享 x 轴或 y 轴:

import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6), sharex=True)

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

ax1.plot(x, y1)
ax1.set_title("How2matplotlib.com - Sine Wave")

ax2.plot(x, y2)
ax2.set_title("How2matplotlib.com - Cosine Wave")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

在这个例子中,两个子图共享相同的 x 轴,这在比较具有相同 x 范围的不同数据集时非常有用。

2.5 子图中的子图

Matplotlib 还允许在子图内创建更小的子图:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

x = np.linspace(0, 10, 100)
y = np.sin(x)

ax.plot(x, y)
ax.set_title("How2matplotlib.com - Main Plot")

# 创建子图中的子图
inset_ax = ax.inset_axes([0.6, 0.1, 0.3, 0.3])
inset_ax.plot(x, y)
inset_ax.set_title("Inset", fontsize=8)
inset_ax.set_xlim(4, 6)
inset_ax.set_ylim(-1, 1)

ax.indicate_inset_zoom(inset_ax)

plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子在主图中创建了一个小的插入图,用于放大显示主图的某个部分。

3. 组合图形大小和子图技术

现在,让我们看看如何结合图形大小和子图技术来创建更复杂的可视化:

3.1 多行多列的子图布局

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(3, 3, figsize=(15, 15))
x = np.linspace(0, 10, 100)

for i in range(3):
    for j in range(3):
        axs[i, j].plot(x, np.sin(x + i*j))
        axs[i, j].set_title(f"How2matplotlib.com - Plot {i+1},{j+1}")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子创建了一个 3×3 的子图网格,每个子图显示稍微不同的正弦波。

3.2 不同大小的子图

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np

fig = plt.figure(figsize=(12, 8))
gs = gridspec.GridSpec(2, 2, width_ratios=[2, 1], height_ratios=[1, 2])

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])

x = np.linspace(0, 10, 100)

ax1.plot(x, np.sin(x))
ax1.set_title("How2matplotlib.com - Sine")

ax2.plot(x, np.cos(x))
ax2.set_title("How2matplotlib.com - Cosine")

ax3.plot(x, np.tan(x))
ax3.set_title("How2matplotlib.com - Tangent")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何创建具有不同大小的子图,使用 GridSpec 来精确控制每个子图的大小和位置。

3.3 子图中的多个图表

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(12, 10))

x = np.linspace(0, 10, 100)

axs[0, 0].plot(x, np.sin(x), 'r', label='sin(x)')
axs[0, 0].plot(x, np.cos(x), 'b', label='cos(x)')
axs[0, 0].set_title("How2matplotlib.com - Trigonometric Functions")
axs[0, 0].legend()

axs[0, 1].scatter(np.random.rand(50), np.random.rand(50))
axs[0, 1].set_title("How2matplotlib.com - Scatter Plot")

axs[1, 0].bar(['A', 'B', 'C', 'D'], [3, 7, 2, 5])
axs[1, 0].set_title("How2matplotlib.com - Bar Chart")

axs[1, 1].hist(np.random.randn(1000))
axs[1, 1].set_title("How2matplotlib.com - Histogram")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子在一个图形中展示了四种不同类型的图表,每个都在自己的子图中。

3.4 子图标题和总标题

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(12, 10))
fig.suptitle("How2matplotlib.com - Various Mathematical Functions", fontsize=16)

x = np.linspace(0, 10, 100)

axs[0, 0].plot(x, np.sin(x))
axs[0, 0].set_title("Sine Function")

axs[0, 1].plot(x, np.cos(x))
axs[0, 1].set_title("Cosine Function")

axs[1, 0].plot(x, np.exp(x))
axs[1, 0].set_title("Exponential Function")

axs[1, 1].plot(x, np.log(x))
axs[1, 1].set_title("Logarithmic Function")

plt.tight_layout()
plt.subplots_adjust(top=0.92)
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何为整个图形添加一个总标题,同时为每个子图设置单独的标题。

3.5 调整子图间距

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(12, 10))

x = np.linspace(0, 10, 100)

for i in range(2):
    for j in range(2):
        axs[i, j].plot(x, np.sin(x + i + j))
        axs[i, j].set_title(f"How2matplotlib.com - Plot {i+1},{j+1}")

plt.tight_layout()
plt.subplots_adjust(wspace=0.3, hspace=0.3)
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何使用 subplots_adjust 函数来调整子图之间的间距。

4. 高级技巧和注意事项

4.1 自适应布局

Matplotlib 提供了自适应布局功能,可以自动调整子图大小和间距:

“`python“`python
import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(10, 8))
x = np.linspace(0, 10, 100)

for i in range(2):
for j in range(2):
axs[i, j].plot(x, np.sin(x + i + j))
axs[i, j].set_title(f”How2matplotlib.com – Plot {i+1},{j+1}”)
axs[i, j].set_xlabel(“X axis”)
axs[i, j].set_ylabel(“Y axis”)

plt.tight_layout()
plt.show()

Output:

![Matplotlib 图形大小和子图布局:全面指南](https://static.deepinout.com/geekdocs/2024/11/16/20240825221744-13.png "Matplotlib 图形大小和子图布局:全面指南")

这个例子使用 `tight_layout()` 函数自动调整子图布局,以避免重叠和确保标签可见。

### 4.2 处理长标题和标签

当处理长标题或标签时,可能需要调整布局以确保所有文本都可见:

```python
import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(12, 10))
x = np.linspace(0, 10, 100)

for i in range(2):
    for j in range(2):
        axs[i, j].plot(x, np.sin(x + i + j))
        axs[i, j].set_title(f"How2matplotlib.com - Very Long Title for Plot {i+1},{j+1}")
        axs[i, j].set_xlabel("This is a very long X axis label")
        axs[i, j].set_ylabel("This is a very long Y axis label")

plt.tight_layout()
plt.subplots_adjust(top=0.9, bottom=0.1, left=0.1, right=0.9)
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何处理长标题和标签,通过调整子图间距来确保所有文本都清晰可见。

4.3 在子图中使用不同的比例

有时,我们可能需要在同一图形中使用不同的比例:

import matplotlib.pyplot as plt
import numpy as np

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.exp(x)

ax1.plot(x, y1)
ax1.set_title("How2matplotlib.com - Sine Function")
ax1.set_ylim(-1.5, 1.5)

ax2.plot(x, y2)
ax2.set_title("How2matplotlib.com - Exponential Function")
ax2.set_yscale('log')

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何在一个子图中使用线性比例,在另一个子图中使用对数比例。

4.4 子图中的图例位置

当处理多个子图时,正确放置图例很重要:

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(12, 10))
x = np.linspace(0, 10, 100)

for i in range(2):
    for j in range(2):
        axs[i, j].plot(x, np.sin(x), label='sin')
        axs[i, j].plot(x, np.cos(x), label='cos')
        axs[i, j].set_title(f"How2matplotlib.com - Plot {i+1},{j+1}")
        axs[i, j].legend(loc='upper right')

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何在每个子图中放置图例,并使用 loc 参数指定位置。

4.5 子图中的颜色条

在某些可视化中,添加颜色条(colorbar)可能很有用:

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, figsize=(12, 10))

for i in range(2):
    for j in range(2):
        data = np.random.rand(10, 10)
        im = axs[i, j].imshow(data, cmap='viridis')
        axs[i, j].set_title(f"How2matplotlib.com - Plot {i+1},{j+1}")
        fig.colorbar(im, ax=axs[i, j])

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子在每个子图中添加了一个颜色条,用于解释热图的颜色含义。

5. 实际应用示例

让我们看一些更复杂的实际应用示例,展示如何结合使用图形大小和子图布局来创建信息丰富的可视化。

5.1 股票价格分析

import matplotlib.pyplot as plt
import numpy as np

# 模拟股票数据
dates = np.arange('2023-01-01', '2023-12-31', dtype='datetime64[D]')
price = 100 + np.cumsum(np.random.randn(len(dates)) * 2)
volume = np.random.randint(1000, 10000, size=len(dates))

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True, gridspec_kw={'height_ratios': [3, 1]})

ax1.plot(dates, price)
ax1.set_title("How2matplotlib.com - Stock Price Analysis")
ax1.set_ylabel("Price ($)")

ax2.bar(dates, volume, width=1)
ax2.set_ylabel("Volume")
ax2.set_xlabel("Date")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子创建了一个股票价格和交易量的分析图,使用共享 x 轴的两个子图。

5.2 天气数据可视化

import matplotlib.pyplot as plt
import numpy as np

# 模拟天气数据
dates = np.arange('2023-01-01', '2023-12-31', dtype='datetime64[D]')
temp_high = 20 + 15 * np.sin(np.arange(len(dates)) * 2 * np.pi / 365) + np.random.randn(len(dates)) * 3
temp_low = temp_high - 10 + np.random.randn(len(dates)) * 2
rainfall = np.random.exponential(5, size=len(dates))

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10), sharex=True)

ax1.plot(dates, temp_high, label='High')
ax1.plot(dates, temp_low, label='Low')
ax1.set_title("How2matplotlib.com - Temperature and Rainfall")
ax1.set_ylabel("Temperature (°C)")
ax1.legend()

ax2.bar(dates, rainfall, width=1, alpha=0.5)
ax2.set_ylabel("Rainfall (mm)")
ax2.set_xlabel("Date")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子创建了一个年度天气数据可视化,包括温度和降雨量。

5.3 多变量数据分析

import matplotlib.pyplot as plt
import numpy as np

# 生成多变量数据
n = 1000
x = np.random.randn(n)
y = 2*x + np.random.randn(n)
z = x - y + np.random.randn(n)

fig = plt.figure(figsize=(12, 10))
gs = fig.add_gridspec(2, 2)

ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])

ax1.scatter(x, y)
ax1.set_title("How2matplotlib.com - X vs Y")
ax1.set_xlabel("X")
ax1.set_ylabel("Y")

ax2.scatter(x, z)
ax2.set_title("How2matplotlib.com - X vs Z")
ax2.set_xlabel("X")
ax2.set_ylabel("Z")

ax3.scatter(y, z, c=x, cmap='viridis')
ax3.set_title("How2matplotlib.com - Y vs Z (color: X)")
ax3.set_xlabel("Y")
ax3.set_ylabel("Z")

plt.colorbar(ax3.collections[0], ax=ax3, label="X value")

plt.tight_layout()
plt.show()

Output:

Matplotlib 图形大小和子图布局:全面指南

这个例子展示了如何使用不同大小的子图来分析多变量数据,包括散点图和颜色编码。

6. 总结

通过本文,我们深入探讨了 Matplotlib 中图形大小和子图布局的各个方面。我们学习了如何:

  1. 控制整体图形大小
  2. 创建和自定义子图布局
  3. 处理不规则子图布局
  4. 调整子图间距和对齐
  5. 在复杂的可视化中结合使用这些技术

掌握这些技能将使你能够创建更专业、更有洞察力的数据可视化。记住,好的可视化不仅仅是展示数据,还要讲述数据背后的故事。通过适当地设置图形大小和子图布局,你可以确保你的可视化清晰、引人注目,并有效地传达你想要表达的信息。

在实际应用中,始终考虑你的目标受众和展示环境。例如,用于演示的图表可能需要更大的字体和更简单的布局,而用于科学论文的图表可能需要更详细的信息和更紧凑的布局。

最后,不要忘记实践的重要性。尝试不同的布局和大小设置,看看它们如何影响你的可视化效果。随着经验的积累,你将能够更直观地选择最适合你数据的图形大小和子图布局。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程