How to Spread Plot's Date Axis According To Years When Plotting With Seaborn?

橙三吉。 提交于 2021-01-29 19:40:05

问题


I'm trying to train a Linear Regression Model with Python via using Google Stock Prices that can be found here: https://www.kaggle.com/medharawat/google-stock-price And trying to predict future stocks by given features. After that I'm planning to plot it with the values in current dataset.

First, I read dataframes with date values with date parser and concatted these 2 dataframes into one in order to split it myself:

parser = lambda date: pd.datetime.strptime(date, '%m/%d/%Y')
df_test=pd.read_csv("/kaggle/input/google-stock-price/Google_Stock_Price_Test.csv",parse_dates=[0], date_parser=parser)
df_train=pd.read_csv("/kaggle/input/google-stock-price/Google_Stock_Price_Train.csv",parse_dates=[0], date_parser=parser)
df=pd.concat([df_train,df_test])

Then I changed the type of Close column as "float64" and plotted the Date-Close relation via using seaborn:

import seaborn as sns
sns.relplot(x='Date', y='Close', data=df,kind="line")

The output is:

I've managed the necessary column translations until this part of the code. In this part I split the data frame, create and trained model, and predicted values.

from sklearn.model_selection import train_test_split

X=df[["Open","High","Low","pc"]]
y=df["Close"]     
X_train,X_test,y_train,y_test = train_test_split(X,y)

from sklearn.linear_model import LinearRegression
model=LinearRegression()
model.fit(X_train,y_train)
model.score(X_test,y_test)
y_pred=model.predict(X_test)

What I want to achieve after this part is I want to set these predictions' dates for future dates in order to combine them into my data frame and plot. I managed to create 2 data frames for real and predicted data and concat and melt them into new dataframe in order to plot it.

dates=(df[-320:]["Date"]).values
df_plot=pd.DataFrame(columns=["Date","Close"])
df_plot["Date"]=dates
df_plot["Close"]=y_test.values.transpose()

df_predd=pd.DataFrame(columns=["Predicted","Date"])
df_predd["Predicted"]=y_pred.transpose()
df_predd["Date"]=dates
df_predd["Date"]=df_predd["Date"]+pd.offsets.DateOffset(years=8) #I want to plot it as future predictions

concatenated = pd.concat([df_predd.assign(dataset='df_predd'), df_plot.assign(dataset='df_plot')],axis=0)
melted_df=pd.melt(concatenated,id_vars=["Date"],value_vars=["Predicted","Close"])

sns.relplot(x='Date', y='value', data=melted_df,hue="variable",style='variable',kind="line",height=10)

Here's the undesired output:

I want an output something like that:

What Am I Missing? I checked the Date Column's type. It's datetime. I can't spread the x-axis as the first plot shown above. Any helps will be appreciated. Thanks in advance.


回答1:


To simplify your example, consider these two toy dataframes:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(1)

df_actual = pd.DataFrame(data={
    "date"  : pd.date_range(start="2020-01-01", periods=8, freq="MS"),
    "value" : np.random.randint(10, 30, 8),
})

df_forecast = pd.DataFrame(data={
    "date"  : pd.date_range(start="2020-08-01", periods=4, freq="MS"),
    "value" : np.random.randint(10, 30, 4)
})

If you want to plot the actual and forecast values together on a shared x axis, the easiest way I can think of is to differentiate them by adding a type column and feeding it to the hue parameter of seaborn's lineplot.

Remember to "connect" the two lines by making the first value of the forecast dataframe the same as the last value of the actual dataframe:

#first forecast value == last actual value
df_forecast.iloc[0, :] = df_actual.iloc[-1, :]

df_forecast["type"] = "forecast"
df_actual["type"] = "actual"

df = pd.concat([df_actual, df_forecast])

Finally, you create your plot like so:

plt.figure(figsize=(10,5))
sns.lineplot(x="date", y="value", hue="type", data=df)



来源:https://stackoverflow.com/questions/63378414/how-to-spread-plots-date-axis-according-to-years-when-plotting-with-seaborn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!