Python数据可视化之美:专业图表绘制指南(全彩)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.1 matplotlib

matplotlib(见链接1)中包含了大量的工具,你可以使用这些工具创建各种图形,包括简单的散点图、正弦曲线,甚至是三维图形。Python科学计算社区经常使用它完成数据可视化工作。在matplotlib面向对象的绘图库中,pyplot是一个方便的接口,其约定俗成的调用形式如下:

3.1.1 图形对象与元素

matplotlib图表的组成元素包括:图形(figure)、坐标图形(axes)、图名(title)、图例(legend)、主要刻度(major tick)、次要刻度(minor tick)、主要刻度标签(major tick label)、次要刻度标签(minor tick label)、Y轴名(Y axis label)、X轴名(X axis label)、边框图(line)、数据标记(markers)、网格(grid)线等。具体如图3-1-1所示。

图3-1-1 matplotlib图表的组成元素

matplotlib主要包含两类元素。

(1)基础(primitives)类:线(line)、点(marker)、文字(text)、图例(legend)、网格(grid)、标题(title)、图片(image)等;

(2)容器(containers)类:图形(figure)、坐标图形(axes)、坐标轴(axis)和刻度(tick)。

基础类元素就是我们要绘制的标准对象,容器类元素则可以包含许多基础类元素并将它们组织成一个整体,它们也有层级结构:图形(figure)→坐标图形(axes)→坐标轴(axis)→刻度(tick),其具体的区别如下:

● figure对象:整个图形即是一个figure对象。figure对象至少包含一个子图,也就是axes对象。figure对象包含一些特殊的artist对象,如图名(title)、图例(legend)。figure对象包含画布(canvas)对象。canvas对象一般不可见,通常无须直接操作该对象,matplotlib程序在实际绘图时需要调用该对象。

● axes对象:字面上理解,axes是axis(坐标轴)的复数,但它并不是指坐标轴,而是子图对象。可以这样理解,每一个子图都有X轴和Y轴,axes则用于代表这两个坐标轴所对应的一个子图对象。常用方法:set_xlim()及set_ylim()——设置子图X轴和Y轴对应的数据范围;set_title()——设置子图的图名;set_xlabel()以及set_ylable()——设置子图X轴和Y轴名。在绘制多个子图时,需要使用axes对象。

● axis对象:axis是数据轴对象,主要用于控制数据轴上的刻度位置和显示数值。axis有locator和formatter两个子对象,分别用于控制刻度位置和显示数值。

● tick对象:常见的二维直角坐标系(axes)都有两条坐标轴(axis),横轴(X axis)和纵轴(Y axis)。每个坐标轴都包含两个元素:刻度(容器类元素),该对象里还包含刻度本身和刻度标签;标签(基础类元素),该对象包含的是坐标轴标签。

当我们需要调整图表元素时,就需要使用图形的主要对象。matplotlib有许多不同的样式可用于渲染绘图,可以用plt.style.available查看系统中有哪些可用的样式。虽然使用plt进行绘图很方便,但是有时候我们需要进行细微调整,一般需要获得图形不同的主要对象包括axes对象及其子对象、figure对象等。

● plt.gca()返回当前状态下的axes对象;

● plt.gca().get_children()可以查看当前axes对象下的元素;

● plt.gcf()返回当前状态下的figure对象,一般用以遍历多个图形的axes对象(plt.gcf().get_axes())。

要画出一幅有内容的图,还需要在容器里添加基础元素,比如线(line)、点(marker)、文字(text)、图例(legend)、网格(grid)、标题(title)、图片(image)等。除图表数据系列的格式外,我们平时主要调整的图表元素,包括图表尺寸、坐标轴的轴名及其标签、刻度、图例、网格线等,如表3-1-1所示。

表3-1-1 图表主要元素调整的函数说明

3.1.2 常见图表类型

matplotlib可以绘制的常见二维图表如表3-1-2所示,包括曲线图、散点图、柱形图、条形图、饼图、直方图、箱形图等。matplotlib绘图的最大的一个问题就是图表的控制参数没能实现很好地统一,比如折线图plot()函数的线条颜色参数为color,而散点图scatter()函数的数据点颜色参数为c。而在plotnine包中将该参数都统一为color,而标记点的填充颜色参数为fill。

表3-1-2 matplotlib常见二维图表的绘制函数

下面我们以“MappingAnalysis_Data.csv”数据集为例(见图3-1-2),讲解如何用matplotlib绘制散点标记的曲线图。我们先使用pd.read_csv()函数导入数据。其中variable有4个类别["0%(Control)","1%","5%","15%"](见图3-1-3)。

图3-1-2 “MappingAnalysis_Data.csv”数据集

图3-1-3 使用matplotlib绘制带标记的曲线图(续)

图3-1-3 使用matplotlib绘制带标记的曲线图

3.1.3 子图的绘制

一幅图中可以有多个坐标系(axes),那是不是就可以说一幅图中有多幅子图(sub plot),因此坐标系和子图是不是同样的概念?其实,这两者在绝大多数情况下是的,只是有一点细微差别:坐标系在母图中的网格结构可以是不规则的;子图在母图中的网格结构必须是规则的,其可以看成是坐标系的一个特例。所以,用matplotlib绘制多幅子图和坐标系主要有两种方式,pyplot方式和axes面向对象的方式。如表3-1-3所示,matplotlib主要有7种子图分区的方法,其中方法1~方法3最为常用。

表3-1-3 matplotlib多幅子图和坐标系的添加方法

其中,subplot()函数的参数有nrows(行)、ncols(列)、index(位置)、projection(投影方式)、polar(是否为极坐标);当projection='3d'时,表示绘制三维直角坐标系;当polar=True时,表示绘制极坐标系。plt.axes([left,bottom,width,height])函数的[left,bottom,width,height]可以定义坐标系left,代表坐标系左边到figure左边的水平距离,bottom代表坐标系底边到figure底边的垂直距离,width代表坐标系的宽度,height代表坐标系的高度。

图3-1-4所示是根据图3-1-3的数据,使用matplotlib绘制的两个子图的效果图。图3-1-4是使用axes方式的subplots()函数构造的两个子图。其核心代码如下所示。

图3-1-4 matplotlib子图绘制案例

3.1.4 坐标系的变换

在编码数据时,需要把数据系列放到一个结构化的空间中,即坐标系,它赋予X、Y坐标或经纬度以意义。图3-1-5展示了3种常用的坐标系,分别为直角坐标系[也称为笛卡儿坐标系(rectangular coordinates)]、极坐标系(polar coordinates)和地理坐标系(geographic coordinates)。它们几乎可以满足数据可视化的所有需求。

图3-1-5 常用坐标系

1.直角坐标系

直角坐标系(rectangular coordinates/cartesian coordinates),也叫笛卡儿坐标系,是最常用的坐标系之一。我们经常绘制的条形图、散点图或气泡图,就是直角坐标系。坐标系所在平面叫作坐标平面,两坐标轴的公共原点叫作直角坐标系的原点。X轴和Y轴把坐标平面分成四个象限,右上面的叫作第一象限,其他三个部分按逆时针方向依次叫作第二象限、第三象限和第四象限。象限以数轴为界,横轴、纵轴上的点不属于任何象限。通常在直角坐标系中的点可以记为(x,y),其中x表示X轴的数值,y表示Y轴的数值。使用matplotlib绘制图表时默认为二维直角坐标系。

matplotlib也可以实现三维直角坐标系,其投影方法默认为透视投影(perspective projection),添加三维直角坐标系的方法为:

matplotlib可以使用不同的函数绘制三维散点图、折线图、柱形图、面积图和曲面图等,如表3-1-4所示。其中较为常用的是三维散点图和三维曲面图(见图3-1-6)。使用ax.view()函数可以调整图表的视角,即相机的位置,azim表示沿着Z轴旋转,elev表示沿着Y轴旋转。

表3-1-4 matplotlib三维图表绘制函数及其说明

图3-1-6 matplotlib三维图表

直角坐标系还可以扩展到多维空间。例如,三维空间可以用(x,y,z)三个值对来表示三维空间中数据点的位置。如果再拓展到平行坐标系(parallel coordinates),则可以用于对高维几何和多元数据的可视化。

2.极坐标系

极坐标系(polar coordinates)是指在平面内由极点、极轴和极径组成的坐标系。在平面上选定一点O,称为极点。从O出发引一条射线Ox,称为极轴。再定一个单位长度,通常规定角度取按时针方向为正。这样,平面上任一点P的位置就可以用线段OP的长度ρ,以及从Ox到OP的角度θ来确定,有序数对(ρ,θ)就称为P点的极坐标,记为P(ρ,θ);ρ称为P点的极径,指数据点到圆心的距离,θ称为P点的极角,指数据点距离最右边水平轴的角度。

极坐标系的最右边点是零度,角度越大,逆时针旋转越多。距离圆心越远,半径越大。极坐标系在绘图中没有直角坐标系用得多,但在角度和方向两个视觉暗示方面有很好的优势,往往可以绘制出出人意料的精美图表。matplotlib可以通过如下语句将坐标系设置为极坐标系:

另外,通过如下语句可以进一步调整matplotlib极坐标系的默认设置:

选择合适的坐标系对数据的清晰表达也很重要,直角坐标系与极坐标系的转换如图3-1-7所示。使用极坐标系可以将数据以365天围绕圆心排列。极坐标系图可以让用户方便地看到数据在周期上、方向上的变化趋势,而对连续时间段变化趋势的显示不如直角坐标系。

图3-1-7 坐标系的转换

极坐标系的表示方法为P(ρ,θ),平面直角坐标系的表示方法为Q(x,y)。极坐标系中的两个坐标r和θ可以由下面的公式转换为直角坐标系下的坐标值:

从直角坐标系中的x和y坐标可以计算出极坐标系下的坐标值:

其中,要满足x不等于0;在x=0的情况下:若y为正数,则θ=90°(π/2);若y为负数,则θ=270°(3π/2)。

3.1.5 图表的导出

plt.savefig()函数可以将matplotlib图表导出不同的格式,包括PDF、PNG、JPG、SVG等,其中导出PDF格式图表的代码如下所示。需要注意的是:要在plt.show()之前调用plt.savefig()。