Matplotlib柱状图图例:如何创建和自定义柱状图的图例
参考:matplotlib bar chart legend
Matplotlib是Python中最流行的数据可视化库之一,它提供了强大的工具来创建各种类型的图表,包括柱状图。在数据可视化中,柱状图是一种常用的图表类型,用于比较不同类别的数据。而图例则是帮助读者理解图表内容的重要元素。本文将详细介绍如何使用Matplotlib创建柱状图,并重点讲解如何添加和自定义图例,以增强图表的可读性和信息传达能力。
1. Matplotlib柱状图基础
在开始讨论图例之前,我们先来了解如何使用Matplotlib创建基本的柱状图。柱状图通常用于展示离散类别的数值比较。
1.1 创建简单的柱状图
让我们从一个简单的例子开始:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
plt.figure(figsize=(8, 6))
plt.bar(categories, values)
plt.title('Simple Bar Chart - how2matplotlib.com')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.show()
Output:
在这个例子中,我们创建了一个简单的柱状图,展示了四个类别的数值。plt.bar()
函数是创建柱状图的核心,它接受两个主要参数:类别标签和对应的数值。
1.2 自定义柱状图外观
我们可以通过调整各种参数来自定义柱状图的外观:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
plt.figure(figsize=(10, 6))
plt.bar(categories, values, color='skyblue', edgecolor='navy', linewidth=2, alpha=0.7)
plt.title('Customized Bar Chart - how2matplotlib.com', fontsize=16)
plt.xlabel('Categories', fontsize=12)
plt.ylabel('Values', fontsize=12)
plt.xticks(rotation=45)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
Output:
在这个例子中,我们自定义了柱子的颜色、边框颜色、透明度等属性,同时调整了标题和轴标签的字体大小,旋转了x轴标签,并添加了网格线。
2. 添加图例到柱状图
图例是帮助读者理解图表内容的重要元素,特别是当图表包含多个数据系列时。让我们看看如何为柱状图添加图例。
2.1 单系列柱状图的图例
即使是单系列的柱状图,有时也需要添加图例:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
plt.figure(figsize=(8, 6))
bars = plt.bar(categories, values, label='Data Series - how2matplotlib.com')
plt.title('Bar Chart with Legend')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.legend()
plt.show()
Output:
在这个例子中,我们通过label
参数为柱状图添加了标签,然后使用plt.legend()
函数显示图例。
2.2 多系列柱状图的图例
当我们有多个数据系列时,图例变得更加重要:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
x = np.arange(len(categories))
width = 0.35
fig, ax = plt.subplots(figsize=(10, 6))
rects1 = ax.bar(x - width/2, values1, width, label='Series 1 - how2matplotlib.com')
rects2 = ax.bar(x + width/2, values2, width, label='Series 2 - how2matplotlib.com')
ax.set_title('Multiple Series Bar Chart')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们创建了两个并排的柱状图系列,并为每个系列添加了标签。ax.legend()
函数自动创建包含这两个标签的图例。
3. 自定义图例
Matplotlib提供了多种方法来自定义图例的外观和位置。
3.1 调整图例位置
我们可以通过loc
参数来调整图例的位置:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
plt.figure(figsize=(8, 6))
plt.bar(categories, values, label='Data - how2matplotlib.com')
plt.title('Bar Chart with Custom Legend Location')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.legend(loc='upper right')
plt.show()
Output:
loc
参数可以接受多种值,如’upper left’、’lower right’、’center’等。
3.2 自定义图例样式
我们可以调整图例的各种视觉属性:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
plt.figure(figsize=(8, 6))
plt.bar(categories, values, label='Data - how2matplotlib.com')
plt.title('Bar Chart with Styled Legend')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.legend(frameon=True, fancybox=True, shadow=True, fontsize=10,
facecolor='lightgray', edgecolor='black', title='Legend Title')
plt.show()
Output:
在这个例子中,我们自定义了图例的边框、阴影、字体大小、背景色等属性。
3.3 图例中的多列布局
当有多个数据系列时,我们可能希望图例以多列的形式显示:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
values3 = [2, 5, 3, 6]
x = np.arange(len(categories))
width = 0.25
fig, ax = plt.subplots(figsize=(12, 6))
rects1 = ax.bar(x - width, values1, width, label='Series 1 - how2matplotlib.com')
rects2 = ax.bar(x, values2, width, label='Series 2 - how2matplotlib.com')
rects3 = ax.bar(x + width, values3, width, label='Series 3 - how2matplotlib.com')
ax.set_title('Multiple Series Bar Chart with Multi-column Legend')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend(ncol=3, loc='upper center', bbox_to_anchor=(0.5, 1.15))
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们使用ncol
参数将图例设置为3列,并使用bbox_to_anchor
参数调整图例的位置。
4. 堆叠柱状图的图例
堆叠柱状图是另一种常见的柱状图类型,它需要特别注意图例的处理。
4.1 创建基本的堆叠柱状图
让我们先创建一个基本的堆叠柱状图:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [1, 2, 3, 4]
values2 = [2, 3, 4, 5]
values3 = [3, 4, 5, 6]
plt.figure(figsize=(10, 6))
plt.bar(categories, values1, label='Series 1 - how2matplotlib.com')
plt.bar(categories, values2, bottom=values1, label='Series 2 - how2matplotlib.com')
plt.bar(categories, values3, bottom=np.array(values1) + np.array(values2), label='Series 3 - how2matplotlib.com')
plt.title('Stacked Bar Chart')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.legend()
plt.show()
Output:
在这个例子中,我们使用bottom
参数来堆叠不同的数据系列。图例自动显示了每个系列的标签。
4.2 自定义堆叠柱状图的图例
我们可以进一步自定义堆叠柱状图的图例:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [1, 2, 3, 4]
values2 = [2, 3, 4, 5]
values3 = [3, 4, 5, 6]
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(categories, values1, label='Series 1 - how2matplotlib.com', color='skyblue')
ax.bar(categories, values2, bottom=values1, label='Series 2 - how2matplotlib.com', color='lightgreen')
ax.bar(categories, values3, bottom=np.array(values1) + np.array(values2), label='Series 3 - how2matplotlib.com', color='salmon')
ax.set_title('Customized Stacked Bar Chart')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.legend(title='Data Series', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们为每个系列设置了不同的颜色,并将图例放置在图表的右侧。
5. 水平柱状图的图例
水平柱状图是柱状图的一种变体,特别适用于类别标签较长的情况。
5.1 创建基本的水平柱状图
让我们创建一个基本的水平柱状图:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Category A', 'Category B', 'Category C', 'Category D']
values = [4, 7, 2, 5]
plt.figure(figsize=(10, 6))
plt.barh(categories, values, label='Data - how2matplotlib.com')
plt.title('Horizontal Bar Chart')
plt.xlabel('Values')
plt.ylabel('Categories')
plt.legend()
plt.show()
Output:
在这个例子中,我们使用plt.barh()
函数创建水平柱状图。图例的添加方式与垂直柱状图相同。
5.2 多系列水平柱状图的图例
对于多系列的水平柱状图,我们需要特别注意柱子的位置和图例的布局:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Category A', 'Category B', 'Category C', 'Category D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
y = np.arange(len(categories))
height = 0.35
fig, ax = plt.subplots(figsize=(12, 6))
rects1 = ax.barh(y - height/2, values1, height, label='Series 1 - how2matplotlib.com')
rects2 = ax.barh(y + height/2, values2, height, label='Series 2 - how2matplotlib.com')
ax.set_title('Multiple Series Horizontal Bar Chart')
ax.set_xlabel('Values')
ax.set_yticks(y)
ax.set_yticklabels(categories)
ax.legend(loc='lower right')
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们创建了两个并排的水平柱状图系列,并将图例放置在右下角。
6. 图例与数据标签的结合
有时,我们可能希望在柱子上直接显示数值,同时保留图例。这种组合可以提供更详细的信息。
6.1 添加数据标签
让我们为柱状图添加数据标签:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(categories, values, label='Data - how2matplotlib.com')
ax.set_title('Bar Chart with Data Labels and Legend')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
# 添加数据标签
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height,
f'{height}',
ha='center', va='bottom')
ax.legend()
plt.show()
Output:
在这个例子中,我们遍历每个柱子,并在其顶部添加对应的数值标签。
6.2 结合数据标签和自定义图例
我们可以进一步自定义数据标签和图例的样式:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
x = np.arange(len(categories))
width = 0.35
fig, ax = plt.subplots(figsize=(12, 6))
rects1 = ax.bar(x - width/2, values1, width, label='Series 1 - how2matplotlib.com', color='skyblue')
rects2 = ax.bar(x + width/2, values2, width, label='Series 2 - how2matplotlib.com', color='lightgreen')
ax.set_title('Bar Chart with Data Labels and Custom Legend')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_xticks(x)
ax.set_xticklabels(categories)
# 添加数据标签
def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax.annotate(f'{height}',
xy=(rect.get_x() + rect.get_width() / 2, height),
xytext=(0, 3), # 3 points vertical offset
textcoords="offset points",
ha='center', va='bottom')
autolabel(rects1)
autolabel(rects2)
ax.legend(title='Data Series', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
Output:
在这个例子中,我们为两个数据系列添加了数据标签,并将图例放置在图表的右侧,同时为图例添加了标题。
7. 动态图例
在某些情况下,我们可能需要根据数据动态地添加或移除图例项。
7.1 动态添加图例项
以下是一个动态添加图例项的例子:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
fig, ax = plt.subplots(figsize=(10, 6))
# 初始只画一个系列
bars1 = ax.bar(categories, values1, label='Series 1 - how2matplotlib.com')
ax.set_title('Dynamic Legend Example')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
# 初始图例
legend = ax.legend()
plt.show(block=False)
plt.pause(2) # 暂停2秒
# 添加第二个系列
bars2 = ax.bar(categories, values2, bottom=values1, label='Series 2 - how2matplotlib.com')
# 更新图例
ax.legend()
plt.draw()
plt.show()
Output:
这个例子展示了如何先显示一个数据系列,然后动态添加另一个系列并更新图例。
7.2 交互式图例
Matplotlib还支持交互式图例,允许用户通过点击图例来显示或隐藏特定的数据系列:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
values3 = [2, 5, 3, 6]
fig, ax = plt.subplots(figsize=(10, 6))
bars1 = ax.bar(np.arange(len(categories)) - 0.25, values1, 0.25, label='Series 1 - how2matplotlib.com')
bars2 = ax.bar(np.arange(len(categories)), values2, 0.25, label='Series 2 - how2matplotlib.com')
bars3 = ax.bar(np.arange(len(categories)) + 0.25, values3, 0.25, label='Series 3 - how2matplotlib.com')
ax.set_title('Interactive Legend Example')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_xticks(np.arange(len(categories)))
ax.set_xticklabels(categories)
leg = ax.legend()
# 使图例可交互
lined = {} # 将图例文本映射到线条对象
for legline, origline in zip(leg.get_lines(), [bars1, bars2, bars3]):
legline.set_picker(5) # 5 pts tolerance
lined[legline] = origline
def onpick(event):
# 点击图例时触发
legline = event.artist
origline = lined[legline]
vis = not origline[0].get_visible()
for rect in origline:
rect.set_visible(vis)
# 更改图例中线条的alpha值
if vis:
legline.set_alpha(1.0)
else:
legline.set_alpha(0.2)
fig.canvas.draw()
fig.canvas.mpl_connect('pick_event', onpick)
plt.show()
Output:
这个例子创建了一个交互式图例,用户可以通过点击图例项来显示或隐藏相应的数据系列。
8. 自定义图例标记
有时,我们可能想要自定义图例中的标记,使其与实际数据表示不同。
8.1 使用自定义标记
以下是一个使用自定义标记的例子:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 2, 5]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(categories, values)
# 创建自定义图例
custom_lines = [plt.Line2D([0], [0], color='blue', lw=4),
plt.Rectangle((0, 0), 1, 1, fc='red')]
ax.legend(custom_lines, ['Line', 'Rectangle - how2matplotlib.com'])
ax.set_title('Bar Chart with Custom Legend Markers')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们创建了自定义的图例标记,一个是线条,另一个是矩形,这与实际的柱状图表示不同。
8.2 组合不同类型的图表
有时,我们可能需要在同一个图表中组合不同类型的图表,并为它们创建统一的图例:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
bar_values = [4, 7, 2, 5]
line_values = [3, 5, 4, 6]
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制柱状图
bars = ax.bar(categories, bar_values, label='Bar Data - how2matplotlib.com')
# 绘制折线图
line = ax.plot(categories, line_values, color='red', marker='o', label='Line Data - how2matplotlib.com')
ax.set_title('Combined Bar and Line Chart')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
# 添加图例
ax.legend()
plt.show()
Output:
这个例子展示了如何在同一个图表中组合柱状图和折线图,并为它们创建统一的图例。
9. 图例的高级样式
Matplotlib提供了许多高级选项来进一步自定义图例的样式。
9.1 使用自定义字体和颜色
我们可以为图例设置自定义字体和颜色:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(np.arange(len(categories)) - 0.2, values1, 0.4, label='Series 1 - how2matplotlib.com', color='skyblue')
ax.bar(np.arange(len(categories)) + 0.2, values2, 0.4, label='Series 2 - how2matplotlib.com', color='lightgreen')
ax.set_title('Bar Chart with Styled Legend', fontsize=16)
ax.set_xlabel('Categories', fontsize=12)
ax.set_ylabel('Values', fontsize=12)
ax.set_xticks(np.arange(len(categories)))
ax.set_xticklabels(categories)
# 自定义图例样式
legend = ax.legend(prop={'family': 'serif', 'size': 12},
title='Data Series',
title_fontsize='13',
facecolor='white',
edgecolor='black',
framealpha=0.8,
loc='upper right')
# 设置图例标题的颜色
legend.get_title().set_color('navy')
plt.tight_layout()
plt.show()
Output:
这个例子展示了如何自定义图例的字体、颜色、背景和边框。
9.2 创建多列图例
对于包含多个数据系列的图表,多列图例可以节省空间:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 2, 5]
values2 = [3, 6, 4, 3]
values3 = [2, 5, 3, 6]
values4 = [5, 3, 6, 2]
fig, ax = plt.subplots(figsize=(12, 6))
width = 0.2
x = np.arange(len(categories))
ax.bar(x - 1.5*width, values1, width, label='Series 1 - how2matplotlib.com', color='skyblue')
ax.bar(x - 0.5*width, values2, width, label='Series 2 - how2matplotlib.com', color='lightgreen')
ax.bar(x + 0.5*width, values3, width, label='Series 3 - how2matplotlib.com', color='salmon')
ax.bar(x + 1.5*width, values4, width, label='Series 4 - how2matplotlib.com', color='gold')
ax.set_title('Bar Chart with Multi-column Legend', fontsize=16)
ax.set_xlabel('Categories', fontsize=12)
ax.set_ylabel('Values', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(categories)
# 创建多列图例
ax.legend(ncol=2, loc='upper center', bbox_to_anchor=(0.5, 1.15),
fancybox=True, shadow=True)
plt.tight_layout()
plt.show()
Output:
这个例子创建了一个包含四个数据系列的柱状图,并使用两列布局的图例来节省空间。
10. 总结
在本文中,我们深入探讨了如何在Matplotlib中创建柱状图并添加图例。我们涵盖了从基本的柱状图创建到复杂的多系列图表,以及如何自定义图例的各个方面。以下是一些关键点:
- 使用
plt.bar()
或ax.bar()
函数可以轻松创建柱状图。 - 通过
label
参数为每个数据系列添加标签,然后使用plt.legend()
或ax.legend()
显示图例。 - 图例的位置可以通过
loc
参数调整,也可以使用bbox_to_anchor
进行更精确的定位。 - 可以自定义图例的外观,包括字体、颜色、背景和边框。
- 对于多系列数据,可以创建堆叠柱状图或并排柱状图,并相应地调整图例。
- 水平柱状图是处理长类别标签的好选择。
- 可以结合使用数据标签和图例来提供更详细的信息。
- 动态和交互式图例可以增强图表的可用性。
- 可以自定义图例标记,使其与实际数据表示不同。
- 对于包含多个数据系列的复杂图表,多列图例可以有效节省空间。
通过掌握这些技巧,你可以创建既信息丰富又视觉吸引的柱状图,有效地传达你的数据故事。记住,好的数据可视化不仅仅是展示数据,更是要让数据说话,帮助观众快速理解和洞察关键信息。
最后,建议在实践中多尝试不同的设置和组合,找到最适合你的数据和目标受众的表现方式。Matplotlib的灵活性使得我们可以创建各种各样的图表样式,充分发挥你的创造力,打造出独特而有效的数据可视化作品。