第一章 使用 matplotlib 绘制折线图
第二章 使用 matplotlib 绘制条形图
第三章 使用 matplotlib 绘制直方图
第四章 使用 matplotlib 绘制散点图
第五章 使用 matplotlib 绘制饼图
第六章 使用 matplotlib 绘制热力图
第七章 使用 matplotlib 绘制堆叠条形图
第八章 使用 matplotlib 在一个画布内绘制多个图
上一章我们讲了折线图的绘制,使用的是 plot 函数。当我们使用 plot 方法绘图时,默认绘制的是折线图。本节课我们来讲下条形图的绘制。
条形图(bar chart)是用宽度相同的条形的高度或长短来表示数据多少的图形,是一种用于对不同类别进行数值比较的统计图表。条形图可以横置或纵置,纵置时也称为柱形图(column chart)。条形图被误用的一个典型代表就是篡改 y 轴,对读者视觉造成误导。在使用条形图时,务必要是原点位于 0。此外,注意对条形图进行排序。依据可视化的目的、以及想突出的重点信息,确定合理的排序标准,避免条形图看起来杂乱无章。
竖直条形图的绘制使用 bar()
函数。示例代码如下:
from matplotlib import pyplot as plt
ages_x = [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
dev_y = [38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752]
plt.bar(ages_x, dev_y, label="全部开发者")
plt.xlabel("年龄")
plt.ylabel("年薪")
plt.title("年龄和薪水的关系")
plt.legend()
plt.show()
在上面的代码中,我们将 plot 函数改为 bar 函数,这样便绘制了条形图。执行完上述代码得到的图形如下图所示:
上面图形中只包含一类数据的条形图,和折线图一样,我们可以在一个图形中做多类数据的条形图,示例代码如下:
from matplotlib import pyplot as plt
ages_x = [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
dev_y = [38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752]
py_dev_y = [45372, 48876, 53850, 57287, 63016, 65998, 70003, 70000, 71496, 75370, 83640]
plt.bar(ages_x, dev_y, label="全部开发者")
plt.bar(ages_x, py_dev_y, label="Python开发者")
plt.xlabel("年龄")
plt.ylabel("年薪")
plt.title("年龄和薪水的关系")
plt.legend()
plt.show()
在上面的代码中,我们又添加了一类数据的条形图,执行完上述代码,得到的图形如下图所示:
从上述图形中,我们可以发现,虽然我们作了两类数据的条形图,但是只显示出一类数据的条形图,这是因为另一类数据的条形图被覆盖了。接下来,我们来解决这个问题。示例代码如下:
import numpy as np
from matplotlib import pyplot as plt
ages_x = [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
x_indexes = np.arange(len(ages_x))
width = 0.33
dev_y = [38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752]
py_dev_y = [45372, 48876, 53850, 57287, 63016, 65998, 70003, 70000, 71496, 75370, 83640]
plt.bar(x_indexes, dev_y, width=width, label="全部开发者")
plt.bar(x_indexes + width, py_dev_y, width=width, label="Python开发者")
plt.xlabel("年龄")
plt.ylabel("年薪")
plt.title("年龄和薪水的关系")
plt.legend()
plt.show()
在上面的代码中,我们创建了一个和列表 ages_x
长度相同的 ndarray(x_indexes)
,在作图时,用 ndarray(x_indexes)
替换横坐标。一类数据的横坐标为 x_indexes
,另一类数据的横坐标为 x_indexes 中每个元素加上一个宽度(width),另外在调用 bar 函数时,传入 width 参数,表示条形图的宽度。执行完上述代码后的图形如下图所示:
仔细观察上述图形,虽然我们将两类数据的条形图分开了,但是横坐标的数据同时也变成了 0~10,这显然是不正确的,因为原来的横坐标为表示年龄的数据,下面我们来解决这个问题。
示例代码如下:
import numpy as np
from matplotlib import pyplot as plt
ages_x = [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
x_indexes = np.arange(len(ages_x))
width = 0.33
dev_y = [38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752]
py_dev_y = [45372, 48876, 53850, 57287, 63016, 65998, 70003, 70000, 71496, 75370, 83640]
plt.bar(x_indexes, dev_y, width=width, label="全部开发者")
plt.bar(x_indexes + width, py_dev_y, width=width, label="Python开发者")
plt.xlabel("年龄")
plt.ylabel("年薪")
plt.title("年龄和薪水的关系")
plt.legend()
plt.xticks(ticks = x_indexes, labels = ages_x)
plt.show()
上面代码中,我们使用 xticks
函数将 x_indexes
替换为 ages_x
。执行完上述代码后的图形如下图所示:
我们发现横坐标的数据变为了年龄。和折线图一样,我们可以使用自带的样式来生成图形,示例代码如下:
import numpy as np
from matplotlib import pyplot as plt
plt.style.use('fivethirtyeight')
ages_x = [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35]
x_indexes = np.arange(len(ages_x))
width = 0.33
dev_y = [38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752]
py_dev_y = [45372, 48876, 53850, 57287, 63016, 65998, 70003, 70000, 71496, 75370, 83640]
plt.bar(x_indexes, dev_y, width=width, label="全部开发者")
plt.bar(x_indexes + width, py_dev_y, width=width, label="Python开发者")
plt.xlabel("年龄")
plt.ylabel("年薪")
plt.title("年龄和薪水的关系")
plt.legend()
plt.xticks(ticks = x_indexes, labels = ages_x)
plt.tight_layout()
plt.show()
我们首先来看使用纵置条形图来绘制有什么问题。示例代码如下:
import numpy as np
from matplotlib import pyplot as plt
languages = ['JavaScript', 'HTML/CSS', 'SQL', 'Python', 'Java', 'Bash/Shell/PowerShell',
'C#', 'PHP', 'C++','TypeScript']
popularity = [59219, 55466, 47544, 36443, 35917, 27097, 23030, 20524, 18523, 18017]
plt.bar(languages, popularity)
plt.title('最流行的编程语言')
plt.xlabel('编程语言')
plt.ylabel('流行度')
plt.tight_layout()
plt.show()
执行完上述代码后的图形如下图所示:
从上图中可以看出,横坐标上的数据标签已经重叠在一起了,下面我们使用横置条形图来改变这种情况,示例代码如下:
import numpy as np
from matplotlib import pyplot as plt
plt.style.use('fivethirtyeight')
languages = ['JavaScript', 'HTML/CSS', 'SQL', 'Python', 'Java', 'Bash/Shell/PowerShell',
'C#', 'PHP', 'C++','TypeScript']
popularity = [59219, 55466, 47544, 36443, 35917, 27097, 23030, 20524, 18523, 18017]
plt.barh(languages, popularity)
plt.title('最流行的编程语言')
plt.xlabel('流行度')
plt.ylabel('编程语言')
plt.tight_layout()
plt.show()
想要绘制横置的条形图,只需要将 bar 函数改为 barh 函数即可。执行完上述代码后生成的图形如下图所示:
改成横置的条形图后,解决了标签重叠的问题。上面的图形中,最流行的语言在图形的最下面,一般情况下,我们希望最流行的语言在最上面,我们只需要对数据进行翻转即可。示例代码如下:
import numpy as np
from matplotlib import pyplot as plt
plt.style.use('fivethirtyeight')
languages = ['JavaScript', 'HTML/CSS', 'SQL', 'Python', 'Java', 'Bash/Shell/PowerShell',
'C#', 'PHP', 'C++','TypeScript']
popularity = [59219, 55466, 47544, 36443, 35917, 27097, 23030, 20524, 18523, 18017]
languages.reverse()
popularity.reverse()
plt.barh(languages, popularity)
plt.title('最流行的编程语言')
plt.xlabel('流行度')
plt.ylabel('编程语言')
plt.tight_layout()
plt.show()
上面的代码中,调用 reverse 函数对列表 languages 和 popularity 进行翻转,执行完上述代码后生成的图形如下图所示:
条形图最适合对分类的数据进行比较。尤其是当数值比较接近时,由于人眼对于高度或长度的感知优于其他视觉元素(如面积、角度等),因此,适用条形图更加合适。
条形图要求至少一个分类变量,它们之间是离散的,绘制条形图时,条形和条形之间有间隔。如果是连续变量,则应当使用直方图,绘制出每个区间的数值,条形之间是连续的、没有间隔。
本章我们讲述了条形图的绘制,包括竖直条形图和水平条形图。还介绍了条形图的适用场景和不适用场景。
上一章 使用 matplotlib 绘制折线图
下一章 使用 matplotlib 绘制直方图