数据可视化 -- Matplotlib②

举报
十八岁讨厌编程 发表于 2022/08/05 23:26:25 2022/08/05
【摘要】 目录 绘制柱状图普通柱状图堆叠柱状图分组柱状图 饼图绘制子图 绘制柱状图 普通柱状图 绘制普通柱状图,我们只需调用 plt.bar() 方法即可。我们需要传入两个参数,第一个参数是 ...

绘制柱状图

普通柱状图

绘制普通柱状图,我们只需调用 plt.bar() 方法即可。我们需要传入两个参数,第一个参数是 x 轴上刻度的标签序列(列表、元组、数组等),第二个参数则用于指定每个柱子的高度,也就是具体的数据。
例如:

names = ['篮球', '羽毛球', '乒乓球']
nums = [26, 20, 19]

plt.bar(names, nums)
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

结果:
在这里插入图片描述
plt.bar() 还有一些可选参数,常用的有 widthcolor,分别用于设置柱子的宽度(默认 0.8)和颜色。
比如我们可以将柱子宽度调小到 0.6,将柱子的颜色设成好看的火红色:

names = ['篮球', '羽毛球', '乒乓球']
nums = [26, 20, 19]

plt.bar(names, nums, width=0.6, color='red')
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

结果:
在这里插入图片描述
注意:
我们前面提到过的的 plt.xlabel()、plt.ylabel()、plt.title() 和 plt.legend() 方法都是通用方法(在plt.bar()中我们也可以传入label参数,不过在普通的柱状图中很少用到),并不只限制于一种图表,所有的图表类型都支持这些方法。
例如:

names = ['篮球', '羽毛球', '乒乓球']
nums = [26, 20, 19]

plt.bar(names, nums, width=0.6, color='red')
plt.title('运动器材数量图')
plt.xlabel('我是横轴')
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果:
在这里插入图片描述
柱状图能直观地展现出不同分类数据上的差异,但有时候我们想更进一步地分析每个分类数据的分布,比如每门选修课的男女比例,这时就需要用到堆叠柱状图。

堆叠柱状图

在画图之前,我们先来看看要画的堆叠柱状图长什么样。
在这里插入图片描述
总体和前面画的柱状图是一样的,只是每个柱子被分成了多块。堆叠柱状图不仅可以展示每一个分类的总量,还能展示该分类包含的每个小分类的大小及占比,因此非常适合处理部分与整体的关系。与饼图显示单个部分到整体的关系不同的是,堆叠柱状图可以显示多个部分到整体的关系。例如编程一班选课的各项目人数统计,你可以用柱状图或饼图来展示。但是,当需要进一步区分男生和女生参与到不同项目中的人数分别是多少时,就需要把每个项目中包含的男生数和女生数都展示出来。如图选用堆叠柱状图,不仅能显示每个项目的总人数,还能展示出每个项目中的一部分与整体的关系。
接下来我们来看看绘制上图的代码:

names = ['篮球', '羽毛球', '乒乓球']
nums_boy = [16, 5, 11]
nums_girl = [10, 15, 8]

plt.bar(names, nums_boy, width=0.6, color='skyblue', label='男')
plt.bar(names, nums_girl, bottom=nums_boy, width=0.6, color='pink', label='女')
plt.legend()
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码和之前相比,多调用了一次 plt.bar() 方法,并传入了 bottom 参数。每调用一次 plt.bar() 方法就会画出对应的柱状图,而 bottom 参数作用就是控制柱状图低端的位置。我们将前一个柱状图的高度传进去,这样就形成了堆叠柱状图。而如果我们没有设置 bottom 参数,后面的图形会盖在原来的图形之上,就像下面这样:
在这里插入图片描述

分组柱状图

分组柱状图经常用于不同组间数据的比较,这些组都包含了相同分类的数据。我们可以先看看分组柱状图长什么样。
在这里插入图片描述
代码如下:

x = np.arange(3)
width = 0.3

names = ['篮球', '羽毛球', '乒乓球']
nums_boy = [16, 5, 11]
nums_girl = [10, 15, 8]

plt.bar(x - width / 2, nums_boy, width=width, color='skyblue', label='男')
plt.bar(x + width / 2, nums_girl, width=width, color='pink', label='女')
plt.xticks(x, names)
plt.legend()
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

首先使用 np.arange(3) 方法创建了一个数组 x,值为 [0 1 2]。并定义了一个变量 width 用于指定柱子的宽度。
在调用 plt.bar() 时,第一个参数不再是刻度上的标签,而是对应的刻度。以 [0 1 2] 为基准,分别加上和减去柱子的宽度得到 [-0.15 0.85 1.85] 和 [0.15 1.15 2.15],这些刻度将分别作为两组柱子的中点,并且柱子的宽度为 0.3。
在这里插入图片描述
因为传入的是刻度,而不是刻度的标签。因此,我们还要调用 plt.xticks() 方法来将 x 轴上刻度改成对应的标签。该方法的第一个参数是要更改的刻度序列,第二个参数是与之对应的标签序列。同理,还可以用 plt.yticks() 方法来更改 y 轴上刻度的标签。

注意:不要与前一篇说过的plt.xlabel()搞混了
plt.xlabel()是用来设置x轴的标签的
而plt.xticks(x, names)是用来将x轴上的刻度替换成对应的标签的

饼图

饼图广泛地应用在各个领域,用于表示不同分类的占比情况,通过弧度大小来对比各种分类。饼图通过将一个圆饼按照分类的占比划分成多个区块,整个圆饼代表数据的总量,每个区块(圆弧)表示该分类占总体的比例大小,所有区块(圆弧)的加和等于 100%。

饼图的画法:只要传入数据和对应的标签给 plt.pie() 方法即可

为了让饼图更加直观清晰,需要了解一些额外的参数。
以 2018 年国内生产总值(GDP)三大产业的占比为例,可以画出这样的饼图:
在这里插入图片描述
代码:

data = [64745.2, 364835.2, 489700.8]
labels = ['第一产业', '第二产业', '第三产业']

plt.pie(data, labels=labels, autopct='%0.1f%%')
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

plt.pie() 方法每个参数的作用:

  • 第一个参数是绘图需要的数据(必选参数)
  • 参数 labels 指定了数据对应的标签(可选参数)
  • 参数 autopct 则给饼图自动添加百分比显示(可选参数)

其中autopct 参数的格式(这里用到了字符串格式化输出的知识):
上述代码中 ‘%0.1f%%’ 可以分为两部分,一部分是 %0.1f 表示保留一位小数,同理 %0.2f 表示保留两位小数。
另一部分是 %%,其实它就表示输出一个 %,因为 % 还字符串格式化输出中有特殊的含义,所以想要输出 % 就得写成 %%。所以,‘%0.1f%%’ 的含义是保留一位小数的百分数,例如:53.3%。

我们还能通过 explode 参数来让饼图中的某一部分突出显示,来强调某项数据。
例如:

data = [64745.2, 364835.2, 489700.8]
labels = ['第一产业', '第二产业', '第三产业']
explode = (0.1, 0, 0)

plt.pie(data, explode=explode, labels=labels, autopct='%0.1f%%')
plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

结果:
在这里插入图片描述
默认 explode 参数里的元素都是 0,我们将需要突出显示的部分对应位置的值设大一点,就能将对应的区块抽离出来突出显示。这个数值越大,抽离的效果就越明显。

绘制子图

到目前我们提到的都是绘制一张图表的方法。但是一张图表很难同时分析多个维度,我们需要把多张图绘制在一起,进行多个维度的查看比较。
Matplotlib 提供了子图的概念,通过使用子图,你可以在一张图里绘制多个图表。

在 matplotlib 中,我们可以调用 plt.subplot() 方法来添加子图。 plt.subplot() 方法的前两个参数分别是子图的行数和列数,第三个参数是子图的序号(从 1 开始)。

例如:

ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 2)
ax3 = plt.subplot(2, 2, 3)
ax4 = plt.subplot(2, 2, 4)

  
 
  • 1
  • 2
  • 3
  • 4

plt.subplot(2, 2, 1) 的作用是生成一个两行两列的子图,并选择其中序号为 1 的子图。所以上面的代码将一张图表分成了 4 个子图,并用 1、2、3、4 来选择对应位置的子图。
在这里插入图片描述
我们也可以不规则的子图,比如上面两张子图,下面一张子图。方法如下:

ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 2)
ax3 = plt.subplot(2, 1, 2)

  
 
  • 1
  • 2
  • 3

在这里插入图片描述
前两个子图的创建你能明白,第三个子图的创建你可能就不太懂了,为什么是 plt.subplot(2, 1, 2) 呢?因为子图序号是独立的,与前面的创建的子图没有关系。plt.subplot(2, 2, 1) 选择并展示了 22 的子图中的第一个,plt.subplot(2, 2, 2) 选择并展示了 22 子图中的第二个,它俩合起来占了 22 的子图的第一行。而 plt.subplot(2, 1, 2) 则是将生成了两行一列的子图,并选择了第二个。即占满第二行的子图,正好填补了之前 22 的子图剩下来的空间。

图表的框架画好了,我们还要往里面绘图。方法很简单,之前调用的是 plt 上的方法绘图,只要将其改成在 plt.subplot() 方法的返回值上调用相应的方法绘图即可。举个例子,下面代码在一张图上绘制了 sin、cos 和 tan 三个函数的图像。

x = np.arange(0, 2 * np.pi, 0.1)

# 子图 1
ax1 = plt.subplot(2, 2, 1)
y1 = np.sin(x)
ax1.plot(x, y1)

# 子图 2
ax2 = plt.subplot(2, 2, 2)
y2 = np.cos(x)
ax2.plot(x, y2)

# 子图 3
ax3 = plt.subplot(2, 1, 2)
y3 = np.tan(x)
ax3.plot(x, y3)

plt.show()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

结果:
在这里插入图片描述

有些人在运行这个程序之后会出现负号显示不出来的情况,可以添加一行代码即可解决:
plt.rcParams[‘axes.unicode_minus’] = False
(plt部分替换为你自己自定义的matplotlib的名字)

文章来源: blog.csdn.net,作者:十八岁讨厌编程,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/zyb18507175502/article/details/122711016

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。