前言
Python 可视化库非常多,其中 matplotlib 是优缺点明显的一个库,优点是他非常灵活,缺点就是学习起来相对复杂。
最近在整理 matplotlib 入门所需核心知识点,会顺带编写各种练习,其中主要关注如何获得快速自学 matplotlib 的思路。
本文目标图表如下:
- 每年小麦产量柱状图
- 使用不同颜色标记最小与最大值的柱子
- 画出均值线
matplotlib 有2种风格的 api:
- MATLAB 风格,适合数据探索(图表没有过多细节要求,主要能反映数据情况即可)
- 面向对象风格,适合编写重复自动化的图表任务或封装各种图表功能
面向对象风格非常适合入门,因此我统一使用这种风格
本文所需要的库如下:
基本套路
本次使用 vega_datasets 的小麦数据:
- 其中 year 与 wheat 是我们需要的数据
类似在一张纸上画出多种图表,其中纸就是放置图表的容器。在 matplotlib 中,这个容器称为 Figure。
因此,代码如下:
- 使用 plt.subplots() 能生成新的 figure 与 axes
"axes 是啥玩意?"
其中 axes 就是坐标系,可以把他看作是一个图表。
subplots 默认参数下,只会生成1个图表,因此现在看起来就是"这张纸(Figure)被1个图表(axes)占满"。
显然,我们需要在 axes 上添加图表各种细节,最重要的当然是数据:
- 行2:在 axes 中画柱状图(bar),第一个参数 x 轴使用 年份数据,第二个参数柱子高度使用 wheat 列数据
但是,图表看起来有问题:
- 因为 df.year 是数值,图表按照连续数字定位 x 轴上的位置
修改数据源的类型:
现在,柱子像点样子,但是 x 轴上乱七八糟:
虽然此时图表还没有做大最终效果,但是基本形状已经出来。
接下来基本是细节操作。
初学者难以入门 matplotlib 其中一个原因是,他的方法很多,很多时候你甚至不知道如何在网上查找。
接下来就是我要介绍的,如何利用 matplotlib 的帮助,推测出我们需要的方法
各种细节的调整
首先,我们希望调整 x 轴上刻度标签的显示角度。
在 matplotlib 中对应这些概念:
- 轴:axis
- 刻度:tick
- 标签:label
通常我们的操作都是基于 axes ,因为我们总是在操作某个图表。
看看这个 axes 有什么可以让我们操作的:
- 行1:直线 plt.setp(对象),可以查看对象有哪些可以设置的属性
- plt.setp 本身是一种批量修改值的快捷方法
看了一下,找到我们的目标:
怎么获取,非常简单:
- 前缀 下划线 属性名就能调用
"但是我们需要设置的是这些刻度标签的角度,拿一堆刻度标签有啥用?"
显然,调整角度是需要设置这些"刻度标签"对象的某个属性,按照之前的方法,查看一下:
- axes.get_xticklabels()[0] ,随意拿出第一个刻度标签对象,看看他里面有啥玩意
果然,找到需要的属性:
万事俱备了:
- 行5:从 axes 中获取所有 x 轴的刻度标签,注意这是一个 list
- 行6:plt.setp 能批量对多个东西设置属性,显然我们这里需要对前一行得到的多个刻度标签设置 rotation 为 90 度
图表成这样子:
"好像没多大改善呀"
这是因为我们的"图纸"不够宽,空间有限,自然要压缩"图纸"中的内容。
适当调整"图纸"的大小:
- 行3:传入相应参数即可
现在效果如下:
"我怎么知道这个 subplots 方法中可以设置这个参数?"
这需要查看他的文档,但是,之前我们已经学过查看某个东西可以调整的属性。
我们可以换另一种方式实现一样的效果。
用 plt.setp 方式,找到属性 figwidth ,显然这是"图纸"的宽度,于是可以这么写:
- 行4:set_figwidth 即可设置
- 怎么设置高度,不用我教了吧
做到这里,你应该会觉得任意使用一个可视化的库,可能1、2行代码即可完成,为啥要折腾这么多?
matplotlib 的灵活在于控制细节。
接下来需要把最小与最大值的柱子标记不同颜色
设置颜色
面向对象设计,意味着图表上你能看到的东西基本上都有一种对象代表他。
现在我们需要找到图表生成的每个柱子。他们在哪里?
原来,本身当我们调用 axes.bar 方法时,这个方法返回的就是这些小柱子:
显然,这是一个集合,我们需要修改其中的某几个柱子的颜色,老规矩查到属性:
现在只需要找到哪个是最小和最大值的柱子就行了:
- pandas 的方法就不多说了
均值线有特定的方法:
这里涉及一个比较高级的概念——投影与转换,这里不作介绍
图表如下:
接下来就是其他修饰
其他点缀
觉得图表风格有些单调?
看看有哪些内置风格可以选:
选用 ggplot 看看效果:
- plt.style.use 这种全局设置,最好放置在 import 之后
现在看起来有点辣眼睛:
- 因为每种内置风格都会有独特的颜色板,但我们画柱状图时没有指定颜色,因此当你使用其他风格时,可能会导致默认图表颜色改变的情况。以后使用调色板时,我们尝试动态从调色板取出标记颜色(上面的橙色与红色)
再设置一下 x、y 轴的名字与整个图表的标题。
用之前的方式,从 axes 中可以轻易找到需要的属性:
- 行18:当要对一个对象同时设置多个属性时,使用 对象.set 方法,即可批量设置
但是,字体有些小:
好吧,全局设置字体大小:
- 必须在设置风格之后,再单独修改某些设置
接下来我会继续编写更多非常规要求的图表,敬请关注!