Matplotlib中如何在子图中添加图例:全面指南

Matplotlib中如何在子图中添加图例:全面指南

参考:Matplotlib legend in subplot

Matplotlib是Python中最流行的数据可视化库之一,它提供了强大的绘图功能。在数据可视化中,图例(legend)是一个非常重要的元素,它可以帮助读者理解图表中不同数据系列的含义。当我们在使用子图(subplot)时,如何正确地添加和调整图例就变得尤为重要。本文将全面介绍如何在Matplotlib的子图中添加和自定义图例,包括基本用法、位置调整、样式设置等多个方面。

1. 基本图例添加

在Matplotlib中,我们可以使用legend()方法来为图表添加图例。当使用子图时,我们需要为每个子图单独添加图例。以下是一个基本的示例:

import matplotlib.pyplot as plt
import numpy as np

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

# 创建图形和子图
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# 在第一个子图中绘制数据并添加图例
ax1.plot(x, y1, label='Sin(x)')
ax1.plot(x, y2, label='Cos(x)')
ax1.legend()
ax1.set_title('Subplot 1 - how2matplotlib.com')

# 在第二个子图中绘制数据并添加图例
ax2.plot(x, y1**2, label='Sin^2(x)')
ax2.plot(x, y2**2, label='Cos^2(x)')
ax2.legend()
ax2.set_title('Subplot 2 - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们创建了两个子图,并在每个子图中绘制了不同的函数。通过调用ax1.legend()ax2.legend(),我们为每个子图添加了图例。

2. 自定义图例位置

默认情况下,Matplotlib会自动选择一个合适的位置放置图例。但有时我们可能需要手动指定图例的位置。我们可以通过legend()方法的loc参数来实现这一点。

import matplotlib.pyplot as plt
import numpy as np

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

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

ax1.plot(x, y1, label='Sin(x)')
ax1.plot(x, y2, label='Cos(x)')
ax1.legend(loc='upper right')
ax1.set_title('Legend at upper right - how2matplotlib.com')

ax2.plot(x, y1, label='Sin(x)')
ax2.plot(x, y2, label='Cos(x)')
ax2.legend(loc='lower left')
ax2.set_title('Legend at lower left - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们在第一个子图中将图例放置在右上角('upper right'),在第二个子图中将图例放置在左下角('lower left')。

3. 使用数字代码指定图例位置

除了使用字符串来指定图例位置,我们还可以使用数字代码。这些代码对应于图表中的不同位置:

import matplotlib.pyplot as plt
import numpy as np

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

fig, (ax1, ax2, ax3, ax4) = plt.subplots(2, 2, figsize=(12, 10))

axes = [ax1, ax2, ax3, ax4]
locations = [0, 1, 2, 3]

for ax, loc in zip(axes, locations):
    ax.plot(x, y1, label='Sin(x)')
    ax.plot(x, y2, label='Cos(x)')
    ax.legend(loc=loc)
    ax.set_title(f'Legend at location {loc} - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们创建了四个子图,并使用数字代码0、1、2和3分别指定了图例的位置。这些数字代码对应于不同的位置:0表示最佳位置(自动选择),1表示右上角,2表示左上角,3表示左下角。

4. 图例位置的精确控制

有时我们可能需要更精确地控制图例的位置。我们可以使用bbox_to_anchor参数来实现这一点:

import matplotlib.pyplot as plt
import numpy as np

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

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

ax1.plot(x, y1, label='Sin(x)')
ax1.plot(x, y2, label='Cos(x)')
ax1.legend(bbox_to_anchor=(0.5, 1.05), loc='lower center', ncol=2)
ax1.set_title('Legend above plot - how2matplotlib.com')

ax2.plot(x, y1, label='Sin(x)')
ax2.plot(x, y2, label='Cos(x)')
ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
ax2.set_title('Legend to the right - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们在第一个子图中将图例放置在图表上方的中央位置,在第二个子图中将图例放置在图表右侧。bbox_to_anchor参数接受一个元组,指定图例的锚点位置。

5. 调整图例样式

我们可以通过多种方式来自定义图例的样式,包括改变字体大小、颜色、边框等:

import matplotlib.pyplot as plt
import numpy as np

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

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

ax1.plot(x, y1, label='Sin(x)')
ax1.plot(x, y2, label='Cos(x)')
ax1.legend(fontsize=12, frameon=False, facecolor='lightgray')
ax1.set_title('Custom legend style 1 - how2matplotlib.com')

ax2.plot(x, y1, label='Sin(x)')
ax2.plot(x, y2, label='Cos(x)')
ax2.legend(edgecolor='red', fancybox=True, shadow=True)
ax2.set_title('Custom legend style 2 - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们展示了两种不同的图例样式。第一个子图中的图例没有边框,字体大小为12,背景色为浅灰色。第二个子图中的图例有红色边框,使用了圆角矩形(fancybox=True),并添加了阴影效果(shadow=True)。

6. 多列图例

当图例项目较多时,我们可能希望将图例排列成多列以节省空间:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
fig, ax = plt.subplots(figsize=(10, 6))

for i in range(6):
    ax.plot(x, np.sin(x + i), label=f'Sin(x + {i})')

ax.legend(ncol=3, loc='upper center', bbox_to_anchor=(0.5, 1.15))
ax.set_title('Multi-column legend - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们绘制了6条正弦曲线,并将它们的图例排列成3列(ncol=3)。图例被放置在图表上方的中央位置。

7. 图例中添加自定义元素

有时我们可能需要在图例中添加一些自定义元素,比如特殊的标记或文本:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.lines import Line2D

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

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(x, y1, 'b-', label='Sin(x)')
ax.plot(x, y2, 'r--', label='Cos(x)')

custom_line = Line2D([0], [0], color='green', lw=4, linestyle=':')
custom_text = ax.text(0, 0, '', color='purple')

ax.legend([custom_line, custom_text], ['Custom Line', 'Custom Text'])
ax.set_title('Legend with custom elements - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们创建了一个自定义的线条和文本元素,并将它们添加到图例中。这种方法允许我们在图例中包含任何我们想要的元素。

8. 图例中排除某些元素

有时我们可能想要在图表中绘制某些元素,但不希望它们出现在图例中:

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)

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(x, y1, label='Sin(x)')
ax.plot(x, y2, label='Cos(x)')
ax.plot(x, y3, color='green')  # 不为这条线添加标签

ax.legend()
ax.set_title('Legend excluding some elements - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们绘制了三条曲线,但只为前两条添加了标签。这样,第三条曲线(绿色的正切函数)就不会出现在图例中。

9. 在子图外部添加全局图例

有时我们可能希望为多个子图添加一个全局的图例:

import matplotlib.pyplot as plt
import numpy as np

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

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

line1, = ax1.plot(x, y1, 'b-')
line2, = ax1.plot(x, y2, 'r--')
ax1.set_title('Subplot 1 - how2matplotlib.com')

ax2.plot(x, y1**2, 'b-')
ax2.plot(x, y2**2, 'r--')
ax2.set_title('Subplot 2 - how2matplotlib.com')

fig.legend([line1, line2], ['Sin(x)', 'Cos(x)'], loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=2)

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们使用fig.legend()而不是ax.legend()来创建一个全局的图例。这个图例被放置在整个图形的顶部中央位置。

10. 动态更新图例

在某些情况下,我们可能需要动态地更新图例的内容:

import matplotlib.pyplot as plt
import numpy as np

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

fig, ax = plt.subplots(figsize=(10, 6))

line1, = ax.plot(x, y1, label='Sin(x)')
line2, = ax.plot(x, y2, label='Cos(x)')

legend = ax.legend()

# 更新图例
line1.set_label('Updated Sin(x)')
line2.set_label('Updated Cos(x)')
ax.legend()

ax.set_title('Dynamic legend update - how2matplotlib.com')

plt.tight_layout()
plt.show()

Output:

Matplotlib中如何在子图中添加图例:全面指南

在这个例子中,我们首先创建了一个带有初始标签的图例,然后通过更新线条的标签并重新调用legend()方法来更新图例的内容。

11. 使用自定义处理程序和标签

Matplotlib允许我们使用自定义的处理程序和标签来创建更复杂的图例:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Rectangle

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

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(x, y1, 'b-')
ax.plot(x, y2, 'r--')

# 创建自定义图例元素
blue_line = Rectangle((0, 0), 1, 1, fc="b", fill=False, lw=2)
red_dash = Rectangle((0, 0), 1, 1, fc="r", fill=False, ls="--", lw=2)
green_square = Rectangle((0, 0), 1, 1, fc="g")

# 添加自定义图例
ax.legend([blue_line, red_dash, green_square], ['Blue Line', 'Red Dash', 'Green Square'])

ax.set_title('Custom legend handlers - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们创建了三个自定义的图例元素:一个蓝色实线、一个红色虚线和一个绿色方块。然后我们使用这些自定义元素创建了图例,这样我们就可以完全控制图例中显示的内容。

12. 图例中使用数学公式

Matplotlib支持在图例中使用LaTeX风格的数学公式,这对于科学和工程应用非常有用:

import matplotlib.pyplot as plt
import numpy as np

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

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(x, y1, label=r'\sin(x)')
ax.plot(x, y2, label=r'\cos(x)')

ax.legend(fontsize=14)
ax.set_title('Legend with math formulas - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们在标签中使用了LaTeX风格的数学公式。注意我们使用了原始字符串(r”)来避免反斜杠被解释为转义字符。

13. 图例中使用不同的标记

在某些情况下,我们可能希望在图例中显示不同的标记,以便更好地区分不同的数据系列:

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)

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(x, y1, 'b-', label='Sin(x)')
ax.plot(x, y2, 'r--', label='Cos(x)')
ax.scatter(x[::10], y3[::10], c='g', marker='^', label='Tan(x)')

ax.legend()
ax.set_title('Legend with different markers - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们使用了不同的线型和标记来绘制三个不同的函数。图例会自动显示这些不同的标记。

14. 图例中使用颜色条

对于使用颜色映射的图表,我们可能希望在图例中包含一个颜色条:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable

x = np.linspace(0, 10, 100)
y = np.linspace(0, 10, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)

fig, ax = plt.subplots(figsize=(10, 8))

im = ax.imshow(Z, cmap='viridis')

divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
cbar = plt.colorbar(im, cax=cax)

ax.set_title('Legend with colorbar - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们创建了一个二维图像,并在图例中添加了一个颜色条。颜色条显示了图像中颜色与数值的对应关系。

15. 在3D图中添加图例

Matplotlib也支持在3D图中添加图例,尽管这需要一些额外的设置:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# 生成一些3D数据
t = np.linspace(0, 10, 100)
x = np.sin(t)
y = np.cos(t)
z = t

ax.plot(x, y, z, label='3D curve')

# 添加图例
ax.legend()

ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('3D plot with legend - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们创建了一个3D图,并在其中绘制了一条3D曲线。然后我们添加了一个图例,就像在2D图中一样。

16. 图例中使用自定义图标

有时我们可能希望在图例中使用自定义的图标,而不是默认的线条或标记:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle, Rectangle

fig, ax = plt.subplots(figsize=(10, 6))

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

# 绘制数据
ax.plot(x, y1)
ax.plot(x, y2)

# 创建自定义图标
circle = Circle((0.5, 0.5), 0.2, facecolor="red")
square = Rectangle((0.2, 0.2), 0.6, 0.6, facecolor="blue")

# 添加带有自定义图标的图例
ax.legend([circle, square], ['Circle', 'Square'])

ax.set_title('Legend with custom icons - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们创建了两个自定义图标(一个圆和一个方块),并在图例中使用了这些图标。

17. 图例中显示误差范围

在某些科学应用中,我们可能需要在图例中显示误差范围:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 50)
y = np.sin(x)
yerr = 0.1 + 0.2 * np.random.rand(len(x))

fig, ax = plt.subplots(figsize=(10, 6))

ax.errorbar(x, y, yerr=yerr, fmt='o', label='Data with error')
ax.plot(x, np.sin(x), 'r-', label='True sine')

ax.legend()
ax.set_title('Legend with error bars - how2matplotlib.com')

plt.tight_layout()
plt.show()

在这个例子中,我们绘制了带有误差棒的数据点,以及真实的正弦曲线。图例会自动包含误差棒的表示。

结论

在本文中,我们详细探讨了如何在Matplotlib的子图中添加和自定义图例。我们涵盖了从基本的图例添加到高级的自定义技巧,包括位置调整、样式设置、多列图例、动态更新、使用数学公式、添加自定义元素等多个方面。

图例是数据可视化中的关键元素,它能帮助读者更好地理解图表中的信息。通过灵活运用Matplotlib提供的各种图例功能,我们可以创建出既信息丰富又美观的图表。

在实际应用中,选择合适的图例样式和位置往往需要根据具体的数据和图表类型来决定。建议在创建图表时多尝试不同的图例设置,以找到最适合你的数据和受众的表现方式。

最后,记住图例的主要目的是帮助读者理解图表。因此,在追求美观的同时,也要确保图例的清晰度和可读性。通过本文介绍的各种技巧,相信你已经能够熟练地在Matplotlib的子图中添加和自定义图例,从而创建出更加专业和有说服力的数据可视化作品。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程