柱状图是一种用矩形柱来表示数据分类的图表,是数据分析中最常规的图形之一。柱状图可以垂直绘制,也可以水平绘制,它的高度与其所表示的数值成正比关系。柱状图显示了不同类别之间的比较关系,图表的水平轴 X 指定被比较的类别,垂直轴 Y 则表示具体的类别值。Matplotlib 提供了bar()函数来绘制垂直柱状图,barth()函数来绘制水平柱状图,当它与 axes 对象一起使用时,即开始绘制柱状图。
尽管柱状图非常基础,但是想要绘制一张心仪的柱状图却并不容易,特别是组合多组数据的并列柱状图。接下来,我将总结一下绘制柱状图bar()函数的相关内容。
1. bar()函数
matplotlib.pyplot.bar()函数用于在二维图形上绘制条形图,其函数形式为:
plt.bar(x, height, width=0.8, bottom=None, align='center', data=None, **kwargs)
它的一些关键参数如下:
参数标识 | 描述 |
x | 必需的,柱形图所在位置的x坐标, 一般为一个可迭代对象,表示每个柱形图的位置。 |
height | 必需的,柱形图的高度, 一般为一个可迭代对象,表示每个柱形图的高度。 |
width | 可选的,表示条形的宽度。默认为0.8。 |
bottom | 可选的,柱形图底部的y坐标,默认为None。 |
align | 可选的,表示条形边缘和坐标轴标签的对齐方式。 可以是"center"、"edge"或"left"/"right"。默认为"center"。 |
data | 可选的,用于绘图的数据,默认为None。 |
color | 可选的,表示条形的颜色。 可以是颜色名(如'b'代表蓝色),或者是一个RGB元组。 默认为"blue"。 |
edgecolor | 可选的,表示条形边缘的颜色。 可以是颜色名,或者是一个RGB元组。 默认为None,这意味着条形边缘颜色与内部颜色相同。 |
linewidth | 可选的,表示条形边缘的线宽。默认为0(无边框)。 |
tick_label | 可选的,表示x轴上的标签。 如果未指定,将从x值中自动选择标签。 |
orientation | 可选的,表示条形的方向。 "horizontal"或"vertical"。默认为"vertical"。 |
log | 可选的,是否使用对数刻度。 |
label | 可选的,柱形图的标签,用于图例显示。 |
hatch | 可选的,柱形图填充样式。 |
capsize | 可选的,误差棒帽子的大小。 |
error_kw | 可选的,用于配置误差棒样式的关键字参数。 |
2. 基本运用示例
问题:现有五个班,每个班分别有学生25,33,30,26,29人,现使用matplotlib库绘制出每个班拥有的人数柱状图。
import matplotlib.pyplot as plt
# 定义每个班的学生人数
students = [25, 33, 30, 26, 29]
# 创建一个柱状图
plt.bar(range(len(students)), students)
# 添加标题和标签
plt.title('The number of students in each class')
plt.xlabel('class')
plt.ylabel('Number of students')
# 显示图形
plt.show()
3. 修改参数
针对上述问题,我们接下来会将人数显示在上柱状图上面,并且将柱状图的宽度变成0.5,同时横坐标用class1,class2,class3,class4,class5进行标识。修改代码如下:
import matplotlib.pyplot as plt
# 定义每个班的学生人数
students = [25, 33, 30, 26, 29]
# 创建一个柱状图
plt.bar(range(len(students)), students, width=0.5)
# 在每个柱子上添加学生人数的标签
for i in range(len(students)):
plt.annotate(f"{students[i]}", (i, students[i]), textcoords="offset points", xytext=(0,3), ha='center')
# 设置横坐标的标签为特定的字符串标识
plt.xticks(range(len(students)), ['class1', 'class2', 'class3', 'class4', 'class5'])
# 添加标题和标签
plt.title('The number of students in each class')
plt.xlabel('class')
plt.ylabel('Number of students')
# 显示图形
plt.show()
这段代码将在每个柱子的顶部添加学生人数的标签。annotate
函数的第一个参数是要显示的文本,第二个参数是文本的位置,第三个参数textcoords="offset points"
设置了文本的位置相对于图形的点坐标,xytext=(0,10)
设置了文本相对于柱子的偏移量,ha='center'
设置了文本的水平对齐方式为居中。同时,在创建柱状图时指定width=0.5
,将柱子的宽度设置为0.5。
4. error_kw参数
bar()
函数中的error_kw
参数是用于自定义误差条的外观和行为的。它是一个字典,可以包含以下关键字参数:
color
:用于设置误差条的颜色。ecolor
:用于设置误差条边缘的颜色。linewidth
:用于设置误差条线宽。capsize
:用于设置误差条端点的大小。marker
:用于设置误差条端点的标记样式。markersize
:用于设置误差条端点标记的大小。
通过使用error_kw
参数可以自定义误差条的外观和行为,以更好地匹配数据和图表风格。以下是一个使用error_kw
参数的示例:
import matplotlib.pyplot as plt
import numpy as np
# 创建数据
x = np.arange(5)
y = np.random.rand(5)
yerr = np.random.rand(5)
# 绘制条形图并添加误差条
plt.bar(x, y, yerr=yerr, error_kw=dict(ecolor='gray', capsize=5, linewidth=2))
# 设置图表标题和坐标轴标签
plt.title('Example Bar Chart with Error Bars')
plt.xlabel('Category')
plt.ylabel('Value')
# 显示图表
plt.show()
在上面的示例中,我们创建了一组随机数据,并使用bar()
函数绘制了条形图。通过设置error_kw
参数,我们指定了误差条的颜色、边缘颜色、线宽、端点大小和标记样式。有了误差条,妈妈就再也不用担心宝宝的图用大写的T来表示了,哈哈!
5. bottom参数
bar() 函数提供了一个可选参数bottom,该参数可以指定柱状图开始堆叠的起始值,一般从底部柱状图的最大值开始,依次类推。因此,柱状图可以绘画出一种堆叠柱状图。所谓堆叠柱状图就是将不同数组别的柱状图堆叠在一起,堆叠后的柱状图高度显示了两者相加的结果值。
下面是一个不同国家参加奥林匹克运动会所得奖牌(金银铜)的柱状堆叠图示例:
import numpy as np
import matplotlib.pyplot as plt
# 输入数据
countries = ['USA', 'India', 'China', 'Russia', 'Germany']
bronzes = np.array([38, 17, 26, 19, 15])
silvers = np.array([37, 23, 18, 18, 10])
golds = np.array([46, 27, 26, 19, 17])
# 此处的 _ 下划线表示将循环取到的值放弃,只得到[0,1,2,3,4]
ind = [x for x, _ in enumerate(countries)]
#绘制堆叠图
# 金牌在最上面
plt.bar(ind, golds, width=0.5, label='golds', color='gold', bottom=silvers+bronzes)
# 银牌其次
plt.bar(ind, silvers, width=0.5, label='silvers', color='silver', bottom=bronzes)
# 铜牌在最下面
plt.bar(ind, bronzes, width=0.5, label='bronzes', color='#CD853F')
#设置坐标轴
plt.xticks(ind, countries)
plt.ylabel("Medals")
plt.xlabel("Countries")
plt.legend(loc="upper right")
plt.title("2020 Olympics Top Scorers")
plt.show()
6. 并列柱状图
并列柱状图是指在X轴的同一个位置同时绘制多个柱状图,这主要是通过调整柱状图的宽度来实现的,我们还可以将不同类别的柱状图设置成不同的颜色以及纹理使它们更容易区分。
问题:某服装厂主要生产三种类型的裤子,在去年的四个季度中,三种裤子的销售情况分别为[36,29,43],[27,34,39],[30,27,40],[43,40,45],请绘制出该服装厂去年四个季度的三种裤子销售情况的柱状图。
import numpy as np
import matplotlib.pyplot as plt
# 读取裤子销售数据
pants1 = [36,29,43,43]
pants2 = [27,34,39,40]
pants3 = [30,27,40,45]
# 设置横坐标
X = np.arange(4)
# 绘制柱状图
plt.bar(X - 0.2, pants1, color='b', edgecolor='black',hatch='\\', width = 0.2)
plt.bar(X + 0.00, pants2, color='g', edgecolor='black', hatch='*',width = 0.2)
plt.bar(X + 0.2, pants3, color='r', edgecolor='black', hatch='o',width = 0.2)
# 在柱状图上标注数据
for i in range(len(pants1)):
plt.text(i - 0.2, pants1[i] + 0.5, str(pants1[i]), ha='center', fontsize=10)
plt.text(i + 0.0, pants2[i] + 0.5, str(pants2[i]), ha='center', fontsize=10)
plt.text(i + 0.2, pants3[i] + 0.5, str(pants3[i]), ha='center', fontsize=10)
# 设置横坐标名称
X_label = ['quarter1', 'quarter2', 'quarter3', 'quarter4']
# 设置横坐标的标签为特定的字符串标识
plt.xticks(range(len(pants1)), X_label)
# 设置图例标签
label=['pants1','pants2','pants3']
# 设置图表标题和坐标轴标签
plt.title('The pants sales of the clothing factory')
plt.xlabel('Pant type')
plt.ylabel('Sales volume')
# 显示图例和网格线
plt.legend(label)
plt.grid(True)
# 显示图表
plt.show()
在上述代码中,我们使用三组bar()函数来绘制并列的柱状图。通过设置柱状图的宽度width = 0.2来确定横坐标平移的距离,使得每个柱状图恰好紧邻。然后我们通过text()函数来实现数据标识,通过具体的位置来标记每个柱状图的大小。
7. 水平叠堆柱状图
最后,我们再附上一张水平叠堆柱状图的代码:
import matplotlib.pyplot as plt
# 数据
labels = ['A', 'B', 'C', 'D']
values = [20, 35, 30, 35]
sub_labels = ['1', '2', '', '3'] # 为没有子分类的类别添加空字符串或其他适当的值
# 绘制分层条形图
fig, ax = plt.subplots()
ax.barh(labels, values, color='blue', align='center')
for i in range(len(labels)):
# 绘制子分类条形图
ax.barh(labels[i], values[i], left=values[i], color='lightblue', align='center')
# 添加子分类标签
ax.text(0.5, labels[i], sub_labels[i], va='center')
# 添加标题和标签
ax.set_title('clustered bar')
ax.set_xlabel('numerical value')
ax.set_ylabel('category')
ax.set_yticks(labels)
ax.set_yticklabels(labels)
# 显示图形
plt.show()
这样,我们对于柱状图的基础学习就全部结束了,还有结合双轴,绘画子图等等的高级操作,那是融会贯通之后的综合手法,不在基础学习之列。