Matplotlib和seaborn的使用
在这一章,我们介绍如何利用Python中的Matplotlib和seaborn这两个包,进行各种图表的绘制。
介绍
数据可视化,或者说绘图,是数据分析中最重要的工作之一。绘图可能是数据探索过程的一部分,例如帮助我们找出异常值、进行必要的数据转换、得出有关模型的想法等。绘图也可以用于结果分析和呈现,画出图表或者做一个可交互的数据可视化也许是数据分析工作的最终目标。在这一部分,我们学习如何在Python中使用Matplotlib和seaborn进行各种类型图像的绘制。
Matplotlib是一个用于创建出版质量图表的桌面绘图包,由John Hunter于2002年启动,其目的是为Python构建一个MATLAB式的绘图接口。Matplotlib和IPython社区进行合作,简化了从IPython shell(包括现在的Jupyter notebook)进行交互式绘图。Matplotlib支持各种操作系统上许多不同的GUI后端,而且还能将图片导出为各种常见的矢量(vector)和光栅(raster)图,例如PDF、SVG、JPG、PNG、BMP、GIF等。
随着时间的发展,Matplotlib衍生出了多个数据可视化的工具集,它们使用Matplotlib作为底层。Pandas自身就内置了很多画图的方法,用于简化从DataFrame和Series绘制图形。另一个库seaborn是由Michael Waskom创建的静态图形库,简化了许多图表的创建代码。
1. Matplotlib绘图
1.1 Matplotlib引入
Matplotlib的通常引入约定是:
import matplotlib import matplotlib.pyplot as plt
为了让Matplotlib生成的图片在Jupyter Notebook中更好地显示,我们可以指定图片输出的格式为svg:
%config InlineBackend.figure_format = 'svg'
我们来看一个最简单的例子,如何画出一组数据的形状:
import numpy as np data = np.arange(10) plt.plot(data)
Matplotlib画出来的图像如下图所示:
1.2 Figure和SubPlot
Matplotlib的图像都位于Figure对象中。我们可以用plt.figure创建一个新的Figure:
fig = plt.figure(figsize=[6,4])
不过我们不能通过空的Figure进行绘图,必须用add_subplot创建一个或多个subplot才行:
fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) ax1.plot(np.random.randn(50).cumsum(), 'k--') ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3) ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
其中
ax1 = fig.add_subplot(2, 2, 1)
的意思是:图像应该是2×2的(即最多4张图),且当前ax1选中的是4个subplot中的第一个(编号从1开始)。ax1.plot(np.random.randn(50).cumsum(), 'k--')
的意思是在ax1对应的subplot中画一个折线图,"k--"是一个线型选项,用于告诉Matplotlib绘制黑色虚线图。ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
的意思是在ax2对应的subplot中画一个直方图,bins表示我们要把数据分成20组,然后统计每组的数据个数,color表示颜色,alpha设置透明度。ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
的意思是画一个散点图,第一个参数为x坐标的列表,第二个参数为y坐标的列表。
绘制出的图像如下图所示:
这几种图表是最标准的图像类型,更多的参数设置可以在matplotlib的文档中找到更详细的说明:https://matplotlib.org/2.2.4/api/index.html
创建包含subplot网格的figure是一个非常常见的任务,matplotlib有一个更为方便的方法plt.subplots,它可以创建一个新的Figure,并返回一个含有已创建的subplot对象的NumPy数组:
fig, axes = plt.subplots(2, 2) print(axes)
输出为:
[[<matplotlib.axes._subplots.AxesSubplot object at 0x0000022CB6683DD8> <matplotlib.axes._subplots.AxesSubplot object at 0x0000022CB66C7208>] [<matplotlib.axes._subplots.AxesSubplot object at 0x0000022CB66EE5F8> <matplotlib.axes._subplots.AxesSubplot object at 0x0000022CB6714AC8>]]
同时也会展示一个空的图:
1.3 调整subplot周围的间距
默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关。我们可以通过Figure的subplots_adjust函数修改间距:subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
,其中wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距。举例如下,间距收缩到了0:
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True) for i in range(2): for j in range(2): axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5) plt.subplots_adjust(wspace=0, hspace=0) # 各subplot之间没有间距
输出的图像如下图所示:
1.4 颜色、标记和线型
Matplotlib的plot函数接受一组X和Y坐标,还可以接受一个表示颜色和线型的字符串缩写。例如,要根据x和y绘制绿色虚线,我们可以执行如下代码:
x = [1, 2, 3, 4, 5] # x坐标一般按照从小到大的顺序排列好 y = [3, 7, 2, 4, 6] # plt.plot(x, y, 'g--') plt.plot(x, y, linestyle='--', color='g') # 分别指明linestyle和color这两个参数也可以实现一样的功能
画出的图像如下图所示:
Matplotlib支持多种线型,可以参考文档:https://matplotlib.org/2.2.4/api/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D.set_linestyle
我们可以给每个数据点加上标记marker,标记也可以放到格式字符串中,但标记类型和线型必须放在颜色后面:
x = [1, 2, 3, 4, 5] # x坐标一般按照从小到大的顺序排列好 y = [3, 7, 2, 4, 6] # plt.plot(x, y, 'r--o') plt.plot(x, y, linestyle='--', color='r', marker='o') # 指明marker='o'可以实现一样的功能
画出的图像如下图所示:
Matplotlib中支持很多标记,可以参考文档:https://matplotlib.org/2.2.4/api/markers_api.html#module-matplotlib.markers
1.5 设置标题、轴标签、刻度以及刻度标签
要设置标题的时候,我们可以用set_title,要设置轴标签时,我们可以用set_xlabel和set_ylabel。要改变X轴刻度,最简单的办法是使用set_xticks和set_xticklabels。前者告诉Matplotlib要将刻度放在数据范围中的哪些位置,默认情况下,这些位置也就是刻度标签。但我们可以通过set_xticklabels将任何其他的值用作标签,并设置字体大小、旋转角度等参数。改变Y轴刻度的方法类似。
fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(np.random.randn(1000).cumsum()) # 绘制一段随机生成的数据的累积和 ax.set_xticks([0, 250, 500, 750, 1000]) # 设置x轴刻度的位置 # 设置刻度标签 # rotation选项设定x刻度标签倾斜30度 # fontsize设定x刻度标签的字体大小 ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small') ax.set_title('This is the title') # 设置标题 ax.set_xlabel('This is x label') # 设置x轴标签 ax.set_ylabel('This is y label') # 设置y轴标签
画出的图像如下图所示:
我们也可以批量设定绘图选项:
fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(np.random.randn(1000).cumsum()) # 绘制一段随机生成的数据的累积和 ax.set_xticks([0, 250, 500, 750, 1000]) # 设置x轴刻度的位置 # 设置刻度标签 # rotation选项设定x刻度标签倾斜30度,设置为负数会朝着另一个方向倾斜 # fontsize设定x刻度标签的字体大小 ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small') props = { 'title': 'This is the title', 'xlabel': 'This is x label', 'ylabel': 'This is y label' } ax.set(**props)
1.6 添加图例
图例(legend)是一种用于标识图表元素的重要工具,特别是当我们在一张图里面画有多条曲线的时候。添加图例的方式有多种。最简单的是在添加subplot的时候传入label参数:
from numpy.random import randn fig = plt.figure() ax = fig.add_subplot(1, 1, 1) # 我们仍然产生一些随机数来进行绘图 ax.plot(randn(1000).cumsum(), 'k', label='one') ax.plot(randn(1000).cumsum(), 'r--', label='two') ax.plot(randn(1000).cumsum(), 'b.', label='three') # 然后我们用ax.legend()或plt.legend()来自动创建图例 # 参数loc会指定图例在图片中的位置,例如左上角还是右下 # loc='best'会让程序自动判断合适的位置 ax.legend(loc='best')
画出的图像如下图所示:
要从图例中去除一个或多个元素,不传入label或传入label='nolegend'即可。
1.7 注解以及在Subplot上绘图
除标准的绘图类型,我们可能还希望绘制一些子集的注解,可能是文本、箭头或其他图形等。注解和文字可以通过text、arrow和annotate函数进行添加。text可以将文本绘制在图表的指定坐标(x,y),还可以加上一些自定义格式:
fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(np.random.randn(1000).cumsum()) x = 100 y = 10 ax.text(x, y, 'Hello world!', family='monospace', fontsize=10)
画出的图像如下图所示:
注解中可以既含有文本也含有箭头。接下来通过一个比较复杂的例子来感受一下效果,我们根据美国的标准普尔500指数价格(来自Yahoo!Finance)绘制一张曲线图,并标出2008年到2009年金融危机期间的一些重要日期。
fig = plt.figure() ax = fig.add_subplot(1, 1, 1) # 我们读取本地的一个csv数据集 import pandas as pd data = pd.read_csv('./stock_px.csv', index_col=0, parse_dates=True) # 使用spx这一列数据 spx = data['SPX'] # 直接调用pandas的series的plot函数 spx.plot(ax=ax, style='k-') # 这些是我们要标注的内容 # 因为我们的x轴是时间点,因此这个列表就表示了某个时间点发生的事件 from datetime import datetime crisis_data = [ (datetime(2007, 10, 11), 'Peak of bull market'),
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
<p> 在这个专刊中,我们会学习Python在金融中的应用: ·掌握Python进行数据分析和处理的方法; ·了解Python在量化投资中的应用; ·转行到金融数据分析和量化交易领域的基础等内容。 这个专刊适合: ·想要学习Python编程的在校学生; ·想要转行到金融领域的在职人士; ·想要利用业余时间进行量化投资的在职人士等。 本专刊购买后即可解锁所有章节,故不可以退换哦~ </p>