![Python数据可视化之美:专业图表绘制指南(全彩)](https://wfqqreader-1252317822.image.myqcloud.com/cover/380/31186380/b_31186380.jpg)
3.1 matplotlib
matplotlib(见链接1)中包含了大量的工具,你可以使用这些工具创建各种图形,包括简单的散点图、正弦曲线,甚至是三维图形。Python科学计算社区经常使用它完成数据可视化工作。在matplotlib面向对象的绘图库中,pyplot是一个方便的接口,其约定俗成的调用形式如下:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_50_2.jpg?sign=1739136139-FxdzKiruKuoxT5BDZKhJEcAtmX9wvP9o-0-4e9ec42e2a96b33c8824ef3490a923c5)
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所示。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_51_1.jpg?sign=1739136139-dyjSLY6nnkQfga7I8pxgzsVg8TUHh50W-0-d1e7250540fa7118c09921fc8fa7c3cf)
图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 图表主要元素调整的函数说明
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_52_1.jpg?sign=1739136139-yCRXRrhEOU5QHwDN5MC4Y5FYWpqOySGF-0-4773a264c2429cfeeee5e36a8230ad7e)
3.1.2 常见图表类型
matplotlib可以绘制的常见二维图表如表3-1-2所示,包括曲线图、散点图、柱形图、条形图、饼图、直方图、箱形图等。matplotlib绘图的最大的一个问题就是图表的控制参数没能实现很好地统一,比如折线图plot()函数的线条颜色参数为color,而散点图scatter()函数的数据点颜色参数为c。而在plotnine包中将该参数都统一为color,而标记点的填充颜色参数为fill。
表3-1-2 matplotlib常见二维图表的绘制函数
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_53_1.jpg?sign=1739136139-tr0rTwx8qs8rpsKDWOUOJ5XLh2vyRGS1-0-be75c3116bd2cd7410e9907336d0cbc1)
下面我们以“MappingAnalysis_Data.csv”数据集为例(见图3-1-2),讲解如何用matplotlib绘制散点标记的曲线图。我们先使用pd.read_csv()函数导入数据。其中variable有4个类别["0%(Control)","1%","5%","15%"](见图3-1-3)。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_54_2.jpg?sign=1739136139-B73Xs7Dmnr0V4zq34ZPEuSavRGhtLFk8-0-39c51ea3af5a6c3f04d46ec0b7e2e63d)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_54_3.jpg?sign=1739136139-nOlXLidNyi3oqsSkMVeHgeETLxdGtzbn-0-b8a1187ae0047d57100e37303ede8988)
图3-1-2 “MappingAnalysis_Data.csv”数据集
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_54_4.jpg?sign=1739136139-0cVCC7ueib65uBcKmWvKxFgxxChPBE9j-0-b02b43441a6bb17dcbe107f85cf7508c)
图3-1-3 使用matplotlib绘制带标记的曲线图(续)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_55_1.jpg?sign=1739136139-G3DFVKcEaTHSrdcjS87CLFp2WtdxESxy-0-7322d34e2e02879f8a2ca8e9e18980a1)
图3-1-3 使用matplotlib绘制带标记的曲线图
3.1.3 子图的绘制
一幅图中可以有多个坐标系(axes),那是不是就可以说一幅图中有多幅子图(sub plot),因此坐标系和子图是不是同样的概念?其实,这两者在绝大多数情况下是的,只是有一点细微差别:坐标系在母图中的网格结构可以是不规则的;子图在母图中的网格结构必须是规则的,其可以看成是坐标系的一个特例。所以,用matplotlib绘制多幅子图和坐标系主要有两种方式,pyplot方式和axes面向对象的方式。如表3-1-3所示,matplotlib主要有7种子图分区的方法,其中方法1~方法3最为常用。
表3-1-3 matplotlib多幅子图和坐标系的添加方法
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_56_1.jpg?sign=1739136139-NyUVjutNj6awCQD9vnMfsPq1W6RvHusx-0-f13d51d6cb3331f2764bbacf4ff674e0)
其中,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()函数构造的两个子图。其核心代码如下所示。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_57_2.jpg?sign=1739136139-NNL308hP4uhanSnGiJpXJOIl6NRwznId-0-3052488e241724f40f5be603004cb676)
图3-1-4 matplotlib子图绘制案例
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_57_3.jpg?sign=1739136139-bVsPlbTrVotSpn5zlsfkclJRCaQxBbYn-0-5594c1f9621d2d3731b1014e191f9816)
3.1.4 坐标系的变换
在编码数据时,需要把数据系列放到一个结构化的空间中,即坐标系,它赋予X、Y坐标或经纬度以意义。图3-1-5展示了3种常用的坐标系,分别为直角坐标系[也称为笛卡儿坐标系(rectangular coordinates)]、极坐标系(polar coordinates)和地理坐标系(geographic coordinates)。它们几乎可以满足数据可视化的所有需求。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_58_2.jpg?sign=1739136139-aJyx98ZuO8sC8TlM6874PR73sn3bD0Sz-0-209eb66fbfe50363132acb7673ef7a1e)
图3-1-5 常用坐标系
1.直角坐标系
直角坐标系(rectangular coordinates/cartesian coordinates),也叫笛卡儿坐标系,是最常用的坐标系之一。我们经常绘制的条形图、散点图或气泡图,就是直角坐标系。坐标系所在平面叫作坐标平面,两坐标轴的公共原点叫作直角坐标系的原点。X轴和Y轴把坐标平面分成四个象限,右上面的叫作第一象限,其他三个部分按逆时针方向依次叫作第二象限、第三象限和第四象限。象限以数轴为界,横轴、纵轴上的点不属于任何象限。通常在直角坐标系中的点可以记为(x,y),其中x表示X轴的数值,y表示Y轴的数值。使用matplotlib绘制图表时默认为二维直角坐标系。
matplotlib也可以实现三维直角坐标系,其投影方法默认为透视投影(perspective projection),添加三维直角坐标系的方法为:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_58_3.jpg?sign=1739136139-CkkMSxXuAr3XTAtCbLXyQj31j7IzubZs-0-e1ca7e9a9face0f8f491413e302088f1)
matplotlib可以使用不同的函数绘制三维散点图、折线图、柱形图、面积图和曲面图等,如表3-1-4所示。其中较为常用的是三维散点图和三维曲面图(见图3-1-6)。使用ax.view()函数可以调整图表的视角,即相机的位置,azim表示沿着Z轴旋转,elev表示沿着Y轴旋转。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_59_2.jpg?sign=1739136139-r4s40dskbJrdjjWbjtjPMFOQbCqUJawV-0-c32238a8664e43956955c4ef8329c981)
表3-1-4 matplotlib三维图表绘制函数及其说明
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_59_3.jpg?sign=1739136139-dYunX7STkequh0PvYMXTcmOHZ0gSGDGn-0-0c3a6146fe920d3c204e2edf89423ab3)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_59_4.jpg?sign=1739136139-Y2Dhn38a4IfNp5GgULXpk7T5kIzFb0y0-0-c51c70e4f562c016fea8a581577147e9)
图3-1-6 matplotlib三维图表
直角坐标系还可以扩展到多维空间。例如,三维空间可以用(x,y,z)三个值对来表示三维空间中数据点的位置。如果再拓展到平行坐标系(parallel coordinates),则可以用于对高维几何和多元数据的可视化。
2.极坐标系
极坐标系(polar coordinates)是指在平面内由极点、极轴和极径组成的坐标系。在平面上选定一点O,称为极点。从O出发引一条射线Ox,称为极轴。再定一个单位长度,通常规定角度取按时针方向为正。这样,平面上任一点P的位置就可以用线段OP的长度ρ,以及从Ox到OP的角度θ来确定,有序数对(ρ,θ)就称为P点的极坐标,记为P(ρ,θ);ρ称为P点的极径,指数据点到圆心的距离,θ称为P点的极角,指数据点距离最右边水平轴的角度。
极坐标系的最右边点是零度,角度越大,逆时针旋转越多。距离圆心越远,半径越大。极坐标系在绘图中没有直角坐标系用得多,但在角度和方向两个视觉暗示方面有很好的优势,往往可以绘制出出人意料的精美图表。matplotlib可以通过如下语句将坐标系设置为极坐标系:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_60_1.jpg?sign=1739136139-SI4szf3Jl6CAw6yBflYhPKcZgaUop8tb-0-dbcbd9cf7c07b84f8ecea4c5764de68f)
另外,通过如下语句可以进一步调整matplotlib极坐标系的默认设置:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_60_2.jpg?sign=1739136139-r5KgtvGq4b5mHrEC0rLz1axr4HNAPcrv-0-8efac8865475dabe0853423445c29969)
选择合适的坐标系对数据的清晰表达也很重要,直角坐标系与极坐标系的转换如图3-1-7所示。使用极坐标系可以将数据以365天围绕圆心排列。极坐标系图可以让用户方便地看到数据在周期上、方向上的变化趋势,而对连续时间段变化趋势的显示不如直角坐标系。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_61_1.jpg?sign=1739136139-5hFqx0l7qhns388cZww1JWKorbkTUlcN-0-c024641a7c4ee87ebf0f3851eb1fc309)
图3-1-7 坐标系的转换
极坐标系的表示方法为P(ρ,θ),平面直角坐标系的表示方法为Q(x,y)。极坐标系中的两个坐标r和θ可以由下面的公式转换为直角坐标系下的坐标值:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_60_3.jpg?sign=1739136139-DZHTo0rK1pq77ahE2QPrPsmH74w39N07-0-1aed2b3d9f75430829361ad5e6910eeb)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_60_4.jpg?sign=1739136139-gaCObZcjoh5CsLaOJgvnok5yyc2R0yYM-0-65e7f419f8d4c1b2ec01d3f7301e55f0)
从直角坐标系中的x和y坐标可以计算出极坐标系下的坐标值:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_60_5.jpg?sign=1739136139-NdLtkogJ238aqIEXJ5weJp7PeQlrcVOC-0-6c2261213b982e2bc9355149e01735ec)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_60_6.jpg?sign=1739136139-F7fRrD4GrXGCxRscE96bTdBVIcTri2Jk-0-1edf287296d7a1234af0688cf4cb1fda)
其中,要满足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()。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_61_2.jpg?sign=1739136139-XZC0lLIO2ykG9Oa2ojHEQGt0zp42NeNA-0-a3b2e4287057dcea77f8254c4a4cf5d3)