如何绘制标准差误差线?

huangapple go评论120阅读模式
英文:

how do I plot a standard deviation error line?

问题

使用scipy,我可以绘制标准差线。如何在该线的上方复制一个95%的线,以及在该线的下方复制另一个95%的线。

请查看下面的两张图片,以了解我的意思:

如何绘制标准差误差线?

如何绘制标准差误差线?

我的代码:

  1. import datetime as date
  2. import matplotlib.pyplot as plt
  3. %matplotlib inline
  4. import datetime
  5. from scipy import stats
  6. Ins_Name = "EURUSD=X"
  7. # Ins_Name = "AAPL"
  8. df = yf.download(Ins_Name,'2019-05-01','2020-01-03')
  9. df.reset_index(inplace=True)
  10. df['date_ordinal'] = pd.to_datetime(df['Date']).apply(lambda date: date.toordinal())
  11. DateVariance = [datetime.date(2019, 5, 1), datetime.date(2020, 1, 3)]
  12. x_reg = df.date_ordinal
  13. y_reg = df.Close
  14. slope, intercept, r_value, p_value, std_err = stats.linregress(x_reg, y_reg)
  15. print("slope: %f intercept: %f STD Error: %f" % (slope, intercept, std_err))
  16. sns.set()
  17. # plt.figure(figsize=(26, 10))
  18. fig, ax = plt.subplots(figsize=(15,7))
  19. ax = plt.plot(x_reg,intercept + slope*x_reg, color='b')
  20. # ax = sns.lmplot('date_ordinal', 'Close', data=df, fit_reg=True, aspect=2, ) #Scatter PLot
  21. ax = sns.regplot(data=df,x='date_ordinal',y=df.Close,ci=1,fit_reg=False,scatter_kws={"color": "red"}, line_kws={"color": "black"}, marker='x') #scatterplot
  22. # sns.jointplot('date_ordinal', df.Close, data=df, kind="reg",ylim=[1.089,1.15],xlim=DateVariance, height=12,color='red',scatter_kws={"color": "red"}, line_kws={"color": "black"})
  23. ax.set_xlabel('Interval', fontsize=25)
  24. ax.set_xlim(DateVariance)
  25. ax.set_ylabel('Price', fontsize=25)
  26. ax.set_title('Mean reversion of ' + Ins_Name + ' Close Prices',fontsize= 45,color='black')
  27. new_labels = [datetime.date.fromordinal(int(item)) for item in ax.get_xticks()]
  28. ax.set_xticklabels(new_labels)

希望这能帮助你。

英文:

Using scipy I can plot the standard deviation line. How do I duplicate that same line 95% above and another one 95% below.

See the two images below of what I mean:

如何绘制标准差误差线?

如何绘制标准差误差线?

My code:

  1. import datetime as date
  2. import matplotlib.pyplot as plt
  3. %matplotlib inline
  4. import datetime
  5. from scipy import stats
  6. Ins_Name = "EURUSD=X"
  7. #Ins_Name = "AAPL"
  8. df = yf.download(Ins_Name,'2019-05-01','2020-01-03')
  9. df.reset_index(inplace=True)
  10. df['date_ordinal'] = pd.to_datetime(df['Date']).apply(lambda date: date.toordinal())
  11. DateVariance = [datetime.date(2019, 5, 1), datetime.date(2020, 1, 3)]
  12. x_reg = df.date_ordinal
  13. y_reg = df.Close
  14. slope, intercept, r_value, p_value, std_err = stats.linregress(x_reg, y_reg)
  15. print("slope: %f intercept: %f STD Error: %f" % (slope, intercept, std_err))
  16. sns.set()
  17. #plt.figure(figsize=(26, 10))
  18. fig, ax = plt.subplots(figsize=(15,7))
  19. ax = plt.plot(x_reg,intercept + slope*x_reg, color='b')
  20. #ax = sns.lmplot('date_ordinal', 'Close', data=df, fit_reg=True, aspect=2, ) #Scatter PLot
  21. ax = sns.regplot(data=df,x='date_ordinal',y=df.Close,ci=1,fit_reg=False,scatter_kws={"color": "red"}, line_kws={"color": "black"}, marker='x') #scatterplot
  22. #sns.jointplot('date_ordinal', df.Close, data=df, kind="reg",ylim=[1.089,1.15],xlim=DateVariance, height=12,color='red',scatter_kws={"color": "red"}, line_kws={"color": "black"})
  23. ax.set_xlabel('Interval', fontsize=25)
  24. ax.set_xlim(DateVariance)
  25. ax.set_ylabel('Price', fontsize=25)
  26. ax.set_title('Mean reversion of ' + Ins_Name + ' Close Prices',fontsize= 45,color='black')
  27. new_labels = [datetime.date.fromordinal(int(item)) for item in ax.get_xticks()]
  28. ax.set_xticklabels(new_labels)

答案1

得分: 0

我认为函数 stats.linregress() 并不是你想要的。它只返回斜率的不确定性,而不是 y 截距,如果我理解你的问题正确的话,你想要的是 y 截距。

我建议使用 scipy.optimize.curve_fit(),像下面这样:

  1. import datetime as date
  2. import matplotlib.pyplot as plt
  3. import datetime
  4. from scipy.optimize import curve_fit
  5. import yfinance as yf
  6. import pandas as pd
  7. import numpy as np
  8. import seaborn as sns
  9. def fline(x, *par):
  10. return par[0] + par[1]*x
  11. Ins_Name = "EURUSD=X"
  12. #Ins_Name = "AAPL"
  13. df = yf.download(Ins_Name,'2019-05-01','2020-01-03')
  14. df.reset_index(inplace=True)
  15. df['date_ordinal'] = pd.to_datetime(df['Date']).apply(lambda date: date.toordinal())
  16. DateVariance = [datetime.date(2019, 5, 1), datetime.date(2020, 1, 3)]
  17. x_reg = df.date_ordinal
  18. x_trans = x_reg - x_reg[0]
  19. y_reg = df.Close
  20. pi = [1.1, -0.0001] # 初始猜测值,可以使用 linregress 获取这些值
  21. # 在这里执行曲线拟合
  22. popt, cov = curve_fit(fline, x_trans, y_reg, p0=pi) # 返回值和协方差(误差)矩阵
  23. yInterceptSigma = np.sqrt(cov[0,0])
  24. print(x_reg)
  25. print(x_reg - x_reg[0])
  26. print(popt)
  27. print(cov)
  28. sns.set()
  29. #plt.figure(figsize=(26, 10))
  30. fig, ax = plt.subplots(figsize=(15,7))
  31. ax = plt.plot(x_reg, fline(x_trans, *popt), color='b')
  32. # +/- 2sigma gives ~95% CI
  33. plt.plot(x_reg, fline(x_trans, *[popt[0] + 2 * yInterceptSigma, popt[1]]), '--b') # +2sigma on the yintercept
  34. plt.plot(x_reg, fline(x_trans, *[popt[0] - 2 * yInterceptSigma, popt[1]]), '--b') # -2sigma on teh yintercept
  35. #ax = sns.lmplot('date_ordinal', 'Close', data=df, fit_reg=True, aspect=2, ) #Scatter PLot
  36. ax = sns.regplot(data=df,x='date_ordinal',y=df.Close,ci=1,fit_reg=False,scatter_kws={"color": "red"}, line_kws={"color": "black"}, marker='x') #scatterplot
  37. #sns.jointplot('date_ordinal', df.Close, data=df, kind="reg",ylim=[1.089,1.15],xlim=DateVariance, height=12,color='red',scatter_kws={"color": "red"}, line_kws={"color": "black"})
  38. ax.set_xlabel('Interval', fontsize=25)
  39. ax.set_xlim(DateVariance)
  40. ax.set_ylabel('Price', fontsize=25)
  41. ax.set_title('Mean reversion of ' + Ins_Name + ' Close Prices',fontsize= 45,color='black')
  42. new_labels = [datetime.date.fromordinal(int(item)) for item in ax.get_xticks()]
  43. ax.set_xticklabels(new_labels)
  44. plt.show()

这将生成以下图表:如何绘制标准差误差线?

英文:

I think the function stats.linregress() is not what you want here. It only returns the uncertainty on the slope and not the y-intercept, which, if I understand your question, is what you want.

I would use scipy.optimize.curve_fit() like below:

  1. import datetime as date
  2. import matplotlib.pyplot as plt
  3. import datetime
  4. from scipy.optimize import curve_fit
  5. import yfinance as yf
  6. import pandas as pd
  7. import numpy as np
  8. import seaborn as sns
  9. def fline(x, *par):
  10. return par[0] + par[1]*x
  11. Ins_Name = "EURUSD=X"
  12. #Ins_Name = "AAPL"
  13. df = yf.download(Ins_Name,'2019-05-01','2020-01-03')
  14. df.reset_index(inplace=True)
  15. df['date_ordinal'] = pd.to_datetime(df['Date']).apply(lambda date: date.toordinal())
  16. DateVariance = [datetime.date(2019, 5, 1), datetime.date(2020, 1, 3)]
  17. x_reg = df.date_ordinal
  18. x_trans = x_reg - x_reg[0]
  19. y_reg = df.Close
  20. pi = [1.1, -0.0001] # initial guess. Could use linregress to get these values
  21. # Perform curve fitting here
  22. popt, cov = curve_fit(fline, x_trans, y_reg, p0=pi) # returns the values and the covariance (error) matrix
  23. yInterceptSigma = np.sqrt(cov[0,0])
  24. print(x_reg)
  25. print(x_reg - x_reg[0])
  26. print(popt)
  27. print(cov)
  28. sns.set()
  29. #plt.figure(figsize=(26, 10))
  30. fig, ax = plt.subplots(figsize=(15,7))
  31. ax = plt.plot(x_reg, fline(x_trans, *popt), color='b')
  32. # +/- 2sigma gives ~95% CI
  33. plt.plot(x_reg, fline(x_trans, *[popt[0] + 2 * yInterceptSigma, popt[1]]), '--b') # +2sigma on the yintercept
  34. plt.plot(x_reg, fline(x_trans, *[popt[0] - 2 * yInterceptSigma, popt[1]]), '--b') # -2sigma on teh yintercept
  35. #ax = sns.lmplot('date_ordinal', 'Close', data=df, fit_reg=True, aspect=2, ) #Scatter PLot
  36. ax = sns.regplot(data=df,x='date_ordinal',y=df.Close,ci=1,fit_reg=False,scatter_kws={"color": "red"}, line_kws={"color": "black"}, marker='x') #scatterplot
  37. #sns.jointplot('date_ordinal', df.Close, data=df, kind="reg",ylim=[1.089,1.15],xlim=DateVariance, height=12,color='red',scatter_kws={"color": "red"}, line_kws={"color": "black"})
  38. ax.set_xlabel('Interval', fontsize=25)
  39. ax.set_xlim(DateVariance)
  40. ax.set_ylabel('Price', fontsize=25)
  41. ax.set_title('Mean reversion of ' + Ins_Name + ' Close Prices',fontsize= 45,color='black')
  42. new_labels = [datetime.date.fromordinal(int(item)) for item in ax.get_xticks()]
  43. ax.set_xticklabels(new_labels)
  44. plt.show()

Which gives the following plot:
如何绘制标准差误差线?

huangapple
  • 本文由 发表于 2020年1月6日 20:36:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612243.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定