python函数python subplot函数中label怎么使用

时间序列(简称TS)被认为是分析领域比较少人知道的技能。(我也是几天前才知道它)。但是你一定知道最近的小型编程马拉松就是基于时间序列发展起来的,我参加了这项活动去学习了解决时间序列问题的基本步骤,在这儿我要分享给大家。这绝对能帮助你在编程马拉松中获得一个合适的模型。
文章之前,我极力推荐大家阅读《基于R语言的时间序列建模完整教程》A Complete Tutorial on Time Series Modeling in R,它就像这篇文章的前篇。它关注基本概念和基于R语言,我将重点使用这些概念来解决Python编程里面端到端的问题。R语言存在许多关于时间序列的资源,但是很少关于Python的,所以本文将使用Python。
36大数据专稿,原文作者:AARSHAY JAIN
本文由36大数据翻译,任何不标明译者和出处以及本文链接/archives/43811的均为侵权。
我们的过程包括下面几步:
1、时间序列有什么特别之处?
2、在Pandas上传和加载时间序列(pandas 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包,类似于 Numpy 的核心是 ndarray,pandas 也是围绕着 Series 和 DataFrame 两个核心数据结构展开的 。)
3、如何检验时间序列的稳定性?
4、如何令时间序列稳定?
5、时间序列预测。
1、时间序列有什么特别之处?
顾名思义,时间序列是时间间隔不变的情况下收集的时间点集合。这些集合被分析用来了解长期发展趋势,为了预测未来或者表现分析的其他形式。但是是什么令时间序列与常见的回归问题的不同?
有两个原因:
1、时间序列是跟时间有关的。所以基于线性回归模型的假设:观察结果是独立的在这种情况下是不成立的。
2、随着上升或者下降的趋势,更多的时间序列出现季节性趋势的形式,如:特定时间框架的具体变化。即:如果你看到羊毛夹克的销售上升,你就一定会在冬季做更多销售。
因为时间序列的固有特性,有各种不同的步骤可以对它进行分析。下文将详细分析。通过在Python上传时间序列对象开始。我们将使用飞机乘客数据集。
请记住本文的目的是希望使你熟悉关于时间序列的不同使用方法。本文的例子只是用来方便解释时间序列对象,我重点关注题目的广泛性,不会做非常精确的预测。
2、在pandas上传和加载时间序列
Pandas有专门处理时间序列对象的库,特别是可以存储时间信息和允许人们执行快速合作的datatime64(ns)类。从激发所需的库开始。
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 15, 6
现在,我们可以上传数据集和查看一些最初的行以及列的数据类型。
data = pd.read_csv('AirPassengers.csv')
print data.head()
print '\n Data Types:'
print data.dtypes
数据包含了指定的月份和该月的游客数量。但是时间序列对象的读取和数据类型的“对象”和“整数类型”的读取是不一样的。为了将读取的数据作为时间序列,我们必须通过特殊的参数读取csv指令。
dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m')
data = pd.read_csv('AirPassengers.csv', parse_dates='Month', index_col='Month',date_parser=dateparse)
print data.head()
我们逐个解释这些参数:
1、parse_dates:这是指定含有时间数据信息的列。正如上面所说的,列的名称为“月份”。
1、index_col:使用pandas 的时间序列数据背后的关键思想是:目录成为描述时间数据信息的变量。所以该参数告诉pandas使用“月份”的列作为索引。
2、date_parser:指定将输入的字符串转换为可变的时间数据。Pandas默认的数据读取格式是‘YYYY-MM-DD HH:MM:SS’。如需要读取的数据没有默认的格式,就要人工定义。这和dataparse的功能部分相似,这里的定义可以为这一目的服务。
现在我们看到数据有作为索引的时间对象和作为列的乘客(#Passengers)。我们可以通过以下指令再次检查索引的数据类型。
data.index
注意: dtype=’datetime[ns]’ 确认它是一个时间数据对象。个人而言,我会将列转换为序列对象,这样当我每次使用时间序列的时候,就不需要每次都要提及列名称。当然,这因人而异,如果能令你更好工作,可以使用它作为数据框架。
ts = data[‘#Passengers’] ts.head(10)
在进一步深入前,我会探讨一些关于时间序列数据的索引技术。先在序列对象选择一个特殊值。可以通过以下两种方式实现:
#1. Specific the index as a string constant:
#2. Import the datetime library and use 'datetime' function:
from datetime import datetime
ts[datetime()]
两种方法都会返回值“112”,这可以通过先前的结果确认。希望我们可以获得1949年5月(包括1949年5月)之前的数据。这又可以用以下两种方法实现:
#1. Specify the entire range:
#2. Use ':' if one of the indices is at ends:
两种方法都会输出以下结果:
我们要注意两点:
跟数值索引不一样,结束索引在这儿是被包含的。比如,如果令一个列表成为索引作为一个数组[:5],它将在索引返回值-[0,1,2,3,4].在这里索引‘’是包含在结果输出里面的。
目录必须为了工作区间而进行分类。如果你随意打乱这些索引,将不能工作。
考虑到可以使用另外一个例子:你需要1949年所有的值。可以这样做:
ts['1949']
可见,月份部分已经省略。如果你要获得某月所有的日期,日期部分也可以省略。
现在,让我们开始分析时间序列。
3、如何检验时间序列的稳定性?
如果一个时间序列的统计特征如平均数,方差随着时间保持不变,我们就可以认为它是稳定的。为什么时间序列的稳定性这么重要?大部分时间序列模型是在假设它是稳定的前提下建立的。直观地说,我们可以这样认为,如果一个时间序列随着时间产生特定的行为,就有很高的可能性认为它在未来的行为是一样的。同时,根据稳定序列得出的理论是更加成熟的, 也是更容易实现与非稳定序列的比较。
稳定性的确定标准是非常严格的。但是,如果时间序列随着时间产生恒定的统计特征,根据实际目的我们可以假设该序列是稳定的。如下:
恒定的平均数
恒定的方差
不随时间变化的自协方差
我会跳过一些细节,因为在文章已经说的非常清楚。接下来,是关于测试稳定性的方法。首先是简化坐标和数据,进行可视分析。数据可以通过以下指令定位。
ts['1949']
非常清晰的看到,随着季节性的变动,飞机乘客的数量总体上是在不断增长的。但是,不是经常都可以获得这样清晰的视觉推论(下文给出相应例子)。所以,更正式的讲,我们可以通过下面的方法测试稳定性。
1、绘制滚动统计:我们可以绘制移动平均数和移动方差,观察它是否随着时间变化。随着移动平均数和方差的变化,我认为在任何“t”瞬间,我们都可以获得去年的移动平均数和方差。如:上一个12个月份。但是,这更多的是一种视觉技术。
2、DF检验:这是一种检查数据稳定性的统计测试。无效假设:时间序列是不稳定的。测试结果由测试统计量和一些置信区间的临界值组成。如果“测试统计量”少于“临界值”,我们可以拒绝无效假设,并认为序列是稳定的。
这些概念不是凭直觉得出来的。我推荐大家浏览前篇文章。如果你对一些理论数据感兴趣,你可以参考Brockwell 和 Davis关于时间序列和预测的介绍的书。这本书的数据很多,但是如果你能读懂言外之意,你会明白这些概念和正面接触这些数据。
回到检查稳定性这件事上,我们将使用滚动数据坐标连同许多DF测试结果,我已经定义了一个需要时间序列作为输入的函数,为我们生成结果。请注意,我已经绘制标准差来代替方差,为了保持单元和平均数相似。
from statsmodels.tsa.stattools import adfuller
def test_stationarity(timeseries):
#Determing rolling statistics
rolmean = pd.rolling_mean(timeseries, window=12)
rolstd = pd.rolling_std(timeseries, window=12)
#Plot rolling statistics:
orig = plt.plot(timeseries, color='blue',label='Original')
mean = plt.plot(rolmean, color='red', label='Rolling Mean')
std = plt.plot(rolstd, color='black', label = 'Rolling Std')
plt.legend(loc='best')
plt.title('Rolling Mean & Standard Deviation')
plt.show(block=False)
#Perform Dickey-Fuller test:
print 'Results of Dickey-Fuller Test:'
dftest = adfuller(timeseries, autolag='AIC')
dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
for key,value in dftest[4].items():
dfoutput['Critical Value (%s)'%key] = value
print dfoutput
代码是非常直观的,如果你在阅读过程中遇到挑战可以在评论处提出。
输入序列开始运行:
基本上是不可能使序列完全稳定,我们只能努力让它尽可能的稳定。
先让我们弄明白是什么导致时间序列不稳定。这儿有两个主要原因。
趋势-随着时间产生不同的平均值。举例:在飞机乘客这个案例中,我们看到总体上,飞机乘客的数量是在不断增长的。
季节性-特定时间框架内的变化。举例:在特定的月份购买汽车的人数会有增加的趋势,因为车价上涨或者节假日到来。
模型的根本原理或者预测序列的趋势和季节性,从序列中删除这些因素,将得到一个稳定的序列。然后统计预测技术可以在这个序列上完成。最后一步是通过运用趋势和季节性限制倒回到将预测值转换成原来的区间。
注意:我将探讨一系列方法。可能有些对文中情况有用,有些不能。但是我的目的是得到一系列可用方法,而不是仅仅关注目前的问题。
让我们通过分析趋势的一部分开始工作吧。
预测&消除趋势
消除趋势的第一个方法是转换。例如,在本例中,我们可以清楚地看到,有一个显著的趋势。所以我们可以通过变换,惩罚较高值而不是较小值。这可以采用日志,平方根,立方跟等等。让我们简单在这儿转换一个对数。
ts_log = np.log(ts)
plt.plot(ts_log)
在这个简单的例子中,很容易看到一个向前的数据趋势。但是它表现的不是很直观。所以我们可以使用一些技术来估计或对这个趋势建模,然后将它从序列中删除。这里有很多方法,最常用的有:
聚合-取一段时间的平均值(月/周平均值)
平滑-取滚动平均数
多项式回归分析-适合的回归模型
我在这儿讨论将平滑,你也应该尝试其他可以解决的问题的技术。平滑是指采取滚动估计,即考虑过去的几个实例。有各种方法可以解决这些问题,但我将主要讨论以下两个。
移动平均数
在这个方法中,根据时间序列的频率采用“K”连续值的平均数。我们可以采用过去一年的平均数,即过去12个月的平均数。关于确定滚动数据,pandas有特定的功能定义。
moving_avg = pd.rolling_mean(ts_log,12)
plt.plot(ts_log)
plt.plot(moving_avg, color='red')
红色表示了滚动平均数。让我们从原始序列中减去这个平均数。注意,从我们采用过去12个月的值开始,滚动平均法还没有对前11个月的值定义。我们可以看到:
ts_log_moving_avg_diff = ts_log - moving_avg
ts_log_moving_avg_diff.head(12)
注意前11个月是非数字的,现在让我们对这11个月降值和检查这些模块去测试稳定性。
ts_log_moving_avg_diff.dropna(inplace=True)
test_stationarity(ts_log_moving_avg_diff)
这看起来像个更好的序列。滚动平均值出现轻微的变化,但是没有明显的趋势。同时,检验统计量比5%的临界值小,所以我们在95%的置信区间认为它是稳定序列。
但是,这个方法有一个缺陷:要严格定义时段。在这种情况下,我们可以采用年平均数,但是对于复杂的情况的像预测股票价格,是很难得到一个数字的。所以,我们采取“加权移动平均法”可以对最近的值赋予更高的权重。关于指定加重这儿有很多技巧。
指数加权移动平均法是很受欢迎的方法,所有的权重被指定给先前的值连同衰减系数。这可以通过pandas实现:
expwighted_avg = pd.ewma(ts_log, halflife=12)
plt.plot(ts_log)
plt.plot(expwighted_avg, color='red')
注意,这里使用了参数“半衰期”来定义指数衰减量。这只是一个假设,将很大程度上取决于业务领域。其他参数,如跨度和质心也可以用来定义衰减,正如上面链接分享的探讨。现在让我们从这个序列转移,继续检查稳定性。
ts_log_ewma_diff = ts_log - expwighted_avg
test_stationarity(ts_log_ewma_diff)
这个时间序列有更少的平均值变化和标准差大小变化。同时,检验统计量小于1%的临界值,这比以前的情况好。请注意在这种情况下就不会有遗漏值因为所有的值在一开始就被赋予了权重。所以在运行的时候,它没有先前的值参与。
消除趋势和季节性
之前讨论来了简单的趋势减少技术不能在所有情况下使用,特别是在高季节性情况下。让我们谈论一下两种消除趋势和季节性的方法。
差分-采用一个特定时间差的差值
分解——建立有关趋势和季节性的模型和从模型中删除它们。
处理趋势和季节性的最常见的方法之一就是差分法。在这种方法中,我们采用特定瞬间和它前一个瞬间的不同的观察结果。这主要是在提高平稳性。pandas可以实现一阶差分:
ts_log_diff = ts_log - ts_log.shift()
plt.plot(ts_log_diff)
表中可以看出很大程度上减少了趋势。让我们通过模块验证一下:
ts_log_diff.dropna(inplace=True)
test_stationarity(ts_log_diff)
我们可以看到平均数和标准差随着时间有小的变化。同时,DF检验统计量小于10% 的临界值,因此该时间序列在90%的置信区间上是稳定的。我们同样可以采取二阶或三阶差分在具体应用中获得更好的结果。这些方法你可以自己尝试。
在这种方法中,趋势和季节性是分别建模的并倒回到序列的保留部分。我将跳过统计数据,直接给出结果:
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(ts_log)
trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid
plt.subplot(411)
plt.plot(ts_log, label='Original')
plt.legend(loc='best')
plt.subplot(412)
plt.plot(trend, label='Trend')
plt.legend(loc='best')
plt.subplot(413)
plt.plot(seasonal,label='Seasonality')
plt.legend(loc='best')
plt.subplot(414)
plt.plot(residual, label='Residuals')
plt.legend(loc='best')
plt.tight_layout()
在这里我们可以看到趋势,季节性从数据分离,我们可以建立残差的模型,让我们检查残差的稳定性:
ts_log_decompose = residual
ts_log_decompose.dropna(inplace=True)
test_stationarity(ts_log_decompose)
DF测试统计量明显低于1%的临界值,这样时间序列是非常接近稳定。你也可以尝试高级的分解技术产生更好的结果。同时,你应该注意到, 在这种情况下将残差转换为原始值对未来数据不是很直观。
预测时间序列
我们看到不同的技术和它们有效的工作使得时间序列得以稳定。让我们建立差分后的时间序列模型,因为它是很受欢迎的技术,也相对更容易添加噪音和季节性倒回到预测残差。在执行趋势和季节性评估技术上,有两种情况:
不含依赖值的严格稳定系列。简单的情况下,我们可以建立残差模型作为白噪音(指功率谱密度在整个频域内均匀分布的噪声)。但这是非常罕见的。
序列含有明显的依赖值。在这种情况下,我们需要使用一些统计模型像ARIMA(差分自回归移动平均模型)来预测数据。
让我给你简要介绍一下ARIMA,我不会介绍技术细节,但如果你希望更有效地应用它们,你应该理解这些概念的细节。ARIMA代表自回归整合移动平均数。平稳时间序列的ARIMA预测的只不过是一个线性方程(如线性回归)。预测依赖于ARIMA模型参数(p d q)。
自回归函数(AR)的条件(p):AR条件仅仅是因变量的滞后。如:如果P等于5,那么预测x(t)将是x(t-1)。。。(t-5)。
移动平均数(MA)的条件(q):MA条件是预测方程的滞后预测错误。如:如果q等于5,预测x(t)将是e(t-1)。。。e(t-5),e(i)是移动平均叔在第ith个瞬间和实际值的差值。
差分(d):有非季节性的差值,即这种情况下我们采用一阶差分。所以传递变量,令d=0或者传递原始变量,令d=1。两种方法得到的结果一样。
在这里一个重要的问题是如何确定“p”和“q”的值。我们使用两个坐标来确定这些数字。我们来讨论它们。
、自相关函数(ACF):这是时间序列和它自身滞后版本之间的相关性的测试。比如在自相关函数可以比较时间的瞬间‘t1’…’t2’以及序列的瞬间‘t1-5’…’t2-5’ (t1-5和t2 是结束点)。
部分自相关函数(PACF):这是时间序列和它自身滞后版本之间的相关性测试,但是是在预测(已经通过比较干预得到解释)的变量后。如:滞后值为5,它将检查相关性,但是会删除从滞后值1到4得到的结果。
时间序列的自回归函数和部分自回归函数可以在差分后绘制为:
#ACF and PACF plots:
from statsmodels.tsa.stattools import acf, pacf
lag_acf = acf(ts_log_diff, nlags=20)
lag_pacf = pacf(ts_log_diff, nlags=20, method='ols')
#Plot ACF:
plt.subplot(121)
plt.plot(lag_acf)
plt.axhline(y=0,linestyle='--',color='gray')
plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
plt.title('Autocorrelation Function')
#Plot PACF:
plt.subplot(122)
plt.plot(lag_pacf)
plt.axhline(y=0,linestyle='--',color='gray')
plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray')
plt.title('Partial Autocorrelation Function')
plt.tight_layout()
在这个点上,0的每一条边上的两条虚线之间是置信区间。这些可以用来确定“p”和“q”的值:
1、p-部分自相关函数表第一次截断的上层置信区间是滞后值。如果你仔细看,该值是p=2。
2、q- 自相关函数表第一次截断的上层置信区间是滞后值。如果你仔细看,该值是q=2。
现在,考虑个体以及组合效应建立3个不同的ARIMA模型。我也会发布各自的RSS(是一种描述和同步网站内容的格式,是使用最广泛的XML应用)。请注意,这里的RSS是指残差值,而不是实际序列。
首先,我们需要上传ARIMA模型。
from statsmodels.tsa.arima_model import ARIMA
p,d,q值可以指定使用ARIMA的命令参数即采用一个元(p,d,q)。建立三种情况下的模型:
自回归(AR)模型:
model = ARIMA(ts_log, order=(2, 1, 0))
results_AR = model.fit(disp=-1)
plt.plot(ts_log_diff)
plt.plot(results_AR.fittedvalues, color='red')
plt.title('RSS: %.4f'% sum((results_AR.fittedvalues-ts_log_diff)**2))
model = ARIMA(ts_log, order=(0, 1, 2))
results_MA = model.fit(disp=-1)
plt.plot(ts_log_diff)
plt.plot(results_MA.fittedvalues, color='red')
plt.title('RSS: %.4f'% sum((results_MA.fittedvalues-ts_log_diff)**2))
移动平均数(MA )模型
model = ARIMA(ts_log, order=(2, 1, 2))
results_ARIMA = model.fit(disp=-1)
plt.plot(ts_log_diff)
plt.plot(results_ARIMA.fittedvalues, color='red')
plt.title('RSS: %.4f'% sum((results_ARIMA.fittedvalues-ts_log_diff)**2))
在这里我们可以看到,自回归函数模型和移动平均数模型几乎有相同的RSS,但相结合效果显著更好。现在,我们只剩下最后一步,即把这些值倒回到原始区间。
倒回到原始区间
既然组合模型获得更好的结果,让我们将它倒回原始值,看看它如何执行。第一步是作为一个独立的序列,存储预测结果,观察它。
predictions_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True)
print predictions_ARIMA_diff.head()
注意,这些是从‘’开始,而不是第一个月。为什么?这是因为我们将第一个月份取为滞后值,一月前面没有可以减去的元素。将差分转换为对数尺度的方法是这些差值连续地添加到基本值。一个简单的方法就是首先确定索引的累计总和,然后将其添加到基本值。累计总和可以在下面找到:
predictions_ARIMA_diff_cumsum = predictions_ARIMA_diff.cumsum()
print predictions_ARIMA_diff_cumsum.head()
你可以在头脑使用之前的输出结果进行回算,检查这些是否正确的。接下来我们将它们添加到基本值。为此我们将使用所有的值创建一个序列作为基本值,并添加差值。我们这样做:
predictions_ARIMA_log = pd.Series(ts_log.ix[0], index=ts_log.index)
predictions_ARIMA_log = predictions_ARIMA_log.add(predictions_ARIMA_diff_cumsum,fill_value=0)
predictions_ARIMA_log.head()
第一个元素是基本值本身,从基本值开始值累计添加。最后一步是将指数与原序列比较。
predictions_ARIMA = np.exp(predictions_ARIMA_log)
plt.plot(ts)
plt.plot(predictions_ARIMA)
plt.title('RMSE: %.4f'% np.sqrt(sum((predictions_ARIMA-ts)**2)/len(ts)))
最后我们获得一个原始区间的预测结果。虽然不是一个很好的预测。但是你获得了思路对吗?现在,我把它留个你去进一步改进,做一个更好的方案。
在本文中,我试图提供你们一个标准方法去解决时间序列问题。这个不可能达到一个更好的时间,因为今天是我们的小型编程马拉松,挑战你们是否可以解决类似的问题。我们广泛的讨论了稳定性的概念和最终的预测残差。这是一个漫长的过程,我跳过了一些统计细节,我鼓励大家使用这些作为参考材料。如果你不想复制粘贴,你可以从我
转载请注明来自36大数据(): &
除非特别注明,本站所有文章均不代表本站观点。报道中出现的商标属于其合法持有人。请遵守理性,宽容,换位思考的原则。70939人阅读
Python 学习(6)
matplotlib 是python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。
它的文档相当完备,并且Gallery页面中有上百幅缩略图,打开之后都有源程序。因此如果你需要绘制某种类型的图,只需要在这个页面中浏览/复制/粘贴一下,基本上都能搞定。
在Linux下比较著名的数据图工具还有gnuplot,这个是免费的,Python有一个包可以调用gnuplot,但是语法比较不习惯,而且画图质量不高。
而&则比较强:Matlab的语法、python语言、latex的画图质量(还可以使用内嵌的latex引擎绘制的数学公式)。
Matplotlib.pyplot快速绘图
matplotlib实际上是一套面向对象的绘图库,它所绘制的图表中的每个绘图元素,例如线条Line2D、文字Text、刻度等在内存中都有一个对象与之对应。
为了方便快速绘图matplotlib通过pyplot模块提供了一套和MATLAB类似的绘图API,将众多绘图对象所构成的复杂结构隐藏在这套API内部。我们只需要调用pyplot模块所提供的函数就可以实现快速绘图以及设置图表的各种细节。pyplot模块虽然用法简单,但不适合在较大的应用程序中使用。
为了将面向对象的绘图库包装成只使用函数的调用接口,pyplot模块的内部保存了当前图表以及当前子图等信息。当前的图表和子图可以使用plt.gcf()和plt.gca()获得,分别表示&Get Current Figure&和&Get Current Axes&。在pyplot模块中,许多函数都是对当前的Figure或Axes对象进行处理,比如说:
plt.plot()实际上会通过plt.gca()获得当前的Axes对象ax,然后再调用ax.plot()方法实现真正的绘图。
可以在Ipython中输入类似&plt.plot??&的命令查看pyplot模块的函数是如何对各种绘图对象进行包装的。
matplotlib所绘制的图表的每个组成部分都和一个对象对应,我们可以通过调用这些对象的属性设置方法set_*()或者pyplot模块的属性设置函数setp()设置它们的属性值。
因为matplotlib实际上是一套面向对象的绘图库,因此也可以直接获取对象的属性
绘制一幅图需要对许多对象的属性进行配置,例如颜色、字体、线型等等。我们在绘图时,并没有逐一对这些属性进行配置,许多都直接采用了matplotlib的缺省配置。
matplotlib将这些缺省配置保存在一个名为“matplotlibrc”的配置文件中,通过修改配置文件,我们可以修改图表的缺省样式。配置文件的读入可以使用rc_params(),它返回一个配置字典;在matplotlib模块载入时会调用rc_params(),并把得到的配置字典保存到rcParams变量中;matplotlib将使用rcParams字典中的配置进行绘图;用户可以直接修改此字典中的配置,所做的改变会反映到此后创建的绘图元素。
(快速绘图)
Matplotlib 里的常用类的包含关系为&Figure -& Axes -& (Line2D, Text, etc.)一个Figure对象可以包含多个子图(Axes),在matplotlib中用Axes对象表示一个绘图区域,可以理解为子图。
可以使用subplot()快速绘制包含多个子图的图表,它的调用形式如下:
subplot(numRows, numCols, plotNum)
subplot将整个绘图区域等分为numRows行* numCols列个子区域,然后按照从左到右,从上到下的顺序对每个子区域进行编号,左上的子区域的编号为1。如果numRows,numCols和plotNum这三个数都小于10的话,可以把它们缩写为一个整数,例如subplot(323)和subplot(3,2,3)是相同的。subplot在plotNum指定的区域中创建一个轴对象。如果新创建的轴和之前创建的轴重叠的话,之前的轴将被删除。
subplot()返回它所创建的Axes对象,我们可以将它用变量保存起来,然后用sca()交替让它们成为当前Axes对象,并调用plot()在其中绘图。
(快速绘图)
如果需要同时绘制多幅图表,可以给figure()传递一个整数参数指定Figure对象的序号,如果序号所指定的Figure对象已经存在,将不创建新的对象,而只是让它成为当前的Figure对象。
import numpy as np
import matplotlib.pyplot as plt
plt.figure(1) # 创建图表1
plt.figure(2) # 创建图表2
ax1 = plt.subplot(211) # 在图表2中创建子图1
ax2 = plt.subplot(212) # 在图表2中创建子图2
x = np.linspace(0, 3, 100)
for i in xrange(5):
plt.figure(1)
#? # 选择图表1
plt.plot(x, np.exp(i*x/3))
plt.sca(ax1)
#? # 选择图表2的子图1
plt.plot(x, np.sin(i*x))
plt.sca(ax2)
# 选择图表2的子图2
plt.plot(x, np.cos(i*x))
plt.show()
matplotlib的缺省配置文件中所使用的字体无法正确显示中文。为了让图表能正确显示中文,可以有几种解决方案。
在程序中直接指定字体。在程序开头修改配置字典rcParams。修改配置文件。
面向对象画图
matplotlib API包含有三层,Artist层处理所有的高层结构,例如处理图表、文字和曲线等的绘制和布局。通常我们只和Artist打交道,而不需要关心底层的绘制细节。
直接使用Artists创建图表的标准流程如下:
创建Figure对象用Figure对象创建一个或者多个Axes或者Subplot对象调用Axies等对象的方法创建各种简单类型的Artists
import matplotlib.pyplot as plt
X1 = range(0, 50)
Y1 = [num**2 for num in X1] # y = x^2
X2 = [0, 1]
Y2 = [0, 1]
Fig = plt.figure(figsize=(8,4))
# Create a `figure' instance
Ax = Fig.add_subplot(111)
# Create a `axes' instance in the figure
Ax.plot(X1, Y1, X2, Y2)
# Create a Line2D instance in the axes
Fig.show()
Fig.savefig(&test.pdf&)
《Python科学计算》()&(深入浅出适合系统学习)
&(主要讲面向对象绘图,对于新手可能有点乱)
Matplotlib.pylab快速绘图
matplotlib还提供了一个名为pylab的模块,其中包括了许多NumPy和pyplot模块中常用的函数,方便用户快速进行计算和绘图,十分适合在IPython交互式环境中使用。这里使用下面的方式载入pylab模块:
&&& import pylab as pl
1 安装numpy和matplotlib
&&& import numpy
&&& numpy.__version__
&&& import matplotlib
&&& matplotlib.__version__
2 两种常用图类型:Line and scatter plots(使用plot()命令), histogram(使用hist()命令)
2.1 折线图&散点图&Line and scatter plots
2.1.1 折线图 Line plots(关联一组x和y值的直线)
import numpy as np
import pylab as pl
x = [1, 2, 3, 4, 5]# Make an array of x values
y = [1, 4, 9, 16, 25]# Make an array of y values for each x value
pl.plot(x, y)# use pylab to plot x and y
pl.show()# show the plot on the screen
2.1.2 散点图 Scatter plots
把pl.plot(x, y)改成pl.plot(x, y, 'o')即可,下图的蓝色版本
2.2& 美化 Making things look pretty
2.2.1 线条颜色&Changing the line&color
红色:把pl.plot(x, y, 'o')改成pl.plot(x, y, ’or’)
2.2.2 线条样式 Changing the line style
虚线:plot(x,y, '--')
2.2.3 marker样式 Changing the marker style
蓝色星型markers:plot(x,y, ’b*’)
2.2.4 图和轴标题以及轴坐标限度 Plot and axis titles and limits
import numpy as np
import pylab as pl
x = [1, 2, 3, 4, 5]# Make an array of x values
y = [1, 4, 9, 16, 25]# Make an array of y values for each x value
pl.plot(x, y)# use pylab to plot x and y
pl.title(’Plot of y vs. x’)# give plot a title
pl.xlabel(’x axis’)# make axis labels
pl.ylabel(’y axis’)
pl.xlim(0.0, 7.0)# set axis limits
pl.ylim(0.0, 30.)
pl.show()# show the plot on the screen
2.2.5&在一个坐标系上绘制多个图 Plotting more than one plot on the same set of axes
做法是很直接的,依次作图即可:
import numpy as np
import pylab as pl
x1 = [1, 2, 3, 4, 5]# Make x, y arrays for each graph
y1 = [1, 4, 9, 16, 25]
x2 = [1, 2, 4, 6, 8]
y2 = [2, 4, 8, 12, 16]
pl.plot(x1, y1, ’r’)# use pylab to plot x and y
pl.plot(x2, y2, ’g’)
pl.title(’Plot of y vs. x’)# give plot a title
pl.xlabel(’x axis’)# make axis labels
pl.ylabel(’y axis’)
pl.xlim(0.0, 9.0)# set axis limits
pl.ylim(0.0, 30.)
pl.show()# show the plot on the screen
2.2.6& 图例 Figure legends
pl.legend((plot1, plot2), (’label1, label2’), 'best’, numpoints=1)
其中第三个参数表示图例放置的位置:'best’‘upper right’, ‘upper left’, ‘center’, ‘lower left’, ‘lower right’.
如果在当前figure里plot的时候已经指定了label,如plt.plot(x,z,label=&$cos(x^2)$&),直接调用plt.legend()就可以了哦。
import numpy as np
import pylab as pl
x1 = [1, 2, 3, 4, 5]# Make x, y arrays for each graph
y1 = [1, 4, 9, 16, 25]
x2 = [1, 2, 4, 6, 8]
y2 = [2, 4, 8, 12, 16]
plot1 = pl.plot(x1, y1, ’r’)# use pylab to plot x and y : Give your plots names
plot2 = pl.plot(x2, y2, ’go’)
pl.title(’Plot of y vs. x’)# give plot a title
pl.xlabel(’x axis’)# make axis labels
pl.ylabel(’y axis’)
pl.xlim(0.0, 9.0)# set axis limits
pl.ylim(0.0, 30.)
pl.legend([plot1, plot2], (’red line’, ’green circles’), ’best’, numpoints=1)# make legend
pl.show()# show the plot on the screen
2.3 直方图 Histograms
import numpy as np
import pylab as pl
# make an array of random numbers with a gaussian distribution with
# mean = 5.0
# rms = 3.0
# number of points = 1000
data = np.random.normal(5.0, 3.0, 1000)
# make a histogram of the data array
pl.hist(data)
# make plot labels
pl.xlabel(’data’)
如果不想要黑色轮廓可以改为pl.hist(data, histtype=’stepfilled’)
2.3.1 自定义直方图bin宽度 Setting the width of the histogram bins manually
增加这两行
bins = np.arange(-5., 16., 1.) #浮点数版本的range
pl.hist(data, bins, histtype=’stepfilled’)
3 同一画板上绘制多幅子图 Plotting more than one axis per canvas
如果需要同时绘制多幅图表的话,可以是给figure传递一个整数参数指定图标的序号,如果所指定
序号的绘图对象已经存在的话,将不创建新的对象,而只是让它成为当前绘图对象。
fig1 = pl.figure(1)
pl.subplot(211)
subplot(211)把绘图区域等分为2行*1列共两个区域, 然后在区域1(上区域)中创建一个轴对象. pl.subplot(212)在区域2(下区域)创建一个轴对象。
You can play around with plotting a variety of layouts. For example, Fig. 11 is created using the following commands:
f1 = pl.figure(1)
pl.subplot(221)
pl.subplot(222)
pl.subplot(212)
当绘图对象中有多个轴的时候,可以通过工具栏中的Configure Subplots按钮,交互式地调节轴之间的间距和轴与边框之间的距离。如果希望在程序中调节的话,可以调用subplots_adjust函数,它有left, right, bottom, top, wspace, hspace等几个关键字参数,这些参数的值都是0到1之间的小数,它们是以绘图区域的宽高为1进行正规化之后的坐标或者长度。
pl.subplots_adjust(left=0.08, right=0.95, wspace=0.25, hspace=0.45)
4 绘制文件中的数据Plotting data contained in files
4.1 从Ascii文件中读取数据 Reading data from ascii files
读取文件的方法很多,这里只介绍一种简单的方法,更多的可以参考官方文档和。
numpy的loadtxt方法可以直接读取如下文本数据到numpy二维数组
**********************************************
# fakedata.txt
**********************************************
import numpy as np
import pylab as pl
# Use numpy to load the data contained in the file
# ’fakedata.txt’ into a 2-D array called data
data = np.loadtxt(’fakedata.txt’)
# plot the first column as x, and second column as y
pl.plot(data[:,0], data[:,1], ’ro’)
pl.xlabel(’x’)
pl.ylabel(’y’)
pl.xlim(0.0, 10.)
4.2 写入数据到文件 Writing data to a text file
写文件的方法也很多,这里只介绍一种可用的写入文本文件的方法,更多的可以参考官方文档。
import numpy as np
# Let’s make 2 arrays (x, y) which we will write to a file
# x is an array containing numbers 0 to 10, with intervals of 1
x = np.arange(0.0, 10., 1.)
# y is an array containing the values in x, squared
print ’x = ’, x
print ’y = ’, y
# Now open a file to write the data to
# ’w’ means open for ’writing’
file = open(’testdata.txt’, ’w’)
# loop over each line you want to write to file
for i in range(len(x)):
# make a string for each line you want to write
# ’\t’ means ’tab’
# ’\n’ means ’newline’
# ’str()’ means you are converting the quantity in brackets to a string type
txt = str(x[i]) + ’\t’ + str(y[i]) + ’ \n’
# write the txt to the file
file.write(txt)
# Close your file
file.close()
这部分是翻译自:
对LaTeX数学公式的支持
Matlplotlib对LaTeX有一定的支持,如果记得使用raw字符串语法会很自然:
xlabel(r&$\frac{x^2}{y^4}$&)
在matplotlib里面,可以使用LaTex的命令来编辑公式,只需要在字符串前面加一个“r”即可
Here is a simple example:
# plain text
plt.title('alpha & beta')
produces “alpha & beta”.
Whereas this:
# math text
plt.title(r'$\alpha & \beta$')
produces &&.
这里给大家看一个简单的例子。
import matplotlib.pyplot as plt
x = arange(1,1000,1)
y = [5*(a**r) for a in x]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.loglog(x,y,label = r&$y = \frac{1}{2\sigma_1^2}, c=5,\sigma_1=-2$&)
ax.legend()
ax.set_xlabel(r&x&)
ax.set_ylabel(r&y&)
程序执行结果如图3所示,这实际上是一个power-law的例子,有兴趣的朋友可以继续google之。
再看一个《用Python做科学计算》中的简单例子,下面的两行程序通过调用plot函数在当前的绘图对象中进行绘图:
plt.plot(x,y,label=&$sin(x)$&,color=&red&,linewidth=2)
plt.plot(x,z,&b--&,label=&$cos(x^2)$&)
plot函数的调用方式很灵活,第一句将x,y数组传递给plot之后,用关键字参数指定各种属性:
label&: 给所绘制的曲线一个名字,此名字在图示(legend)中显示。只要在字符串前后添加&$&符号,matplotlib就会使用其内嵌的latex引擎绘制的数学公式。color&: 指定曲线的颜色linewidth&: 指定曲线的宽度
详细的可以参考matplotlib官方教程:
有几个问题:
matplotlib.rcParams属性字典想要它正常工作,在matplotlibrc配置文件中需要设置text.markup = &tex&。如果你希望图表中所有的文字(包括坐标轴刻度标记)都是LaTeX'd,需要在matplotlibrc中设置text.usetex = True。如果你使用LaTeX撰写论文,那么这一点对于使图表和论文中其余部分保持一致是很有用的。在matplotlib中使用中文字符串时记住要用unicode格式,例如:u''测试中文显示''
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:220890次
积分:2507
积分:2507
排名:第10362名
原创:71篇
转载:70篇
评论:19条
(1)(6)(1)(13)(9)(1)(2)(1)(8)(1)(5)(1)(1)(1)(17)(9)(9)(1)(10)(21)(24)}

我要回帖

更多关于 python subplot的用法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信