matplotlib绘图与可视化1


前言

制作提供信息的可视化是数据分析中最重要任务之一。可视化可能是探索过程的一部分,例如,帮助识别异常值或所需的数据转换,或者为建模提供一些想法。对于某些实验来说,构建网络交互式可视化可能是最终目标。因此本章节我们将注重关注matplotlib。


一、简明matplotlib

在使用类似matplotlib类似的第三方库时,不要忘了第一步工作就是导入:

import matplotlib.pyplot as plt

导入后,我们就可以使用matplotlib的pyplot模块绘制图形。我们可以生成一个简单的图形如下图所示

import numpy as np
data = np.arange(10)
print(data)
plt.plot(data)
plt.show()
-------------------------------------------------------------
[0 1 2 3 4 5 6 7 8 9]

在这里插入图片描述
将data的数据传给plt.plot方法,然后绘制图形,最后,通过plt.show() 显示图形。

1.1 pyplot功能

我们尝试应用NumPy的sin函数np.sin()和cos函数np.cos()的图形,并尝试使用pyplot的添加标题和x轴标签名等其他功能。

x = np.arange(0,6,0.1)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y1,label='sin')
plt.plot(x,y2,linestyle='--',label='cos')
plt.xlabel('x')
plt.ylabel('y')
plt.title('sin&cos')
plt.legend()
plt.show()

在这里插入图片描述


1.2 图片与子图

matplotlib所绘制的图位于图片(Figure)对象中。你可以使用plt.figure生成一个新的图片:

flg = plt.figure()

plt.figure有一些选项,比如figsize是确保图片有一个确定的大小以及存储到硬盘时的长宽比。不能使用空白的图片进行绘图。此时需要使用add_subplot创建一个或多个子图:

ax1 = flg.add_subplot(2,2,1)
ax2 = flg.add_subplot(2,2,2)
ax3 = flg.add_subplot(2,2,3)
plt.show()

在这里插入图片描述

**flg.add_subplot(2,2,1)**的意思应该是2x2的(最多四个图片),并且我们选择了四个图形中的第一个(序号从1开始)。
当你输入绘图命令:

plt.plot(np.random.randn(50).cumsum(),'k--')

matplotlib会在最后一个图片和子图上进行绘制,从而隐藏图片和子图的创建。
在这里插入图片描述
'k–'是用于绘制黑色分段线的style选项。fig.add_subplot返回的对象是AxesSuplot对象,使用这些对象你可以直接在其他空白的子图上调用对象的实例方法进行绘图:

_ = 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))

在这里插入图片描述
使用子图网络创建图片是非常常见的任务,所以matplotlib包含了一个便捷方法plt.subplots,它创建一个新的图片,然后返回包含了已生成子图对象的NumPy数组:

fig,axes = plt.subplots(2,3)
print(axes)
----------------------------------------------------------------------
[[<AxesSubplot: > <AxesSubplot: > <AxesSubplot: >]
 [<AxesSubplot: > <AxesSubplot: > <AxesSubplot: >]]

这是非常有用的,因为数组axes可以像二维数组那样方便地进行索引,例如axes[0,1]。你也可以通过使用sharex和sharey来表明子图分别拥有相同的x轴或y轴。此外,matplotlib还可以独立地缩放图像的界限。下表有更多的介绍:

参数描述
nrows子图的行数
ncols子图的列数
sharex所有的子图使用相同的x轴刻度(调整xlim会影响所有子图)
sharey所有的子图使用相同的y轴刻度(调整ylim会影响所有子图)
subplot_kw传入add_subplot的关键字参数字典,用于生成子图
**fig_kw在生成图片时使用的额外关键字参数,例如plt.subplots(2,2,figsize=(8,6))

1. 调整子图周围的间距
默认情况下,matplotlib会在子图的外部和子图之间留出一定的间距。这个间距都是相对于图的高度和宽度来指定的,所以如果你通过编程或手动使用GUI窗口来调整图的大小,那么图就会自动调整。你可以使用图对象上的subplots_adjust方法更改间距,也可以用作顶层函数:

subplots_adjust(left=None,bottom=None,right=None,top=None,
                wspace=None,hspace=None)

wspace和hspace分别控制的是图片的宽度和高度百分比,以用作子图间的间距。

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)
plt.show()

在这里插入图片描述
你可能会注意到轴标签是存在重叠的。matplotlib并不检查标签是否重叠,因此在类似情况下你需要通过显式指定刻度位置和刻度标签的方法来修复轴标签。


1.3 颜色、标记和线类型

matplotlib的主函数plot接收带有x和y轴的数组以及一些可选的字符串缩写参数来指明颜色和线类型。例如,要用绿色破折号绘制x对y的线,你需要执行:

ax.plot(x,y,'g--')

这种在字符串中指定颜色和线条样式的方式是方便的。在实践中,如果你以编程方式创建绘图,则可能不希望将字符串混合在一起以创建具有所需样式的图表。同样的图表可以使用更为显式的方式来表达:

ax.plot(x,y,linestyle='--',color='g')

折线图还可以标记用来凸显实际的数据点。由于matplotlib创建了一个连续性折线图,插入点之间有时并不清除点在哪。标记可以是样式字符串的一部分,样式字符串中线类型,标记类型必须跟在颜色后面:

plt.plot(np.random.randn(30).cumsum(),'ko--')
plt.show()

在这里插入图片描述
上面的代码可以写得更为显式:

plt.plot(np.random.randn(30).cumsum(),color='k',linestyle='dashed',marker='o')

对于折线图,你会注意到后续的点默认是线性内插的。可以通过drawstyle选项进行更改:

data = np.random.randn(30).cumsum()
plt.plot(data,'k--',label='Default')
plt.plot(data,'k--',drawstyle='steps-post',label='steps-post')
plt.legend(loc='best')
plt.show()

在这里插入图片描述
这里,由于我们向plot传递了label选项,我们可以使用plt.legend为每条线生成一个用于区分的图例。


1.4 刻度、标签和图例

pyplot接口设计为交互式使用,包含了像xlim、xticks和xticklabels等方法。这些方法分别控制了绘图范围、刻度位置以及刻度标签。我们可以在两种方式中使用:

  • 在没有函数参数的情况下调用,返回当前的参数值(例plt.xlim())
  • 传入参数的情况下调用,并设置参数值(例如plt.xlim([0,10])会将x轴的范围设置为0到10)

1.3.1 设置标题、轴标签、刻度和刻度标签
通过下列这个例子进行讲解轴的自定义,我会生成一个简单的图表:

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(np.random.randn(1000).cumsum())
plt.show()

在这里插入图片描述

要改变x轴刻度,最简单的方式是使用set_xticksset_xticklabelsset_xticks表示在数据范围内设定刻度的位置,默认情况下,这些刻度也有标签。但是我们可以使用set_xticklabels为标签赋值:

ticks = ax.set_xticks([0,250,500,750,1000])
labels = ax.set_xticklabels(['one','two','three','four','five'],rotation=30,fontsize='small')

rotation选项会将x轴刻度标签旋转30度。最后,set_xlabel会给x轴一个名称,set_titel会给子图一个标题:

ax.set_title('My first matplotlib plot')
ax.set_xlabel('Stages')

在这里插入图片描述
1.3.2 添加图例

图例是用来区分绘图元素的另一个重要内容。有多种方式可以添加图例。最简单的方式是在添加每个图表时传递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(),'k--',label='two')
ax.plot(randn(1000).cumsum(),'k.',label='three')
ax.legend(loc='best')
plt.show()

在这里插入图片描述
你也可以调用ax.legend()plt.legend自动生成图例。legend方法有多个其他的位置参数loc。loc参数告诉matplotlib在哪里放置图表。而‘best’会自动选择最合适的位置。如果取消图例中的元素,不要传入label参数或者传入label=’_nolegend _'.


1.5 注释与子图加工

除了标准的绘图类型,你可能还会想在图表上绘制自己的注释,而且注释中可能会包含文本、箭头以及其他图形。你可以使用textarrowannote方法来添加注释和文本。text在图表上给定的坐标(x,y),根据可选的定制样式绘制文本:

ax.text(x,y,'Hello world',family='monospace',fontsize=10)

注释可以同时绘制文本和箭头。有一个例子,让我们绘制标普500指数从2007年以来的收盘价,并在图表中标注2008年到2009年金融危机中的重要日期。我们可以从这本书的GitHub仓库下载这个例子 GitHub仓库

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
data = pd.read_csv('spx.csv',index_col=0,parse_dates=True)
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')

ax.set_xlim(['1/1/2007','1/1/2011'])
ax.set_ylim([600,1800])
ax.set_title('Important dates in the 2008-2009 financial crisis')

plt.show()

ax.annotate方法可以在指定的x和y坐标上绘制标签。我们可以使用set_xlimset_ylim方法手动设置图表的边界,而不是使用matplotlib的默认设置。最后,ax.set_title给图表添加了一个主标题。

在这里插入图片描述

绘制图形时有更多需要注意的地方。matplotlib含有表示多种常见图形的对象,这些对象的引用是patches。一些图形,比如Rectangle(图形)和Circle(圆形),可以在matplotlib.pyplot中找到,但图形的全集位于matplotlib.patches。

想在图表中添加图形时,你需要生成patch对象shp,并调用ax.add_patch(shp)将它加入到子图中:

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)
circ = plt.Circle((0.7,0.2),0.15,color='b',alpha=0.3)
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)

plt.show()

在这里插入图片描述


1.6 将图片保存到文件

你可以使用plt.savefig将活动图片保存到文件中。这个方法等价于图片对象的savefig实例方法。例如将图片保存为SVG,你只需要输入以下代码:

plt.savefig('aaa.svg')

此时要注意,保存请写在plt.show()的上一行,否则会形成空白的图片文件。这是因为plt.show()的作用:

  1. 暂时终止配置
  2. 显示图表图片
  3. 不与后边对其他图表的配置冲突

常常会使用几个重要的选项来发布图形:dpi,它控制每英寸点数的分辨率;bbox_inches,可以修剪实际图形的空白。为了得到同样一个PNG图片,且使用最小的空白,拥有400DPI,你需要运行以下代码:

plt.savefig('aab.png',dpi=400,bbox_inches='tight')

下表是savefig其他选项的列表:

参数描述
fname包含文件路径或Python文件型对象的字符串。图片格式是从文件扩展名中推断出来的(例如PDF格式的.pdf)
dpi每英寸点数的分辨率;默认为100,但可以配置
facecolor,edgecolor子图之外的图形背景的颜色;默认情况下是‘w’(白色)
format文件格式
bbox_inches要保存的图片范围;如果传递’tight‘,将会去除掉图片周围空白的部分

1.7 matplotlib设置

matplotlib配置了配色方案和默认设置,主要用来准备用于发布图片。幸运的是,几乎所有的默认行为都可以通过广泛的全局参数来定制,包括图形大小、子图间距、颜色、字体大小和网络样式等等。使用rc方法是使用Python编程修改配置的一种方式,例如,要将全局默认数字大小设置为10x10,你可以输入:

plt.rc('figure',figsize=(10,10))

rc的第一参数是你想要自定义的组件,比如’figure‘、‘axes’、‘xtick’、‘ytick’等等。之后,可以按照关键字参数的序列指定新参数。字典是一种在程序中设置选项的简单方式:

font_options={'family':'monospace',
              'weight':'bold',
              'size':'small'}
plt.rc('font',**font_options)

如果需要更深入的定制和参看全量选项,可以参考matplotlib的设置文件matplotlibrc,该文件位于matplotlib/mpl-data路径。如果你定制了这个文件,并将他放置在home路径下并且文件名为.matplotlibrc,则每次你使用matplotlib时都会读取该文件。


总结

以上就是今天要讲的内容,本文初步介绍了如何使用matplotlib库去绘制图片。介绍了pyplot的一些功能可以更加详细描述图片,除了plt.plot方法以外,我们还可以使用plt.subplot方法。然后讲到了对于图片如何去规定颜色、标记和线类型。并且讲到了如何控制绘图范围、刻度位置以及刻度标签,注释和文本等等,将我们绘制的图片可以以不同格式保存在文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值