Home > Software engineering >  How to prevent Matplotlib from changing time series data on x-axis to 1970s?
How to prevent Matplotlib from changing time series data on x-axis to 1970s?

Time:03-11

I am trying to plot data from pandas data frame with python using Seaborn (and Matplotlib). I have the dates set as the index values in the dataframe starting at 2016-02-03 and ending at the current date. The values are of type datetime (not strings). No matter what I try, when I plot a graph of the data I have, it is changing the dates and going all the way back to 1970 instead of the dates that I have. Would appreciate any help.

import matplotlib.pyplot as plt
import requests
import os
import pandas as pd
import json
from datetime import *
from percent import change
from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource
from bokeh.models.tools import HoverTool
import numpy as np
import seaborn as sns 
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter

#constants
daily = "TIME_SERIES_DAILY"
symbols = ["COIN"]

COLOR = sns.color_palette('Set2')[4]

currentdate = date.today()


lastweek = currentdate  - timedelta(days=7)
lastyear = currentdate - timedelta(days=364)
lastyear = str(lastyear)
currentdate = str(currentdate)


api_key = REDACTED
base_url = 'https://www.alphavantage.co/query?'

params = {'function': daily,
         'outputsize': 'full',
         'symbol': symbols[0],
         'horizon': '3month',
         'datatype': 'csv',
         'apikey': api_key}


response = requests.get(base_url, params = params) #.json is same as json.loads()
#response_dict = response.json()
with open('eurusd.csv', 'wb') as file:
    file.write(response.content)

sns.set(style="ticks", context="talk")
plt.style.use("dark_background")



df = pd.read_csv("eurusd.csv", parse_dates = True)
df.set_index('timestamp', inplace = True)
df = df.iloc[::-1] #flips

plt.rc('axes', titlesize=18)     # fontsize of the axes title
plt.rc('axes', labelsize=14)    # fontsize of the x and y labels
plt.rc('xtick', labelsize=13)    # fontsize of the tick labels
plt.rc('ytick', labelsize=13)    # fontsize of the tick labels
#plt.rc('legend', fontsize=13)    # legend fontsize
plt.rc('font', size=10)          # controls default text sizes

plt.figure(figsize=(8,5), tight_layout=True)

a = sns.lineplot(data = df['close'], color=sns.color_palette('Set2')[4],linewidth = 2)

#graph extras
sns.despine()
plt.xticks(rotation = 45, ha = 'right')
plt.xticks([500,1000]) # to replace with specific name: plt.xticks([500,1000], [name1, name2 etc])
a.spines['left'].set_color(COLOR)      
a.spines['bottom'].set_color(COLOR)
a.xaxis.label.set_color(COLOR)       
a.yaxis.label.set_color(COLOR)       
a.tick_params(axis='x', colors= COLOR)   
a.tick_params(axis='y', colors=COLOR)
a.set(xlabel=None)
a.set(ylabel=None)
a.set_title('Stock Chart', color = COLOR)

for tick_label in a.axes.get_yticklabels():
    tick_label.set_color(sns.color_palette('Set2')[4])
for tick_label in a.axes.get_xticklabels():
    tick_label.set_color(sns.color_palette('Set2')[4])

a.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.show()

image of the plot enter image description here

First few lines of CSV data:

2016-02-03  18.00  18.88  16.0000  18.20  4157947
2016-02-04  18.26  19.42  17.5725  18.50   469941
2016-02-05  18.84  18.88  17.5200  17.60   220160
2016-02-08  17.52  18.00  15.7200  15.85   372112
2016-02-09  15.50  15.50  12.7482  12.81   744115

example of the csv data

CodePudding user response:

Running your example with the latest versions seems to use correct dates for the x-axis:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from io import StringIO

df_str = '''timestamp open close high low volume
2016-02-03  18.00  18.88  16.0000  18.20  4157947
2016-02-04  18.26  19.42  17.5725  18.50   469941
2016-02-05  18.84  18.88  17.5200  17.60   220160
2016-02-08  17.52  18.00  15.7200  15.85   372112
2016-02-09  15.50  15.50  12.7482  12.81   744115'''
df = pd.read_csv(StringIO(df_str), delim_whitespace=True)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))
sns.lineplot(data=df, x='timestamp', y='close', ax=ax1)
sns.lineplot(data=df.set_index('timestamp')['close'], ax=ax2)

seaborn sns.lineplot with dates as x-axis

With a longer list of dates, only the year, or year-month are shown:

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

df = pd.DataFrame({'timestamp': pd.date_range('2016-02-03', '2022-02-03')})
df['close'] = np.random.normal(0.02, 1, len(df)).cumsum()   20
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(15, 5))
sns.lineplot(data=df, x='timestamp', y='close', ax=ax1)
sns.lineplot(data=df.iloc[:len(df) // 2], x='timestamp', y='close', ax=ax2)
plt.tight_layout()
plt.show()

sns.lineplot with 6 years x axis

  • Related