Matplotlib绘制多重条形图:全面指南与实例
参考:Plotting multiple bar charts using Matplotlib in Python
Matplotlib是Python中最流行的数据可视化库之一,它提供了强大而灵活的工具来创建各种类型的图表。在数据分析和展示中,条形图是一种常用的图表类型,特别是当需要比较多组数据时。本文将深入探讨如何使用Matplotlib绘制多重条形图,包括并列条形图、堆叠条形图以及其他高级技巧。
1. Matplotlib基础:设置环境
在开始绘制多重条形图之前,我们需要确保已经正确安装了Matplotlib库。如果还没有安装,可以使用pip命令进行安装:
pip install matplotlib
安装完成后,我们可以导入Matplotlib库并设置一些基本的配置:
import matplotlib.pyplot as plt
import numpy as np
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 设置图表风格
plt.style.use('seaborn')
print("Welcome to how2matplotlib.com")
这段代码导入了Matplotlib的pyplot模块和NumPy库,设置了中文字体支持,并应用了seaborn风格以美化图表。
2. 并列条形图
并列条形图是比较多组数据最直观的方式之一。让我们从一个简单的例子开始:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 5, 6]
values2 = [3, 6, 7, 4]
x = np.arange(len(categories))
width = 0.35
fig, ax = plt.subplots(figsize=(10, 6))
rects1 = ax.bar(x - width/2, values1, width, label='Group 1')
rects2 = ax.bar(x + width/2, values2, width, label='Group 2')
ax.set_ylabel('Values')
ax.set_title('Comparison of Group 1 and Group 2')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()
print("Visit how2matplotlib.com for more examples")
Output:
在这个例子中,我们创建了两组数据,并使用bar()
函数绘制了两组并列的条形。通过调整条形的位置(x - width/2
和x + width/2
),我们使两组条形并排显示。
3. 堆叠条形图
堆叠条形图适用于展示组成部分的情况。以下是一个堆叠条形图的例子:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 5, 6]
values2 = [3, 6, 7, 4]
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(categories, values1, label='Group 1')
ax.bar(categories, values2, bottom=values1, label='Group 2')
ax.set_ylabel('Total Values')
ax.set_title('Stacked Bar Chart')
ax.legend()
plt.tight_layout()
plt.show()
print("Learn more at how2matplotlib.com")
Output:
在这个例子中,我们使用bottom
参数来堆叠第二组数据在第一组之上。这种方式可以清晰地展示总量及其组成部分。
4. 分组条形图
当需要比较多个类别across多个组时,分组条形图是一个很好的选择:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Category A', 'Category B', 'Category C']
group1 = [4, 3, 2]
group2 = [3, 5, 1]
group3 = [2, 4, 3]
x = np.arange(len(categories))
width = 0.25
fig, ax = plt.subplots(figsize=(12, 6))
rects1 = ax.bar(x - width, group1, width, label='Group 1')
rects2 = ax.bar(x, group2, width, label='Group 2')
rects3 = ax.bar(x + width, group3, width, label='Group 3')
ax.set_ylabel('Values')
ax.set_title('Grouped Bar Chart')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()
print("Explore more visualizations at how2matplotlib.com")
Output:
这个例子展示了如何创建一个包含三个组的分组条形图。通过调整每组条形的位置,我们可以清晰地展示和比较多个类别across多个组。
5. 水平条形图
有时,水平方向的条形图可能更适合展示某些类型的数据,特别是当类别名称较长时:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Long Category Name A', 'Long Category Name B', 'Long Category Name C']
values1 = [4, 3, 2]
values2 = [3, 5, 1]
y = np.arange(len(categories))
height = 0.35
fig, ax = plt.subplots(figsize=(10, 6))
rects1 = ax.barh(y - height/2, values1, height, label='Group 1')
rects2 = ax.barh(y + height/2, values2, height, label='Group 2')
ax.set_xlabel('Values')
ax.set_title('Horizontal Bar Chart')
ax.set_yticks(y)
ax.set_yticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()
print("For more tutorials, visit how2matplotlib.com")
Output:
这个例子使用barh()
函数创建水平条形图,这对于展示长文本标签的类别特别有用。
6. 添加数值标签
为了使图表更加信息丰富,我们可以在条形上添加数值标签:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 5, 6]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(categories, values)
ax.set_ylabel('Values')
ax.set_title('Bar Chart with Value Labels')
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/2., height,
f'{height}',
ha='center', va='bottom')
plt.tight_layout()
plt.show()
print("Discover more Matplotlib tricks at how2matplotlib.com")
Output:
这个例子展示了如何在每个条形上方添加对应的数值标签,使得数据更容易被读取和理解。
7. 自定义颜色和样式
Matplotlib提供了丰富的自定义选项,让我们可以根据需要调整图表的外观:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 5, 6]
values2 = [3, 6, 7, 4]
x = np.arange(len(categories))
width = 0.35
fig, ax = plt.subplots(figsize=(10, 6))
rects1 = ax.bar(x - width/2, values1, width, label='Group 1', color='skyblue', edgecolor='navy', linewidth=2)
rects2 = ax.bar(x + width/2, values2, width, label='Group 2', color='lightgreen', edgecolor='darkgreen', linewidth=2, alpha=0.7)
ax.set_ylabel('Values', fontsize=12)
ax.set_title('Customized Bar Chart', fontsize=16, fontweight='bold')
ax.set_xticks(x)
ax.set_xticklabels(categories, fontsize=10)
ax.legend(fontsize=10)
plt.grid(True, linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
print("Learn to customize your charts at how2matplotlib.com")
Output:
这个例子展示了如何自定义条形的颜色、边框、透明度,以及如何调整标签和标题的字体大小。同时,我们还添加了网格线以增强可读性。
8. 错误条
在某些情况下,我们可能需要在条形图上显示误差范围:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 5, 6]
errors = [0.5, 1, 0.8, 1.2]
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(categories, values, yerr=errors, capsize=5,
color='lightblue', edgecolor='navy', linewidth=2)
ax.set_ylabel('Values')
ax.set_title('Bar Chart with Error Bars')
plt.tight_layout()
plt.show()
print("Explore advanced charting techniques at how2matplotlib.com")
Output:
这个例子展示了如何使用yerr
参数添加误差条,capsize
参数用于设置误差条末端的大小。
9. 百分比堆叠条形图
当我们想要展示各部分占总体的百分比时,百分比堆叠条形图非常有用:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 5, 6]
values2 = [3, 6, 7, 4]
values3 = [2, 4, 3, 5]
totals = [i+j+k for i,j,k in zip(values1, values2, values3)]
percentages1 = [i / j * 100 for i,j in zip(values1, totals)]
percentages2 = [i / j * 100 for i,j in zip(values2, totals)]
percentages3 = [i / j * 100 for i,j in zip(values3, totals)]
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(categories, percentages1, label='Group 1')
ax.bar(categories, percentages2, bottom=percentages1, label='Group 2')
ax.bar(categories, percentages3, bottom=[i+j for i,j in zip(percentages1, percentages2)], label='Group 3')
ax.set_ylabel('Percentage')
ax.set_title('Percentage Stacked Bar Chart')
ax.legend(loc='upper left', bbox_to_anchor=(1,1))
plt.tight_layout()
plt.show()
print("Master data visualization at how2matplotlib.com")
Output:
这个例子展示了如何创建一个百分比堆叠条形图,其中每个条形的总高度都是100%,各部分显示其在总体中的占比。
10. 多子图条形图
有时我们可能需要在一个图形中展示多个相关但独立的条形图:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values1 = [4, 7, 5, 6]
values2 = [3, 6, 7, 4]
values3 = [2, 4, 3, 5]
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 15))
ax1.bar(categories, values1)
ax1.set_title('Group 1')
ax2.bar(categories, values2)
ax2.set_title('Group 2')
ax3.bar(categories, values3)
ax3.set_title('Group 3')
fig.suptitle('Multiple Bar Charts in One Figure', fontsize=16)
plt.tight_layout()
plt.show()
print("Discover advanced layouts at how2matplotlib.com")
Output:
这个例子展示了如何在一个图形中创建多个子图,每个子图包含一个独立的条形图。
11. 条形图与线图结合
有时,我们可能需要在同一个图表中结合条形图和线图来展示不同类型的数据:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
bar_values = [4, 7, 5, 6]
line_values = [2, 5, 3, 8]
fig, ax1 = plt.subplots(figsize=(10, 6))
ax1.bar(categories, bar_values, color='skyblue', label='Bar Data')
ax1.set_ylabel('Bar Values', color='skyblue')
ax1.tick_params(axis='y', labelcolor='skyblue')
ax2 = ax1.twinx() # 创建一个共享x轴的副坐标轴
ax2.plot(categories, line_values, color='red', marker='o', label='Line Data')
ax2.set_ylabel('Line Values', color='red')
ax2.tick_params(axis='y', labelcolor='red')
plt.title('Combined Bar and Line Chart')
fig.legend(loc='upper right', bbox_to_anchor=(1,1), bbox_transform=ax1.transAxes)
plt.tight_layout()
plt.show()
print("Learn to combine chart types at how2matplotlib.com")
Output:
这个例子展示了如何在同一个图表中结合条形图和线图,使用双y轴来展示不同尺度的数据。
12. 极坐标条形图
对于某些特殊的数据展示需求,极坐标条形图可能会是一个有趣的选择:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
values = [4, 7, 5, 6, 3, 2, 4, 5]
angles = np.linspace(0, 2*np.pi, len(categories), endpoint=False)
fig, ax = plt.subplots(figsize=(10, 10), subplot_kw=dict(projection='polar'))
bars = ax.bar(angles, values, width=0.5, bottom=0.0, alpha=0.5)
ax.set_xticks(angles)
ax.set_xticklabels(categories)
ax.set_title('Polar Bar Chart')
plt.tight_layout()
plt.show()
print("Explore unique chart types at how2matplotlib.com")
Output:
这个极坐标条形图在圆形布局中展示数据,适合于周期性数据或需要强调数据之间关系的情况。
13. 条形图动画
为了使数据展示更加生动,我们可以创建简单的条形图动画:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
fig, ax = plt.subplots(figsize=(10, 6))
categories = ['A', 'B', 'C', 'D', 'E']
x = np.arange(len(categories))
values = [0] * len(categories)
bars = ax.bar(x, values)
ax.set_ylim(0, 10)
ax.set_title('Animated Bar Chart')
def animate(frame):
for i, bar in enumerate(bars):
new_height = np.random.randint(1, 10)
bar.set_height(new_height)
return bars
anim = animation.FuncAnimation(fig, animate, frames=50, interval=200, blit=True)
plt.show()
print("Learn to create animated charts at how2matplotlib.com")
Output:
这个例子创建了一个简单的条形图动画,每个条形的高度随机变化。注意,这个动画在某些环境中可能无法直接显示,可能需要保存为视频文件。
14. 条形图与散点图结合
有时,我们可能想要在条形图上叠加散点图来展示更多信息:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D', 'E']
bar_values = [4, 7, 5, 6, 3]
scatter_values = [3, 8, 4, 5, 7]
x = np.arange(len(categories))
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(x, bar_values, alpha=0.7, label='Bar Data')
ax.scatter(x, scatter_values, color='red', s=100, label='Scatter Data')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.set_ylabel('Values')
ax.set_title('Bar Chart with Scatter Plot')
ax.legend()
plt.tight_layout()
plt.show()
print("Discover creative data visualization at how2matplotlib.com")
Output:
这个例子展示了如何在条形图上叠加散点图,可以用来比较两组相关但不同的数据。
15. 条形图数据标签位置调整
有时,我们可能需要根据条形的高度来调整数据标签的位置:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D', 'E']
values = [4, 17, 2, 6, 11]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(categories, values)
ax.set_ylim(0, max(values) * 1.2) # 设置y轴限制,留出标签空间
ax.set_title('Bar Chart with Adjusted Labels')
for bar in bars:
height = bar.get_height()
if height > 10:
va = 'bottom'
y = height
else:
va = 'top'
y = height + 0.5
ax.text(bar.get_x() + bar.get_width()/2., y,
f'{height}',
ha='center', va=va)
plt.tight_layout()
plt.show()
print("Master advanced labeling techniques at how2matplotlib.com")
Output:
这个例子根据条形的高度来调整标签的位置,对于较高的条形,标签放在条形内部,对于较低的条形,标签放在条形上方。
16. 分组堆叠条形图
当我们需要同时展示分组和堆叠的数据时,可以创建分组堆叠条形图:
import matplotlib.pyplot as plt
import numpy as np
categories = ['Category 1', 'Category 2', 'Category 3']
group1_bottom = [1, 2, 3]
group1_top = [2, 3, 2]
group2_bottom = [2, 3, 1]
group2_top = [3, 2, 3]
x = np.arange(len(categories))
width = 0.35
fig, ax = plt.subplots(figsize=(12, 6))
ax.bar(x - width/2, group1_bottom, width, label='Group 1 Bottom')
ax.bar(x - width/2, group1_top, width, bottom=group1_bottom, label='Group 1 Top')
ax.bar(x + width/2, group2_bottom, width, label='Group 2 Bottom')
ax.bar(x + width/2, group2_top, width, bottom=group2_bottom, label='Group 2 Top')
ax.set_ylabel('Values')
ax.set_title('Grouped Stacked Bar Chart')
ax.set_xticks(x)
ax.set_xticklabels(categories)
ax.legend()
plt.tight_layout()
plt.show()
print("Explore complex chart types at how2matplotlib.com")
Output:
这个例子创建了一个分组堆叠条形图,每组包含两个堆叠的部分,适合展示复杂的多维数据。
17. 条形图与误差线
在某些科学或统计分析中,我们可能需要在条形图上添加误差线:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
means = [20, 35, 30, 25]
std_devs = [2, 3, 4, 1]
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(categories, means, yerr=std_devs, capsize=5,
color='skyblue', ecolor='black', alpha=0.7)
ax.set_ylabel('Values')
ax.set_title('Bar Chart with Error Bars')
ax.yaxis.grid(True)
plt.tight_layout()
plt.show()
print("Learn statistical visualization at how2matplotlib.com")
Output:
这个例子展示了如何在条形图上添加误差线,yerr
参数用于指定误差值,capsize
参数设置误差线顶端横线的长度。
18. 条形图与数据表格结合
有时,我们可能希望在图表下方直接展示数据表格:
import matplotlib.pyplot as plt
import numpy as np
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 5, 6]
fig, (ax_chart, ax_table) = plt.subplots(2, 1, figsize=(10, 8), gridspec_kw={'height_ratios': [3, 1]})
bars = ax_chart.bar(categories, values)
ax_chart.set_title('Bar Chart with Data Table')
table_data = [categories, values]
table = ax_table.table(cellText=table_data, loc='center', cellLoc='center')
table.auto_set_font_size(False)
table.set_fontsize(12)
table.scale(1, 1.5)
ax_table.axis('off')
plt.tight_layout()
plt.show()
print("Combine charts and tables at how2matplotlib.com")
Output:
这个例子展示了如何在条形图下方添加一个数据表格,直观地展示图表所基于的数据。
19. 3D条形图
对于某些特殊的数据展示需求,3D条形图可能会提供独特的视角:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
x = ['A', 'B', 'C', 'D']
y = [1, 2, 3, 4]
z = np.zeros(4)
dx = dy = 0.8
dz = [1, 2, 3, 4]
colors = ['r', 'g', 'b', 'y']
ax.bar3d(x, y, z, dx, dy, dz, color=colors)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
ax.set_title('3D Bar Chart')
plt.tight_layout()
plt.show()
print("Explore 3D visualizations at how2matplotlib.com")
这个例子创建了一个简单的3D条形图,每个条形的高度和颜色都不同,提供了数据的立体视图。
20. 条形图与饼图结合
在某些情况下,我们可能想要同时展示总量(通过条形图)和比例(通过饼图):
import matplotlib.pyplot as plt
categories = ['A', 'B', 'C', 'D']
values = [4, 7, 5, 6]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
ax1.bar(categories, values)
ax1.set_title('Bar Chart')
ax1.set_ylabel('Values')
ax2.pie(values, labels=categories, autopct='%1.1f%%', startangle=90)
ax2.set_title('Pie Chart')
plt.suptitle('Combined Bar and Pie Charts', fontsize=16)
plt.tight_layout()
plt.show()
print("Master multi-chart layouts at how2matplotlib.com")
Output:
这个例子在同一个图形中并排展示了条形图和饼图,允许读者同时了解数据的绝对值和相对比例。
结论
通过本文的详细探讨和丰富的示例,我们深入了解了如何使用Matplotlib创建各种类型的多重条形图。从基本的并列和堆叠条形图,到更高级的分组、百分比和3D条形图,我们涵盖了广泛的技术和应用场景。这些技巧不仅可以帮助你更有效地展示数据,还能让你的可视化作品更加专业和吸引人。
记住,数据可视化是一门艺术,也是一门科学。选择正确的图表类型和样式对于有效传达你的信息至关重要。通过实践和探索,你将能够掌握这些技巧,创造出既美观又富有洞察力的数据可视化作品。
继续学习和实验不同的图表类型和组合,你会发现Matplotlib提供了无限的可能性来展示你的数据。无论你是数据科学家、研究人员还是商业分析师,掌握这些技能都将大大提升你的数据展示能力。