信息可视化是数据分析的一块重要内容。这是一个探索性的过程。比如说,可以帮助我们坚定离群值,或者必要的数据转换,又或者是构建一个理想的模型。对于其他的一些领域,也可以进行web可视化。Python有许多的扩展库可以进行静态或者动态的可视化,但是在这一章里,书的作者只focus on在matplotlib以及建立在之上的库。
matplotlib是一个桌面绘图包,用于绘制(主要是二维的)发表用的图。该项目由John Hunter在2002年启动,目的是在Python中使用类似matlab的绘图界面。matplotlib和IPython协作简化了IPython shell(现在是Jupyter笔记本)中的交互式绘图。matplotlib支持所有操作系统上的各种GUI后端,此外还可以导出可视化到所有常见的格式中(PDF、SVG、JPG、PNG、BMP、GIF等)。
在Jupyter notebook里使用matlpotlib的方法很简单(关于如何使用jupyter notebook的网页版请见我之前的文章:ipython的初步了解):
%matplotlib notebook
第一节 Matplotlib的初步了解
在Jupyter notebook输入%matplotlib notebook,或者在ipython里输入%matplotlib后,可以调用matplotlib:
In [3]: import matplotlib.pyplot as plt
先来画一个最最最简单的直线吧:
In [4]: import numpy as np
In [5]: data = np.arange(10)
In [6]: data
Out[6]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [7]: plt.plot(data)
(一)Figures and Subplots
在matlibplot里,plots属于Figure对象。你可以使用plt.figure
函数创建一个新的图:
In [8]: fig = plt.figure()
在ipython里,上面的代码会显示出一张空白的图。你可以使用add_subplot
函数来增加图形:
In [9]: ax1 = fig.add_subplot(2, 2, 1)
这行代码的意思是:我们要绘制2行2列,一共4张图,而后面的1代表我们现在选中的是第一个图。那么运行这行代码,刚才上面一片空白的图会变成下面这样:
然后继续添加图形:
In [10]: ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
这里需要强调的是:jupyter notebook里的matplotlib的图形绘制在每一个cell里会被重置,也就是说,你如果要绘制很复杂的图形,最好把所有的代码都放在同一个cell里
举个例子,上面的创建图形的代码可以写在同一个cell里:
这时,如果你想绘制plt.plot([1.5, 3.5, -2, 1.6])的时候,matlpotlib会把图形画在最后一个创建的子图里面:
In [13]: plt.plot([1.5, 3.5, -2, 1.6])
Out [13]: [<matplotlib.lines.Line2D at 0x7f462574f590>]
这时如果你再加一行代码:
In [14]: plt.plot(np.random.randn(50).cumsum(), 'k--')
Out [14]: [<matplotlib.lines.Line2D at 0x7f4625737110>]
你会发现新的图被直接加到了原来的第三张图上面:
'k--'的意思是在matplotlib里画一条黑色的虚线。在其他空白的地方添加图形:
In [15]: _ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
Out [15]: <matplotlib.collections.PathCollection at 0x7f46256f75d0>
(1)Adjusting the spacing around subplots调整子图之间的间距
默认参数下,matplotlib在子图之间留有间隔。该间距都是相对于图形的高度和宽度调整的,你可以通过代码或使用GUI窗口手动调整图形的大小。你可以在图形对象上使用subplots_adjust
方法改变间距,格式如下:
subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
wspace
和hspace
控制图形宽度和高度的百分比,以控制子图之间的空间。下面是一个小例子:
In [16]: 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)#这里设置空隙是0,子图之间就是连接起来的
(二)Colors, Markers, and Line Styles
Matplotlib的主函数接受x和y坐标数组,也可以接受表示颜色和线条样式的字符串缩写。例如,要用绿色破折号绘制x和y,用如下代码:
ax.plot(x, y, 'g--')
也可以在字符串中同时指定颜色和线条样式:
ax.plot(x, y, linestyle='--', color='g')
线图上还可以标记突出实际数据点。由于matplotlib创建了一个连续的线图,连接点的之间,有时会不清楚每一个数据的位置。添加标记可以是样式字符串的一部分,它必须有颜色、标记类型和线条样式:
In [17]: fig = plt.figure()
from numpy.random import randn
plt.plot(randn(30).cumsum(), 'ko--')
(三)Ticks, Labels, and Legends
为交互使用而设计的pyplot包括xlim、xticks, xticklabels参数。这些控制绘图范围、刻度位置和刻度标签。它们可以以两种方式使用:
•不设置参数返回当前参数值(例如:plt.xlim())返回当前的x轴绘制范围)
•调用参数设置参数值(例如:plt.xlim([0, 10]),x轴范围为0到10)
(1)设置标题,坐标轴标签,刻度,刻度标签
In [17]: fig = plt.figure() #创建一个新的空白图
ax = fig.add_subplot(1, 1, 1) #设置图的个数,1行*1列,将下面的代码绘制到第一个图里
ax.plot(np.random.randn(1000).cumsum()) #绘图
然后使用set_xticks
和set_xticklabels
参数添加标题和坐标刻度:
方法一:
In [18]: ticks = ax.set_xticks([0, 250, 500, 750, 1000])
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'],rotation=30, fontsize='small')
ax.set_xlabel('Stages')
ax.set_title('My first matplotlib plot')
方法二:
In [19]: props = {
'title': 'My first matplotlib plot',
'xlabel': 'Stages'
}
ax.set(**props)
(2)添加注释(Legends)
使用.legend
添加注释。
In [20]: 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(), 'k--', label='two') #虚线
ax.plot(randn(1000).cumsum(), 'k.', label='three') #点图
ax.legend(loc='best') #loc='best'指选择一个最合适的位置来绘图
(四)Annotations and Drawing on a Subplot
有时在画图的时候,你可能需要标注特定的文本、箭头等等。你可以使用text
, arrow
, annotate
函数添加annotation和文本。比如像这样的代码:
ax.text(x, y, 'Hello world!', family='monospace', fontsize=10)
下面看一个例子,示例csv文件的下载地址:https://github.com/YanFang0620/shared-paper/blob/master/pydata-book-master_ch09_stock_px.csv
In [1]: import pandas as pd
In [2]: data = pd.read_csv('./spx.csv', index_col=0, parse_dates=True)
In [3]: data
Out[3]:
AAPL MSFT XOM SPX
2003-01-02 7.40 21.11 29.22 909.03
2003-01-03 7.45 21.14 29.24 908.59
2003-01-06 7.45 21.52 29.96 929.01
2003-01-07 7.43 21.93 28.95 922.93
2003-01-08 7.28 21.31 28.83 909.93
... ... ... ... ...
2011-10-10 388.81 26.94 76.28 1194.89
2011-10-11 400.29 27.00 76.27 1195.54
2011-10-12 402.19 26.96 77.16 1207.25
2011-10-13 408.43 27.18 76.37 1203.66
2011-10-14 422.00 27.27 78.11 1224.58
[2214 rows x 4 columns]
把这个表里的最后一列SPX进行可视化:
In [4]: from datetime import datetime
import pandas as pd
fig = plt.figure() #创建新图形
ax = fig.add_subplot(1, 1, 1) #只创建一个图形
spx = data['SPX'] #把最后一列赋给一个变量
spx.plot(ax=ax, style='k-')
crisis_data = [
(datetime(2007, 10, 11), 'Peak of bull market'),
(datetime(2008, 3, 12), 'Bear Stearns Fails'),
(datetime(2008, 9, 15), 'Lehman Bankruptcy')
] #对三个特定点进行标注
for date, label in crisis_data:
ax.annotate(label, xy=(date, spx.asof(date) + 75),
xytext=(date, spx.asof(date) + 225),
arrowprops=dict(facecolor='black', headwidth= 4, width=2,headlength=4),
horizontalalignment='left',verticalalignment='top')
# Zoom in on 2007-2010
ax.set_xlim(['1/1/2007', '1/1/2011']) #限制X轴的范围
ax.set_ylim([600, 1800]) #限制Y轴范围
ax.set_title('Important dates in the 2008-2009 financial crisis') #图标题
如果你想绘制一个形状,比如圆形、三角形、四边形之类的,可以使用ax.add_patch()
函数:
In [5]: fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
rect = plt.Rectangle((0.2, 0.75), 0.4, 0.15, color='k', alpha=0.3) #(0.2,0.75)是四边形左下角的坐标位置,0.4代表长度,0.15代表高度
circ = plt.Circle((0.7, 0.2), 0.15, color='b', alpha=0.3) #(0.7,0.2)是椭圆形中心点的位置,0.15代表半径
pgon = plt.Polygon([[0.15, 0.15], [0.35, 0.4], [0.2, 0.6]],color='g', alpha=0.5) #三个[]里代表三角形三个点的坐标位置
ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)
(五)Saving Plots to File保存
你可以使用plt.savefig
来保存你的图。
plt.savefig('figpath.svg')
在你整理发表论文的图的时候,杂志经常会要求你的图的dpi必须要大于多少多少,当然你也可以在保存的时候就指定这个参数:
plt.savefig('figpath.png', dpi=400, bbox_inches='tight')
(六)matplotlib Configuration配置
matplotlib配置了配色方案和默认设置,主要用于准备发布的图形。有一点很方便的是,几乎所有的默认参数都可以通过一组全局参数来设置,这些参数包括图形大小、子图间距、颜色、字体大小、网格样式等等。Python里的rc
方法可以进行全局的参数设置。例如,要设置全局默认图形大小为10×10,可以输入:
plt.rc('figure', figsize=(10, 10))
在rc
里,你可以设置'figure', 'axes', 'xtick', 'ytick', 'grid', 'legend'等等参数。你甚至可以用一个字典的形式来设置你的全局变量:
font_options = {'family' : 'monospace',
'weight' : 'bold',
'size' : 'small'}
plt.rc('font', **font_options)
网友评论